本文介绍了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控制器执行两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 21:32
查看更多