避免在angularjs指令中引用父作用域

时间:2013-11-12 10:43:28

标签: javascript angularjs

我正在编写一个指令,用于在名为djlist

的HTML表格中显示来自服务器的数据
directive('djlist', function(urls) {
    return {
        restrict: 'ACE',
        templateUrl: urls.list_objs_template,
        scope: {},
        controller: ['$scope', '$resource', 
            function($scope, $resource) {
                $scope.objs = $resource(urls.list_objs);
                $scope.objs_api = $resource(urls.list_objs_api);
                $scope.data = $scope.objs.get();
            }
        ]
    };
})

来自服务器的数据显示为ng-repeat。数据数组中的每个对象都附有一个删除按钮,这是另一个名为djdel

的指令
<div class="row panel panel-primary">
    <h3 class="panel-heading">Data from REST</h3>
    <div class="panel-body">
        <table class="table">
            <tr>
                <th>Content</th>
                <th>Date Created</th>
                <th>Action</th>
            </tr>
            <tr ng-repeat="d in data.objects">
                <td>{{ d.content }}</td>
                <td>{{ d.date }}</td>
                <td>
                    <djdel ng-click="del($index)" model-pk="d.id"></djdel>
                </td>
            </tr>
        </table>
    </div>
</div>

以下是我定义djdel

的方法
directive('djdel', function() {
    return {
        restrict: 'ACE',
        template: '<button class="btn btn-danger btn-small">Delete</button>',
        scope: {
            modelPk: '='
        }, controller: ['$scope', '$http', '$resource', 
            function($scope, $http, $resource) {
                $scope.del = function(index) {
                    var $parent = $scope.$parent.$parent;
                    $parent.objs_api.
                    remove({id: $scope.modelPk}, function() {
                        $parent.data.objects.splice(index, 1);
                    });
                };
            }
        ]
    };
}).

这很有效。但是,在我的对象从djdel scope中启动的服务器中成功删除后,我需要一种方法来刷新djlist scope中的数据集合。范围层次结构为djlist > ng-repeat > djdel,因此在引用数据收集时为$scope.$parent.$parent

有没有办法避免在范围链中引用这么多级别?

2 个答案:

答案 0 :(得分:6)

您可以require父控制器:在djdel

directive('djdel', function() {
    return {
        ...
        require: "^djlist",
        ...
        link: function(scope, elem, attrs, djlistController) {
            // the controller function does not have access to the required
            // controllers, so we just inject htem in the scope
            scope.djlistController = djlistController;
        },
        controller: ['$scope', '$http', '$resource', 
            function($scope, $http, $resource) {
                // you can access members of the djlistController as
                $scope.djlistController.XXX();
                ...
            }]
    };
});

djlist中将所需的功能添加到this(不是$scope):

directive('djlist', function(urls) {
    ...
    controller: ['$scope', '$resource',
        function($scope, $resource) {
            this.XXX = function() {
                // you can also add variables here
            };
            ...
        }]
    ...
});

答案 1 :(得分:0)

您可以随时尝试在应用程序的$rootScope中发送事件。

$rootScope.$broadcast("nameOfTheEvent", paramsToSend);

从服务器上删除内容后

$rootScope.$on("nameOftheEvent", function(paramsToRecieve) { refreshList();});

当然,paramsToRecieve是paramsToSend并且可以是任何对象。