[英]AngularJS 1.4: How to create two-way binding using bindToController and controllerAs syntax
[英]AngularJS 1.4 directives: scope, two way binding and bindToController
更新 :在代码的另一部分中一定是愚蠢的。 它现在有效,所以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。
过了一会儿,我们只是尝试了旧的方式:
.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
原始答案:
希望,我可以解释一下为什么你所经历的这种行为是正确的,你在哪里错误地理解了那里的范围绑定的概念。
让我解释一下,你在第一段代码片段中做了些什么:
.directive('mdAddress', function mdAddress() {
var directive = {
restrict: 'EA',
scope: {},
bindToController: {
address: '='
},
templateUrl: 'modules/address/address.html',
controller: AddressController,
controllerAs: 'dir'
};
使用scope: {}
,您为mdAddress
指令创建了一个隔离的范围(没有任何继承)。 这意味着:父控制器和指令之间没有数据传递。
记住这一点,关于你的第二个代码片段:
<md-address address="vm.address"></md-address>
来自父控制器/视图的vm.address
将被指定为指令的地址属性的表达式,但是在您之前定义隔离的范围时,数据不会传递到AddressController
,因此在bindToController
值中不可用。
让我们将scope
对象定义视为“将传入哪些数据”,将bindToController
视为“哪些数据将在我视图的controllerAs对象中可用”。
那么,现在让我们看看最后一个(和工作代码片段):
.directive('mdAddress', function mdAddress() {
var directive = {
restrict: 'EA',
scope: {
address: '='
},
bindToController: true,
templateUrl: 'modules/address/address.html',
controller: AddressController,
controllerAs: 'dir'
};
在那里你也创建了一个独立的范围,但是这次你添加了要作为表达式传入的address
属性。 因此,现在您从第二个代码段中的视图传入的address
将在控制器的范围内可用。 设置bindToController: true
now,将所有当前作用域的属性绑定到控制器(或者更可能是controllerAs对象)。 现在,它可以按预期工作,因为数据将传递到范围,数据将传递到控制器的模板范围。
这个简短的概述是否有助于您更好地理解scope
和bindToController
定义对象的概念?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.