我有一个自定义表单指令,每个页面可能会多次使用。我需要这些指令的总数,所以在指令配置对象之外添加了一个,即
module.directive("customInput", [
function ()
{
/*
* Because each instance of the directive will get its own
* instance of the return object, we have to declare groupCount
* here, instead of inside the post-link function where it's used.
*/
var groupCount = {};
return { ...configObj... }
}
]);
问题是此计数在视图中仍然存在。我将它移动到一个服务并给它一个重置方法,但我需要一种方法来每页只调用一次该方法。
我不想添加$routeChangeSuccess
侦听器,因为对于使用这些输入的几个页面而言,这似乎太过沉重。我无法在指令的控制器中执行此操作(例如$watch("$viewContentLoaded")
),因为它会执行多次。
如果有办法做一次,我不想把负担放在个别视图控制器上。有没有(可能有“父”指令)?
答案 0 :(得分:1)
这可以在架构层面解决,AngularJS有很好的机制来处理这类事情。了解移动应用程序的常用编写方式,并制作“经理”服务。 Angular中的服务是一个单例,因此它可以维护变量,如对象集合(指令)和这些项的计数。然后可以在需要时询问它们,可以要求它们创建/更改/删除它们。当您执行类似ngRepeat的操作时,它也可以是数据源,而不是将数据直接存储在控制器中。
通信驱动的模型做了很多,而且效果很好。假设你有一个假设的“好友列表”。你可以这样做:
angular
.module('myApp', [])
.controller('MainDisplay', function($scope, buddyManager) {
$scope.buddyManager = buddyManager;
// Handle things here that are relevant to the main display
$scope.sendMessage = function(buddy) {
alert('here I could message ' + buddy.name);
}
buddyManager.addBuddy('Susan');
buddyManager.addBuddy('David');
buddyManager.addBuddy('Jamie');
})
.service('buddyList', function() {
var self = this;
this.buddies = [];
this.buddyCount = 0; // If you didn't want to just do buddies.length...
this.addBuddy = function(name) {
// Again, if you didn't want to just use .length...
self.buddyCount++;
self.buddies.push({
name: name
});
};
})
.directive('buddy', function() {
return {
restrict: 'E',
replace: true,
scope: { buddy: '=' },
template: '<div class="buddy">{{ name }}</div>',
link: function($scope) {
// Here you can put anything specific to a buddy, like click handlers
// $scope.buddy is yourself / your buddy data
}
};
});
一个简单的页面:
<html ng-app="myApp">
<head>
<!-- You know you what you need... -->
</head>
<body ng-controller="MainDisplay">
<buddy ng-repeat="buddy in buddyManager.buddies" buddy="buddy"></buddy>
</body>
</html>
在这里工作Plnkr: http://plnkr.co/edit/R3QMwLxEbqMRlBg74dOi?p=preview
答案 1 :(得分:0)
如果需要,您可以监听范围,只是增加。类似的东西:
module.directive("customInput", [
function (){
/*
* Because each instance of the directive will get its own
* instance of the return object, we have to declare groupCount
* here, instead of inside the post-link function where it's used.
*/
var groupCount = {};
var totalCount = 0;
return {
link: function(scope){
totalCount++;
scope.$on("$destroy", function(){
totalCount--
});
}
}
}
]);
totalCount将始终是您拥有的元素数量。如果你想使用它,你可以连接到你想要的任何东西(服务等......)。
答案 2 :(得分:0)
我把计数器放在一个服务中,以便它有一些很好的增量和减量方法。根据{{3}}建议使用$destroy
,我可以调用服务的减量方法。我的估计是这个解决方案比一次性重置呼叫稍微重一点,但不像手表路线变化那样糟糕。
// recommended var name for this object: groupControl
module.service("GroupControlSvc", [
function ()
{
this.groupCount = {};
this.incrementGroupCount = function (groupName)
{
if (!this.groupCount.hasOwnProperty(groupName)) {
this.groupCount[groupName] = 0;
}
this.groupCount[groupName]++;
};
this.decrementGroupCount = function (groupName)
{
if (this.groupCount.hasOwnProperty(groupName)) {
console.log("decrementing group " + groupName);
this.groupCount[groupName]--;
if (this.groupCount[groupName] === 0) {
console.log("removing group " + groupName);
delete this.groupCount[groupName];
}
}
};
}
]);
module.directive("customInput", [
function ()
{
return {
...
,link: function (scope, elem, attrs)
{
...
/*
* Count the members of each group, so we can
* determine which element is last. Because
* groupCount is an object (and an object of
* objects, at that), assigning it to scope
* here is by reference. Thus, every scope
* instance will point to the same object.
*/
if (attrs.hasOwnProperty("editGroup")) {
groupControl.incrementGroupCount(attrs.editGroup);
}
scope.groupCount = groupControl.groupCount;
scope.$on("$destroy", function ()
{
groupControl.decrementGroupCount(attrs.editGroup);
});
} // end post-link function
};
}
]);
我想不直接公开groupCount
属性,但是将范围内的getter函数赋值给它并不值得。
这也使我groupCount
或其回调失败导致$destroy
出现偏差的可能性。
虽然这解决了我的需要,但它没有回答问题。