【发布时间】:2015-10-06 14:19:17
【问题描述】:
我在玩 bindToController 指令选项。我偶然发现了使用子作用域与隔离作用域的行为之间看似奇怪的区别。当我使用隔离作用域时,会为指令创建一个新作用域,但对绑定控制器属性的更改会转发到父作用域。然而,当我改用子范围时,我的例子就中断了。 (根据http://blog.thoughtram.io/angularjs/2015/01/02/exploring-angular-1.3-bindToController.html#improvements-in-14 应该允许使用bindToController 使用子作用域)
代码:
{
restrict: 'E',
scope: {},
controller: 'FooDirCtrl',
controllerAs: 'vm',
bindToController: {
name: '='
},
template: '<div><input ng-model="vm.name"></div>'
};
工作演示https://jsfiddle.net/tthtznn2/
使用子作用域的版本:
{
restrict: 'E',
scope: true,
controller: 'FooDirCtrl',
controllerAs: 'vm',
bindToController: {
name: '='
},
template: '<div><input ng-model="vm.name"></div>'
};
演示:http://jsfiddle.net/ydLd1e00/
对名称的更改将转发到子范围,但不会转发到父范围。这与绑定到隔离范围相反。这是为什么呢?
【问题讨论】:
-
因为 vm.name 是字符串和 javascript 值传递?可能是,再创建一个嵌套对象,如 vm.data.name 并绑定数据。
-
在后一种情况下绑定到对象确实有效(参见:jsfiddle.net/sbvm1nd4)。我仍然不明白为什么隔离范围和子范围之间存在不同,但我希望隔离范围会遇到同样的问题。
-
其原型继承的 javascript 性质 - github.com/angular/angular.js/wiki/Understanding-Scopes,我个人认为 angular 可以将这种行为更改为一致,因为所有表达式都是通过 angular 的 AST 解析的,但可能是他们选择遵循 javascript 的性质。
-
我了解 JavaScript 的原型继承。我的问题是,通过定义与控制器的双向绑定,我希望将更改传播到父范围(您同意这是
bindToController选项的用途,对吧?)。 -
我知道范围。我也知道关于范围和角度的讨论。他们现在都不是我真正感兴趣的。我要问的是:因为子范围和隔离范围都创建了一个新范围。 (是的,第一个是通过原型继承创建的,我完全同意这一点)。但是为什么第一个选项双重绑定到新创建的范围,而第二个选项双重绑定到旧/父范围?对我来说,这似乎不一致。
标签: angularjs angularjs-directive angularjs-scope