7

关于 AngularJS 指令,我遇到了从另一个指令中调用指令的情况,我有以下问题。

  1. 为什么我不能在我的链接函数中引用 scope.bindValue?有没有办法可以从 scope.bindValue 计算一个值并将其设置为范围?
  2. 为什么子指令可以在 scope:{} 中使用“@”绑定,但在链接函数中不能使用 scope.value = attrs.value?

以下所有内容都可以在http://jsfiddle.net/sdg9/AjDtt/13/上看到

HTML:

<directive bind-value="12" value="7"></directive>

JS:

var myApp = angular.module('myApp', []);
var commonTemplate = '<div>{{name}} bind-value is: {{bindValue}} </div><div>{{name}} value is: {{value}} </div><div>{{name}} add one to bind-value is: {{addOneBindValue}} </div><div>{{name}} add one to value is: {{addOneValue}} </div><br/>';

myApp.directive('directive', function () {
    return {
        scope: {
            bindValue: "@",
        },
        template: commonTemplate + '<br/><sub-directive bind-value="{{value}}" value="{{value}}"></sub-directive>',
        restrict: 'E',
        link: function (scope, element, attrs) {
            scope.name = "Directive";
            scope.value = attrs.value;
            scope.addOneBindValue = parseInt(scope.bindValue) + 1;
            scope.addOneValue = parseInt(scope.value) + 1;
        }
    };
});


myApp.directive('subDirective', function () {
    return {
        scope: {
            bindValue: "@"
        },
        template: commonTemplate,
        restrict: 'E',
        link: function (scope, element, attrs) {   
            scope.name = "SubDirective";
            scope.value = attrs.value;
            scope.addOneBindValue = parseInt(scope.bindValue) + 1;
            scope.addOneValue = parseInt(scope.value) + 1;
        }
    };
});

输出:

Directive bind-value is: 12
Directive value is: 7
Directive add one to bind-value is: null    <--- why?
Directive add one to value is: 8    

SubDirective bind-value is: 7
SubDirective value is:                      <--- why?
SubDirective add one to bind-value is: null
SubDirective add one to value is: null  
4

1 回答 1

13

当链接函数运行时,内插属性(即使用 {{}} 的属性)和使用“@”定义的隔离范围属性不可用。您需要使用attrs.$observe()(or scope.$watch( @ property here, ...)) 来获取值(异步)。

因此,scope.bindValue当您尝试使用它时不可用。

同样,在您的 subDirective 中,属性value具有 {{}},因此当您尝试使用它时,它的值也将不可用。您还需要为此定义一个“@”指令属性。

工作小提琴

异步要求的原因是 {{}} 中的项目可能会更改,并且您通常希望您的指令注意到(然后做一些事情——比如更新“addOne”值)。当属性值包含 {{}} 时,“@”通常与隔离范围一起使用。

如果属性值是常量,并且您不打算在模板(或 templateUrl)中使用这些值,那么可能不应该使用“@”。在链接函数中,attrs.attrName如果值是字符串,或者scope.$eval(attrs.attrName)属性是数字或布尔值(或者parseInt(attrs.attrName)如果您知道它是数字),则只需使用。

于 2013-03-15T17:54:35.053 回答