更新 :在代码的另一部分中一定有些愚蠢。现在可以使用,因此bindToController语法很好。
我们正在使用AngularJS 1.4,它引入了在指令中使用bindToController的新方法。
经过大量的阅读(也许并不能理解所有内容),我们如下定义了指令:
.directive('mdAddress', function mdAddress() { var directive = { restrict: 'EA', scope: {}, bindToController: { address: '=' }, templateUrl: 'modules/address/address.html', controller: AddressController, controllerAs: 'dir' };
从这样的另一个视图调用它:
<md-address address="vm.address"></md-address>
先前已在视图控制器中定义:
vm.address = { street: null, countryCode: null, cityCode: null, postalCode: null };
像这样在指令模板中引用变量:
<md-input-container> <label>{{'ADDRESSNUMBER' | translate}}</label> <input type="number" ng-model="dir.address.streetNumber"> </md-input-container>
我们花了4小时试图弄清楚为什么我们的指令不起作用。很好,它正在工作,但是控制器和指令之间的双向绑定没有实现,因此vm.address.street被无望地设置为null。
vm.address.street
一段时间后,我们只是尝试了旧方法:
.directive('mdAddress', function mdAddress() { var directive = { restrict: 'EA', scope: { address: '=' }, bindToController: true, templateUrl: 'modules/address/address.html', controller: AddressController, controllerAs: 'dir' };
它神奇地工作。知道 为什么 吗?
更新:
感谢对此博客文章的引用,我需要更新我的答案。从AngularJS 1.4开始,您似乎可以使用
scope: {}, bindToController: { variable: '=' }
它将(完全)执行与旧语法相同的操作:
scope: { variable: '=' }, bindToController: true
AngularJS源代码中的有用代码行解释了此行为:
if (isObject(directive.scope)) { if (directive.bindToController === true) { bindings.bindToController = parseIsolateBindings(directive.scope, directiveName, true); bindings.isolateScope = {}; } else { bindings.isolateScope = parseIsolateBindings(directive.scope, directiveName, false); } } if (isObject(directive.bindToController)) { bindings.bindToController = parseIsolateBindings(directive.bindToController, directiveName, true); }
资料来源:AngularJS 1.4.0
原始答案:
希望我能向您解释为什么您遇到的这种行为是正确的,以及您在哪里错过了理解范围绑定概念的原因。
让我解释一下,您在第一个代码段中做了什么:
使用scope: {},您为mdAddress指令创建了一个隔离范围(没有任何继承)。这意味着:在父控制器和您的指令之间不传递任何数据。
scope: {}
mdAddress
考虑到这一点,关于第二个代码段:
vm.address来自您的父控制器/视图的数据将作为表达式分配给指令的address属性,但是由于您之前定义了隔离范围,因此数据不会传递到AddressController该bindToController值中,因此无法使用。
vm.address
AddressController
bindToController
让我们将scope对象定义视为“将传入哪些数据”,并将对象定义视为“ bindToController在我的视图的controllerAs对象中可用的数据”。
scope
因此,现在让我们看一下最后一个(以及有效的代码片段):
在那里,您也创建了一个孤立的作用域,但是这次您添加了address要作为表达式传递的属性。因此,现在address从第二个片段的视图中传入的您将在控制器的作用域中可用。bindToController: true现在设置,会将当前作用域的所有属性绑定到控制器(或更可能是controllerAs对象)。现在,它可以按您期望的那样工作,因为数据将被传递到合并范围,并且数据将被传递到控制器的模板范围。
address
bindToController: true
简要概述是否有助于您更好地理解scope和bindToController定义对象的概念?