子范围中的行为bindToController与隔离范围的行为

时间:2015-10-06 14:19:17

标签: angularjs angularjs-directive angularjs-scope

我正在玩指令的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/

对名称的更改将转发到子作用域,但不会转发到父作用域。这与绑定到隔离范围形成对比。这是为什么?

1 个答案:

答案 0 :(得分:3)

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

您可能知道,alias语法只是在作用域上创建vm属性并将其设置为控制器实例。由于您在两种情况下都使用MainCtrl作为别名(FooDirCtrlMainCtrl),因此在正常情况下,您正在“隐藏”vm.name别名< / em>子范围。 (在这种情况下,“正常”意味着“原型继承父范围”。) 因此,当您尝试评估新范围的vmMainCtrlFooDirCtrl.name)以获取“父值”时,它实际上正在评估bindToController(这是当您尝试分配回父范围时,会发生同样的情况。

isolate 范围版本不受影响,因为范围不是从其父范围继承。

Updated fiddle

<强>更新 仔细查看源代码,这可能是一个错误(因为非追踪范围的vm支持被“追溯”添加)。 由于原型继承,我们似乎已经逃脱了这个错误,但是当名字发生碰撞时,我们运气不好。

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

这是(部分)为什么我不喜欢使用{ "apple" : true, "spotify" : true } 作为我的控制器别名(尽管它受到流行风格指南的建议):)

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