在指令中嵌套指令

Ste*_*ven 7 angularjs angularjs-directive

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

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

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

HTML:

<directive bind-value="12" value="7"></directive>
Run Code Online (Sandbox Code Playgroud)

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;
        }
    };
});
Run Code Online (Sandbox Code Playgroud)

输出:

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  
Run Code Online (Sandbox Code Playgroud)

Mar*_*cok 13

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

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

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

工作小提琴.

异步要求的原因是{{}}内的项可能会发生变化,您通常希望指令注意(然后执行某些操作 - 例如更新"addOne"值).当属性值包含{{}}时,'@'通常与隔离范围一起使用.

如果属性值是常量,并且您不打算使用模板(或templateUrl)中的值,则可能不应使用"@".在链接函数中,只要使用attrs.attrName值是字符串,或者scope.$eval(attrs.attrName)属性是数字还是布尔值(或者parseInt(attrs.attrName)如果您知道它是数字).

  • 关于"如果属性值是常量,'@'可能不应该使用",那么当我嵌套指令时呢?我的最外面的指令可能看起来像<directive value ="7"> </ directive>但由于它使用的是templateURL,它通过插值属性调用我的子指令.这是对templateURL的正确使用还是我应该通过angular.element自己构建元素并将其添加到模板中?对于我来说,为了避免插值属性,后来感觉就像是一项额外的工作. (3认同)