我们在angularjs 1.2中开发了一套(理想情况下)灵活的,基于组件的可重用模板,以开发一系列电子学习模块。
该规范的一部分要求跟踪“可完成的”'组件。目前主控制器看起来像这样:
app.controller('mainCtrl', ['$scope', function($scope) {
$scope.completables = [];
$scope.completed = [];
$scope.addCompletable = function (object) {
$scope.completables.push(object);
// also set correlating completed property to 'false' for each completable added
$scope.completed.push(false);
}
$scope.componentCompleted = function(id) {
// Set complete to 'true' for matching Sscope.completed array index
// We COULD use .indexOf on the completables array, but that doesn't work with IE8
var tempArray = $scope.completables;
var matchingIndex = -1;
for (var i=0; i<tempArray.length; i++) {
if (tempArray[i]==id) {
matchingIndex = i;
}
}
if (i>-1) {
$scope.completed[matchingIndex] = true;
}
}
}]);
我们有一个eng-completable属性,可触发以下指令:
app.directive('engCompletable', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
// add the id of this element to the completables array in the main controller
scope.$parent.addCompletable(attrs.id);
}
}
});
因此,每次角度遇到“可完成的”时,在元素上的属性,它在父作用域上调用addCompletable,它将元素id添加到&#39; completables&#39;数组和&#39; false&#39;到完成的相应索引&#39;阵列。
在eng-popup属性指令中,我们有一个函数来检查它是否可见:
app.directive('engPopup', function() {
return {
restrict: 'A',
replace: true,
templateUrl: 'components/popup.html',
link: function(scope, element, attrs) {
scope.$watch(function() { return element.is(':visible') }, function() {
scope.$parent.componentCompleted(attrs.id);
});
}
};
});
其中还使用父作用域触发&#39; componentCompleted&#39;功能。我被告知,提到父母范围是不好的做法,显然它也搞乱了我们的单元测试。
我想知道替代方案是什么。如何让我的应用知道特定组件已完成?这个州应该在哪里跟踪?
我真的很想知道如何做到这一点 - 不只是被告知我做错了。请让我知道替代方案。
但是,与往常一样,任何帮助都将受到高度赞赏。
答案 0 :(得分:2)
一种替代方案是创建一个服务来负责跟踪所有组件并保持其状态(完成/未完成)。
它将不再需要 $ scope.parent ,并且可以将服务注入到您需要的任何控制器或指令中。
:)
答案 1 :(得分:0)
如果completables
列表在应用程序范围内,您可以考虑将其与$rootScope
方法一起添加到addCompletable
- 以及任何其他相关方法 - 而不是将其添加到您的{ {1}} mainController
。
通过这种方式,您可以使用$scope
替换scope.$parent.componentCompleted(attrs.id);
,并避免拨打$rootScope.componentCompleted(attrs.id);
。