【问题标题】:Avoid referencing parent scope in angularjs directive避免在 angularjs 指令中引用父范围
【发布时间】:2013-11-12 10:43:28
【问题描述】:

我正在编写一个指令以在名为 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 &gt; ng-repeat &gt; djdel,因此在引用数据收集时为$scope.$parent.$parent

有什么方法可以避免在作用域链上引用这么多级别?

【问题讨论】:

    标签: javascript angularjs


    【解决方案1】:

    你可以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
                };
                ...
            }]
        ...
    });
    

    【讨论】:

    • 非常干净。谢谢。
    【解决方案2】:

    您始终可以尝试在应用程序的$rootScope 中发出事件。

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

    在你从服务器中删除某些内容之后,

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

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

    【讨论】:

    • $rootScope 上调用的方法应该是 $broadcast 而不是发射。发射上升,广播下降。 $rootScope 是顶级范围,因此需要广播。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-06
    相关资源
    最近更新 更多