如何避免使用'范围。$ parent ...'角度1.2

时间:2016-09-02 12:43:06

标签: javascript angularjs angularjs-directive controller

我们在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;功能。我被告知,提到父母范围是不好的做法,显然它也搞乱了我们的单元测试。

我想知道替代方案是什么。如何让我的应用知道特定组件已完成?这个州应该在哪里跟踪?

我真的很想知道如何做到这一点 - 不只是被告知我做错了。请让我知道替代方案。

但是,与往常一样,任何帮助都将受到高度赞赏。

2 个答案:

答案 0 :(得分:2)

一种替代方案是创建一个服务来负责跟踪所有组件并保持其状态(完成/未完成)。

它将不再需要 $ scope.parent ,并且可以将服务注入到您需要的任何控制器或指令中。

:)

答案 1 :(得分:0)

如果completables列表在应用程序范围内,您可以考虑将其与$rootScope方法一起添加到addCompletable - 以及任何其他相关方法 - 而不是将其添加到您的{ {1}} mainController

通过这种方式,您可以使用$scope替换scope.$parent.componentCompleted(attrs.id);,并避免拨打$rootScope.componentCompleted(attrs.id);

相关问题