2015-10-06 91 views
5

我正在玩指令的bindToController选项。我偶然发现了使用子范围的行为与孤立范围之间的看似奇怪的区别。当我使用隔离的作用域时,将为该指令创建一个新的作用域,但对绑定的控制器属性的更改将转发到父作用域。然而,当我使用一个子范围,而我的例子中断。 (使用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

因为vm.name是字符串和JavaScript传值?可能会再创建一个像vm.data.name这样的嵌套对象并绑定数据。 – YOU

+0

实际上,在后一种情况下绑定到一个对象(请参阅:http://jsfiddle.net/sbvm1nd4/)。尽管如此,我仍然不明白孤立子域与子域之间为什么会有所不同,但我希望孤立域也会遇到同样的问题。 –

+0

其原型继承的JavaScript性质 - https://github.com/angular/angular.js/wiki/Understanding-Scopes,我个人认为角度可以改变这种行为是一致的,因为所有的表达式都是通过角度的AST来分析的,但是可能是他们选择遵循javascript的本质。 – YOU

回答

3

这是因为您对两个控制器使用相同的别名(并且与注释中提到的对象vs字符串值无关)。

如您所知,controller as alias语法只是在作用域上创建alias属性并将其设置为控制器实例。由于在这两种情况下(MainCtrlFooDirCtrl)您都使用vm作为别名,所以在“”正常子范围的情况下,您正在“隐藏”MainCtrl别名。 (在这种情况下,“正常”的意思是“从父范围原型继承”)。 因此,当您试图在新范围上评估vm.namevmMainCtrl以获得“父值”时, FooDirCtrl.name(这是未定义的),当您尝试将其分配回父作用域时会发生同样的情况。

隔离区作用域版本不受影响,因为作用域不是从它的父作用域继承的。

Updated fiddle


UPDATE: 以源代码仔细一看,这可能是一个错误(因为加入了bindToController非隔离示波器支持“追溯”)。 由于原型继承,我们似乎已经摆脱了这个bug,但当名称相撞时,我们运气不佳。

我不得不仔细看看它是否确实是一个错误,如果它是“可修复的”,但现在你可以通过为你的控制器使用不同的别名来解决它(见上面的小提琴)。


这就是为什么我不喜欢使用vm我的电脑板别名(尽管它是通过流行的风格指南建议)(的一部分):)

让我们在angular.js#13021跟踪此。

+0

感谢您的回复。我会密切关注线程。当我们对这个问题进一步讨论时,我会接受答案。我顺便也不是'vm'的粉丝,tbh,我偷了小提琴,只是调整了第二个例子;-) –

+0

@ Jan-WillemGmeligMeyling:顺便说一句,我提交了一个修正:[angular。 js#13025](https://github.com/angular/angular.js/pull/13025) – gkalpak

+0

它被合并。所以,这会从v1.5.0-beta.2开始正常工作。 – gkalpak