AngularJS控制器执行两次 [英] AngularJS Controller execute twice
问题描述
我必须补充,我在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> </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控制器执行两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!