将变量传递给指令模板而不创建新范围

时间:2013-05-15 09:19:49

标签: angularjs angularjs-directive

有没有办法在不创建新范围的情况下使用属性将变量传递给指令?

HTML

<div ng-click='back()' button='go back'></div>

JS

.directive('button', function () {
    return {
        scope: {
            button: '@'
        },
        template: "<div><div another-directive></div>{{button}}</div>",
        replace: true
    }
})

问题是ng-click='back()'现在指的是指令范围。 我仍然可以做ng-click='$parent.back()',但这不是我想要的。

2 个答案:

答案 0 :(得分:33)

默认情况下,指令不会创建新范围。如果要明确说明,请将scope: false添加到指令中:

<div ng-click='back()' button='go back!'></div>
angular.module('myApp').directive("button", function () {
    return {
        scope: false,  // this is the default, so you could remove this line
        template: "<div><div another-directive></div>{{button}}</div>",
        replace: true,
        link: function (scope, element, attrs) {
           scope.button = attrs.button;
        }
    };
});

fiddle

由于在作用域上创建了一个新属性button,因此通常应使用scope: true创建一个新的子作用域,如@ ardentum-c在其答案中所示。新范围将prototypially inherit来自父范围,这就是您不需要将$parent.back()放入HTML中的原因。

要提及的另一个问题是:即使我们使用replace: true,点击该元素仍会调用back()。这是因为“替换过程将所有属性/类从旧元素迁移到新元素。” - directive doc所以ng-click='back()' button='go back!'迁移到指令模板中的第一个div

答案 1 :(得分:2)

我猜你应该在这种情况下使用编译函数。

angular.module('myApp').directive("button", function () {
    return {
        template: "<div><div another-directive></div>{{button}}</div>",
        replace: true,
        scope:   true,
        compile: function (tElement, tAttrs) {
            // this is link function
            return function (scope) {
                scope.button = tAttrs.button;
            };            
        }
    };
});

这是jsfiddle example