【问题标题】:angularjs: directive creates two child scope(not isolation scope)? and how to get scope of an element?angularjs:指令创建两个子范围(不是隔离范围)?以及如何获取元素的范围?
【发布时间】:2013-08-19 06:27:27
【问题描述】:

我正在编写我的 angularjs 指令,其定义如下:

return {
    restrict: 'EA',
    link: link,
    scope: true,
    transclude: true,
    replace: true,
    controller: controller,
    template: '<div class="wizard">' +
        '<div ng-transclude></div>' +
        '</div>'
};

我注意到创建了两个范围:

< Scope (003)  --- parent scope of directive
    < Scope (004)  --- controller scope of directive which I think is child scope created by 'scope=true'. all my functions, properites defined in controller show up in this scope
    < Scope (005)  --- transclude scope which is empty

从文档中我预计只创建了一个子范围,因为 'scope=true' 不会创建一个孤立的范围。这导致所有被“ng-transclude”替换的元素实际上继承了 Scope(005) 并且无法访问我在控制器中定义的函数/属性,因为它们位于 Scope(004) 中,它是 Scope(005) 的兄弟。

我不知道出了什么问题,有人可以在这里放灯吗?

当使用 Chrome 调试器查看我的元素时,我注意到这些元素是由“ng-scope”类添加的,但是,如何将“ng-scope”与batarang 控制台中显示的范围匹配?比如显示 ng-scope 的 id。

谢谢

【问题讨论】:

    标签: angularjs scope directive


    【解决方案1】:

    scope: true 将从控制器作用域创建一个新的子作用域 prototypically inherits - 这是作用域 004。

    scope: { ... } 将创建一个新的子范围,它在原型上并不从控制器范围继承。

    无论哪种方式,都会创建一个新的子作用域。

    此外,由于您使用的是transclude: true,因此会创建另一个(转入的)子作用域 005。被嵌入的作用域总是原型继承自控制器作用域。

    正如您已经发现的那样,您在指令范围(即指令内部)上定义的属性和函数对视图不可用,因为视图使用了转入的范围。

    上图基于以下代码:

    app.directive('myDirective', function() {
        return {
            restrict: 'EA',
            //link: link,
            scope: true,
            transclude: true,
            replace: true,
            controller: function($scope) {
                $scope.dirProp1 = "dirProp1";
                $scope.dirFunc = function() {}
            },
            template: '<div class="wizard">' +
                '<div ng-transclude></div>' +
                '</div>'
        };
    });
    

    function MyCtrl($scope) {
        $scope.parentCtrlProp1 = 'ParentCtrlProp1';
    }
    

    因此,从图中可以看出,被嵌入的范围(因此被嵌入的内容)只能通过原型链访问控制器范围 (003) 上定义的属性和函数。


    如何将“ng-scope”与batarang 控制台中显示的范围相匹配?像显示 ng-scope 的 身份证。

    我不知道有什么方法可以做到这一点(这就是为什么我编写了一个工具来绘制自己的图片)。

    【讨论】:

    • 对于 ng-scope 部分,您可以在每个作用域中创建一个 scope.name 变量,并使用 ng-class 在各种 Dom 元素中显示作用域名称
    • 很棒的回复!现在很清楚,我认为这对很多追求同样问题的人都有好处。非常感谢!
    • 顺便问一下,你画图的好工具是什么?它是可以在某处找到的开源软件吗?
    • @zx_wing,该工具只是半支持(如果那样的话),所以我还没有把它放在github上。 (也许我应该这样做,这样其他人就可以完成剩下的工作。)我使用 GraphViz 来绘制图片,使用 AngularJS 指令来遍历范围,并在服务器端使用 Python。
    【解决方案2】:

    如果没有上下文的任何 jsfiddle,很难弄清楚。你的链接功能是什么?你的控制器功能是什么?

    顺便说一下,这是正常的行为,因为文档说 transclude:true 也会创建一个新范围。

    看这里:https://github.com/angular/angular.js/wiki/Understanding-Scopes

    嵌入的和孤立的范围(如果有的话)是同级的—— 每个作用域的 $parent 属性引用相同的父作用域。什么时候 一个嵌入和一个隔离范围都存在,隔离范围属性 $$nextSibling 将引用嵌入的范围。

    因此,如果您想从彼此访问 2 个兄弟姐妹,您必须使用与它们的父级的 2-way 绑定

    【讨论】:

    • +1,尽管 OP 没有询问隔离范围。但是,对于scope: true 的情况,指令范围和转入范围都是兄弟,就像隔离情况一样(参见我的答案中的图片)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-15
    • 1970-01-01
    • 1970-01-01
    • 2015-12-08
    相关资源
    最近更新 更多