页面上的多个相同组件会覆盖自身

时间:2017-06-11 11:29:43

标签: angularjs angularjs-directive

我在一个页面上有两次指令,但它会一直覆盖自己。 这意味着,dialogId会被模板中的下一个example-dialog实例覆盖,而不是保留自己的dialogId。

angular.module('directives')
    .directive('exampleDialog', ["$rootScope", "$timeout", "ngDialog", "$compile", '$templateRequest', function ($rootScope, $timeout, ngDialog, $compile, $templateRequest) {
        return {
            templateUrl: "/dialog.component.html",
            transclude: {
                button: '?dialogButton',
                title: '?dialogTitle',
                body: '?dialogBody',
                footer: '?dialogFooter'
            },
            replace: true,
            link: function (scope, el, attrs, ctrl, transclude) {
                var dialogId = scope.blah.id; // gets overwritten - so when scope.open() gets called, the last instance ID gets used for both

                scope.open = function(){
                    console.log(dialogId) // prints the same for both directives instead of the unique dialogId.
                }
            },
            controller: function ($scope) {

            }
        }
    }]);

使用以下HTML:

<example-dialog>
    <dialog-button>
        <a href="#" ng-click="open()">ExampleButton1</a>
    </dialog-button>
    <dialog-title ng-non-bindable>Title1</dialog-title>
    <dialog-body ng-non-bindable>
        <div ng-include="'template1.tpl.html'"></div>
    </dialog-body>
    <dialog-footer ng-non-bindable>
    </dialog-footer>
</example-dialog>


<example-dialog>
    <dialog-button>
        <a href="#" ng-click="open()">ExampleButton2</a>
    </dialog-button>
    <dialog-title ng-non-bindable>Title2</dialog-title>
    <dialog-body ng-non-bindable>
        <div ng-include="'template2.tpl.html'"></div>
    </dialog-body>
    <dialog-footer ng-non-bindable>
    </dialog-footer>
</example-dialog>

如何在继承父母的范围的同时让他们保存自己的引用?

修改 有人建议我使用scope: true来创建经典的原型继承。

但是,当我尝试此操作时,来自open()转移点的<dialog-button>现在不起作用,以及模板中的任何其他绑定。

2 个答案:

答案 0 :(得分:0)

您应该隔离指令的范围。在你的return语句中添加scope:{}

通过执行此操作,您的指令将创建自己的受控范围,并且您将无法从父范围获取任何值(基本上没有来自父范围的冲突)。要从父控制器/范围访问值,您将需要明确地传递它们。

答案 1 :(得分:0)

要完成上一个答案,您可以在角色官方文档(here)中看到:

  

scope属性可以是false,true或对象:

     

false(默认值):不会为该指令创建范围。该   指令将使用其父级的范围。

     

true:原型继承自其父级的新子范围   将为指令的元素创建。如果有多个指令   同一个元素请求一个新范围,只创建一个新范围。

     

{...}(对象哈希):为。创建一个新的“隔离”范围   指令的模板。 “隔离”范围与正常范围不同   它没有原型继承其父范围。这是   在创建可重用组件时很有用,但不应该   意外地读取或修改父作用域中的数据。注意一个   隔离范围指令没有模板或templateUrl不会   将隔离范围应用于其子元素。

编辑就像评论中提到的@itamar一样:

  

当我使用scope:true时,似乎它确实将id保存在指令中(通过转到dom元素并打印范围来检查)。但是,从tansclusion点开始的open()与模板中的任何其他绑定一起不起作用。

答案(来自angularjs doc)是:

'isolate'范围对象哈希定义了一组从指令元素的属性派生的局部范围属性。这些本地属性对于模板的别名值很有用。对象哈希中的键映射到隔离范围上的属性名称;这些值通过匹配指令元素的属性来定义属性如何绑定到父作用域:

  • @或@attr - 将本地范围属性绑定到DOM属性的值。
  • = or = attr - 在本地范围属性和通过属性attr传递的表达式之间建立双向绑定。表达式在父作用域的上下文中计算。
  • &LT;或者&lt; attr - 在本地范围属性和通过属性attr传递的表达式之间建立单向(单向)绑定。表达式在父作用域的上下文中计算。如果未指定attr名称,则假定属性名称与本地名称相同。
  • &安培;或&amp; attr - 提供在父作用域的上下文中执行表达式的方法。如果未指定attr名称,则假定属性名称与本地名称相同。