AngularJS:指令隔离范围 - 范围变量undefined

时间:2017-03-10 22:45:31

标签: angularjs angularjs-directive angularjs-scope

请有人解释一下,为什么attrDir的范围变量可见,oneWay不是? 我认为scope: {}也是孤立的。

angular.module('test', []);

angular.module('test').directive('attrDir', attrDir);

function attrDir(){
    return {

        scope: true,

        link: function(scope){
          scope.hello = 'attrDir';
        }

    };
}

angular.module('test').directive('oneWay', oneWay);

function oneWay(){
    return {

        scope: {
          data: '<?'
        },

        link: function(scope){
          scope.hello = 'oneWay';  
        }

    };
}

hello只会在attr-dir中呈现。

<attr-dir>
  <span>{{hello}}</span>
</attr-dir>
<one-way>
  <span>{{hello}}</span>
</one-way>

这是一个掠夺者:https://plnkr.co/edit/2CM4vVRshWuJvaBj2q8T?p=preview

THX。

4 个答案:

答案 0 :(得分:2)

首先,您观察的内容与 char* line = NULL; char* line2 = NULL; size_t len = 0; size_t len2 = 0; char *function = NULL; size_t read, read2; //read2 gia to config while ((read = getline(&line, &len, op)) != -1) { line[read - 2] = 0; char* pch; pch = strtok(line, " "); strcpy(function, pch); 绑定无关。

问题是两个指令中的表达式<不是这些指令的模板的一部分。对于这些元素,绑定规则是不同的。

Angular会自动为{{hello}}表达式创建链接函数。但是在这种情况下,评估这些链接函数的范围是不同的。

你可能期望的是:

{{hello}}

然而,根据this comment in source

  

//如果isolate指令有一个,我们只传递隔离范围   template,
//否则子元素不属于isolate   指令。

真实情况如下:

            rootScope
         /             \
        /               \
attr-dir-new-scope  one-way-isoloate-scope
      /                   \
     /                     \
{{hello}}               {{hello}}

因此,在您的示例中,第一个指令 root scope / \ \ / \ \ attr-dir-new-scope \ one-way-isoloate-scope / \ / \ {{hello}} {{hello}} 不会创建隔离范围,但会创建新范围,因此在链接角度时,将此新范围传递给指令的链接函数:

<attr-dir>

以及为link: function(scope){ scope.hello = 'attrDir'; } 表达式创建的链接函数。这就是为什么当你在链接函数中添加一个值时,它在表达式链接函数中可用。

但是你的第二个指令{{hello}}会创建隔离范围,根据我上面提到的评论,指令的链接功能会得到隔离范围,因为它应该,但表达式的链接函数接收不同的范围(在您的示例中为根范围)。因此,您需要在不同的范围上添加<one-way>值。这就是为什么价值未定义的原因。

答案 1 :(得分:0)

范围:true和范围:{}将为指令创建子范围。但是,

范围:true将原型继承父级的属性(比如指令所在的控制器),其中asscope:{}不会从父级继承属性,因此称为隔离

由于oneWay是一个独立的范围指令,并且您没有传递问候语,因此它在HTML中未定义。

答案 2 :(得分:0)

如果未指定范围,则为共享范围。 如果scope指定为true,则它是继承范围。 如果使用花括号指定范围,则它是隔离范围。

可视化范围的最佳方法是在链接函数中使用console.log语句,如下所示,

link: function(scope) {          
      scope.hello = 'attrDir';
      console.log('scope in attrDir: ', scope);
    }

    link: function(scope) {          
          scope.hello = 'oneWay';
          console.log('scope in oneWay: ', scope);
        }

如果打开开发人员工具,您将看到第一个指令在其原型

中继承其父作用域
__proto__:Scope 

而第二个是具有自己范围的对象(通过使用花括号,你给它一个隔离范围)

__proto__:Object

答案 3 :(得分:-2)

因为你在指令中实现组件绑定。

  

&lt; symbol表示从1.5开始可用的单向绑定。

如果您想在hello组件中显示one-way,则应更改以下实施方式:

HTML

 <one-way hello="$ctrl.hello">
      <span>{{$ctrl.hello}}</span>
    </one-way>

JS

angular.module('test').component('oneWay', {
  bindings:{
    hello:'='
  },
  controller: function() {
    this.hello = 'oneWay';
  }
});

演示

plnkr