AngularJS控制器执行两次 [英] AngularJS Controller execute twice

查看:477
本文介绍了AngularJS控制器执行两次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须补充,我在SharePoint 2013,可视化Web部件的工作。
我ASCX:

I must add I am working on Sharepoint 2013, visual web part. my ascx:

<%@ Control Language="C#" Inherits="SharePoint.BLL.UserControls.VODCatalog, SharePoint.BLL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=81fc048468441ab3" %>
<%@ Register TagPrefix="SPWP" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls"  Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>


<div ng-app="VODCatalogModule">
    <div class="wrapper" ng-view="">   
    </div>
</div>

我的JS:

var VODCatalogModule = angular.module('VODCatalogModule', []);

var testWPDefinedView = 'TopLevelView';

VODCatalogModule.config(function ($routeProvider) {
    $routeProvider.when('/TopLevelView', { controller: 'VODCatalogController', templateUrl: '/_catalogs/masterpage/html/VODCatalog_TopLevelView.html' })
                  .when('/LowLevelView', { controller: 'VODCatalogController', templateUrl: '/_catalogs/masterpage/html/VODCatalog_LowLevelView.html' })
                  .otherwise({ redirectTo: '/' + testWPDefinedView });
});

function VODCatalogController($scope, $http) {
    $scope.VODCatalogLevel = 1;
    $scope.BreadCrumbs = [];
    $scope.MainCatalog = [];
    $scope.NavCatalog = [];
    $scope.crumbsVisible = $scope.BreadCrumbs.length == 0 ? "hidden" : "";

    var getVODCatalogData = function (PARENT_VOD_CATALOG_GK, vodLevel) {
        var url = "VODCatalogHandler.ashx?action=GetVODCatalogData&vodLevel=" + vodLevel;
        if (PARENT_VOD_CATALOG_GK)
            url += "&PARENT_VOD_CATALOG_GK=" + PARENT_VOD_CATALOG_GK;
        $http.get(url, { cache: true })
            .success(function (data, status, headers, config) {
                setVODCatalogData(data, vodLevel);
            }).error(function (data, status, headers, config) {
                alert('ERROR in VODCatalogDataService get');
            });
    };

    var setVODCatalogData = function (data, vodLevel) {
        $scope.BreadCrumbs = data;
        $scope.MainCatalog = data;
        $scope.NavCatalog = data;
    };

    $scope.catalogItemClick = function (catalogItem) {
        getVODCatalogData(catalogItem.VOD_CATALOG_GK, ++$scope.VODCatalogLevel);
    };

    getVODCatalogData(null, $scope.VODCatalogLevel);
}

VODCatalogModule.controller("VODCatalogController", VODCatalogController);

我的观点(VODCatalog_TopLevelView.html):

My view (VODCatalog_TopLevelView.html):

<section class="zebra brightBGcolor">
    <div class="catalog">
        <div class="centerPage">
            <div class="pageTitle withBreadCrumbs">
                <h3>VOD</h3>
                <ul class="breadCrumbs {{ crumbsVisible }}">
                    <li>
                        <a href="#">VOD</a>
                    </li>
                    <li ng-repeat-start="crumb in BreadCrumbs">
                        <span>&nbsp;</span>
                    </li>
                    <li ng-repeat-end>
                        <a href="#">{{ crumb.NAME }}</a>
                    </li>
                </ul>
            </div>
            <ul class="list inRow4 clearfix">
                <li ng-repeat="catalogItem in MainCatalog" ng-click="catalogItemClick(catalogItem)">
                    <a class="box" href="#">
                        <img src="{{ catalogItem.MEDIA_URI_Complete}}" alt="">
                        <div class="textContainer">
                            <h4>{{ catalogItem.NAME }}</h4>
                        </div>
                    </a>
                </li>
            </ul>
        </div>
    </div>
</section>

在开始时一切看起来不错,它加载的所有图片和数据的第一个Ajax调用。

At the start all looks great, it loads the 1st ajax call with all the pics and data.

然后,当我点击在李的同一个NG单击第二个AJAX被执行了两次,一次就得到正确的数据,并将其与getVODCatalogData的(初始调用空,$ scope.VODCatalogLevel再次调用自身后,立即);并带回旧观点。

Then when I click at one of the li's with the ng-click the 2nd ajax gets executed twice, once it gets the right data and immediately after it calls itself again with the initial call of getVODCatalogData(null, $scope.VODCatalogLevel); and brings back the old view.

当我试图把在module.run东西它也运行两次,它可以帮助?

When I tried to put something in module.run it also runs twice, can it help?

我想AP preciate任何暗示和帮助,因为它是我第一次有棱有角。

I would appreciate any hint and help as it is my 1st time with angular.

THX!
阿里尔

thx! ariel

