我正在玩指令的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/
对名称的更改将转发到子作用域,但不会转发到父作用域。这与绑定到隔离范围形成对比。这是为什么?
答案 0 :(得分:3)
这是因为您对两个控制器使用相同的别名(并且与注释中提到的对象与字符串值无关)。
您可能知道,alias
语法只是在作用域上创建vm
属性并将其设置为控制器实例。由于您在两种情况下都使用MainCtrl
作为别名(FooDirCtrl
和MainCtrl
),因此在正常情况下,您正在“隐藏”vm.name
别名< / em>子范围。
(在这种情况下,“正常”意味着“原型继承父范围”。)
因此,当您尝试评估新范围的vm
(MainCtrl
为FooDirCtrl.name
)以获取“父值”时,它实际上正在评估bindToController
(这是当您尝试分配回父范围时,会发生同样的情况。
isolate 范围版本不受影响,因为范围不是从其父范围继承。
<强>更新强>
仔细查看源代码,这可能是一个错误(因为非追踪范围的vm
支持被“追溯”添加)。
由于原型继承,我们似乎已经逃脱了这个错误,但是当名字发生碰撞时,我们运气不好。
我必须仔细检查以确定它是否确实是一个错误,如果它是“可修复的”,但是现在你可以通过为控制器使用不同的别名来解决它(参见上面的小提琴)。
这是(部分)为什么我不喜欢使用{
"apple" : true,
"spotify" : true
}
作为我的控制器别名(尽管它受到流行风格指南的建议):)
让我们在angular.js#13021中跟踪此内容。