AngularJS控制器执行两次

时间:2013-08-06 11:44:07

标签: angularjs

我必须补充一点,我正在研究Sharepoint 2013,可视化网络部分。 我的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):

<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调用。

然后当我点击其中一个用ng-click时,第二个ajax被执行两次,一旦它获得了正确的数据,并且在它再次使用getVODCatalogData的初始调用(null, $ scope.VODCatalogLevel);并带回旧观点。

当我尝试在module.run中放置一些东西时,它也会运行两次,这有用吗?

我很感激任何提示和帮助,因为这是我第一次有角度。

THX! 爱丽儿

编辑: 更多信息 - 我在控制器的开头放了一个日志,然后点击控制器再次初始化

2 个答案:

答案 0 :(得分:12)

如果在$routeProvider和HTML模板中指定了控制器,则每个声明都会创建一次。

答案 1 :(得分:3)

第二个答案,技术答案是$routeProvider引起了它,我不知道为什么但是当我将我的“主人”html更改为:

<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那么它只适用于基本路由,那么任何更复杂的东西都需要工作。 最着名的文章和例子是Nested Views Routing-And Deep Linking With AngularJS谁创造了一个美妙的建筑,而我的尝试将包含在我的博客更具活力,我将尝试阅读工厂中的参数。

第一回答: 找到了解决方案! 我没有使用MVC架构。 控制器是 SUPPOSED 以便在每次调用时重新创建,因此尝试在控制器中管理我的数据确实一团糟,因为Ajax调用有它的承诺保证返回async然后它重新创建控制器。

解决方案是管理控制器中的 ONLY BEHAVIORS 以及服务/工厂/提供商中的所有数据。

所以这里是新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 and ajax filtering refreshing