编辑:
一些更多的信息 - 我把记录在控制器的开始和点击后的控制器被再次初始化

some more info - I put a log at the beginning of the controller and after the click the controller gets initialized again

推荐答案

第2个答案,技术答案是 $ routeProvider 造成它,我不知道为什么,但是当我改变我的主人的HTML这样的:

2nd Answer, the technical answer is that the $routeProvider caused it, i dont know why but when i change my "master" html to this:

<div ng-app="VODCatalogModule" ng-controller="VODViewsController" ng-switch on="templateUrl">
   <div class="wrapper" ng-switch-when="TopLevelView" ng-include="'/_catalogs/masterpage/html/VODCatalog_TopLevelView.html'" ng-controller="VODCatalogController"></div>
   <div class="wrapper" ng-switch-when="LowLevelView" ng-include="'/_catalogs/masterpage/html/VODCatalog_LowLevelView.html'" ng-controller="VODCatalogController"></div>
</div>

控制器终于创建只有一次。得出的结论是,如果你使用 $ routeProvider 则其基本的路由,任何事情更复杂的唯一的好工作需要要去工作。
对于最有名的文章,并例子是的嵌套视图的路由,而深层链接随着谁创造了一个美丽的建筑AngularJS,而我的努力将包括在我的博客的东西更有活力,我会尝试读取工厂PARAMS。

the controller finally was created only once. the conclusion is that if you gonna work with the $routeProvider then its only good for basic routing, anything more complex require work. the most famous article and example for that is Nested Views Routing-And Deep Linking With AngularJS who created a wonderful architecture, while my attempt that will be included in my blog is something more dynamic, i will try to read the params in the factory.

第一个答案:
找到了解决办法!
我没有使用MVC架构。
控制器的应该以获得重新创建每次被调用的时候,并为此尝试管理我的控制器中的数据做了一个烂摊子,因为Ajax调用有其允诺的回报异步然后重新创建控制器。

1st Answer: found the solution! i was not using MVC architecture. the controller is SUPPOSED to get recreated every time it is being called, and therefor trying to managed my data in the controller did a mess since the Ajax call has its promise promise return async then it recreates the controller.

解决是管理的只有行为在你的控制器,并在服务/工厂/供应商的所有数据。

the solution to that is to manage ONLY BEHAVIORS in your controller and all data in a service/factory/provider.

所以这里是在新的JS

    var VODCatalogModule = angular.module('VODCatalogModule', []);

    VODCatalogModule.factory('VODCatalogFactory', function($http) {
        var VODFactory = [];

        VODFactory.VODCatalogLevel = 1;
        VODFactory.PARENT_VOD_CATALOG_GK;

        VODFactory.getVODCatalogData = function (PARENT_VOD_CATALOG_GK) {
            var url = "VODCatalogHandler.ashx?action=GetVODCatalogData&vodLevel=" + VODFactory.VODCatalogLevel;
            if (PARENT_VOD_CATALOG_GK)
                url += "&PARENT_VOD_CATALOG_GK=" + PARENT_VOD_CATALOG_GK;
            return $http.get(url, { cache: true });
        };

        VODFactory.changeVODCatalog = function (level, PARENT_VOD_CATALOG_GK){
            VODFactory.VODCatalogLevel = level;
            VODFactory.PARENT_VOD_CATALOG_GK = PARENT_VOD_CATALOG_GK;
        };

        return VODFactory;
    });

    var testWPDefinedView = 'TopLevelView';
    //var testWPDefinedView = 'LowLevelView';

    VODCatalogModule.config(function ($routeProvider) {
        $routeProvider.when('/TopLevelView', { controller: 'VODCatalogController', templateUrl: '/_catalogs/masterpage/Yes/html/VODCatalog_TopLevelView.html' })
                      .when('/LowLevelView', { controller: 'VODCatalogController', templateUrl: '/_catalogs/masterpage/Yes/html/VODCatalog_LowLevelView.html' })
                      .otherwise({ redirectTo: '/' + testWPDefinedView });
    });

function VODCatalogController($scope, $http, VODCatalogFactory) {
    console.log("VODCatalogController ctor");
    $scope.crumbsVisible = !$scope.BreadCrumbs || $scope.BreadCrumbs.length == 0 ? "hidden" : "";

    $scope.catalogItemClick = function (catalogItem) {
        VODCatalogFactory.changeVODCatalog(++VODCatalogFactory.VODCatalogLevel, catalogItem.VOD_CATALOG_GK);
    };

    VODCatalogFactory.getVODCatalogData().then(function(response){
        $scope.BreadCrumbs = response.data;
        $scope.MainCatalog = response.data;
        $scope.NavCatalog = response.data;
    });

    VODCatalogModule.controller("VODCatalogController", VODCatalogController);

angularjs和Ajax过滤清爽

这篇关于AngularJS控制器执行两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