正在与子指令作用域共享作用域对象

Sharing scope object with child directive scopes

本文关键字:作用域 共享 对象 指令      更新时间:2023-09-26

我有一个父指令,它在link期间创建第三方对象的实例,并且该变量需要可由子指令访问。

然而,有两个限制:

  • 每个页面可能有多个这样的实例,所以javascript文件顶部的singleton不起作用
  • 子指令是递归的,因此它们必须创建自己的作用域

我能想到的唯一方法是将该值作为属性传递给每个子指令。这感觉效率很低,但考虑到上述限制,我看不出有其他选择。

// Some imaginary third-party object
function Tree() {}
// Root directive which creates an instance of the object, links to the page, and loads the data needed.
app.directive('tree', function() {
    return {
        restrict: 'E',
        replace: true,
        template: '<div><nodes nodes="nodes"></nodes></div>',
        scope: {
          nodes: '='
        },
        link: function(scope, $element) {
           // This value needs to be accessible to all child directives
           scope.tree = new Tree();
        }
    };
});
// A directive to render an array of nodes
app.directive('nodes', function() {
    return {
        restrict: 'E',
        replace: true,
        template: '<ol>' +
            '<li ng-repeat="node in nodes track by node.id">' +
                '<node node="node"></node>' +
            '</li>' +
        '</ol>',
        scope: {
            nodes: '='
        }
    };
});
// A directive to render a single node, and recursively any child nodes
app.directive('node', ['$compile', function($compile) {
    return {
        restrict: 'E',
        replace: true,
        scope: {
            node: '='
        },
        template: '<div><span ng-bind="node.text"></span></div>',
        link: function(scope, $element) {
            if (scope.node.children && scope.node.children.length > 0) {
              console.log(scope.node.children);
                var tmpl = '<nodes nodes="node.children"></nodes>';
                var children = $compile(tmpl)(scope);
                $element.append(children);
            }
            // @todo Here's a good example of where I need access to scope.tree
        }
    };
}]);

我能想到的唯一解决方案是将tree: '='添加到scope对象,然后将tree="tree"传递给每个子对象。

Plunker

一个解决方案是不隔离作用域,这样子指令将从其父作用域继承。如果父级具有scope.tree = new Tree(),则嵌套指令将继承scope.tree

但是,由于您提到每个页面可以有多个这样的实例,这意味着您可能需要一个独立的范围(这就是您目前拥有的范围)。将数据传递到隔离作用域的唯一方法是通过标记中的指令属性。

我想你已经回答了自己的问题:)