在指令中嵌套指令

时间:2013-03-15 17:41:33

标签: angularjs angularjs-directive

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

  1. 为什么我不能在我的链接功能中引用scope.bindValue?有没有办法可以从scope.bindValue计算一个值并将其设置为范围?
  2. 为什么在范围内使用“@”表示子对象绑定:{}但是在链接函数中不使用scope.value = attrs.value?
  3. 以下所有内容均可在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  
    

1 个答案:

答案 0 :(得分:13)

插值属性(即使用{{}} s的属性)并隔离用&#39; @&#39;定义的范围属性。链接功能运行时不可用。您需要使用attrs.$observe()(或scope.$watch( @ property here, ...))来获取值(异步)。

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

同样,在您的subDirective中,属性attrs.attrName有{{}} s,因此当您尝试使用它时,它的值也不可用。您还需要定义一个&#39; @&#39;指令属性。

工作fiddle

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

如果属性值是常量,并且您不打算使用模板(或templateUrl)中的值,那么&#39; @&#39;可能不应该使用。在链接函数中,如果值是字符串,则使用scope.$eval(attrs.attrName);如果属性是数字或布尔值,则使用parseInt(attrs.attrName)(如果您知道它是数字,则使用{{1}}。) / p>