我有一个控制器,应该将输入字段中的文本写入屏幕。如果我自己使用这个控制器,一切都按预期工作:
(function() {
angular.module('test', []);
function OneCtrl() {
vm = this;
vm.changeHandler = changeHandler;
vm.item = "";
vm.value = "";
}
angular
.module('test')
.controller('OneCtrl', OneCtrl);
var changeHandler = function() {
vm.value = vm.item;
console.log(vm.item);
};
})();
在此尝试:http://codepen.io/minuskruste/pen/qdrZqq
但是,如果我添加另一个具有相同行为的控制器,则会发生一些非常奇怪的事情。首先,字段1的输入不再发送到控制台,文本也没有插入到html主体中。其次,当我在输入字段2中键入内容时,它的行为正确。如果我现在返回到字段1并在那里键入,则突然将字段2输入输出到控制台,即使控制器2从未被告知这样做!这是控制器2:
(function(){
function TwoController(){
vm = this;
vm.changeHandler = changeHandler;
vm.item = "";
vm.value = "";
}
angular
.module('test')
.controller('TwoController', TwoController);
var changeHandler = function() {
vm.value = vm.item;
};
})();
在此尝试:http://codepen.io/minuskruste/pen/QbpNdY
这是正常行为吗?我很惊讶它。我还检查了changeHandler()
是否泄漏到了全球空间,但是因为我把所有东西放在封闭中并非如此。此外,这在不同平台即Chrome和FF上是一致的。有任何想法吗?
答案 0 :(得分:1)
这是因为您正在使用全局“vm”变量,该变量包含此控制器的引用。使用第二个控制器,你将参考第二个控制器覆盖vm变量。
我已更新您的代码以正确使用此引用
此外,angular还支持使用特殊$ scope对象的另一种数据绑定方法:https://docs.angularjs.org/guide/scope
(function() {
angular.module('test', []);
function OneCtrl($scope) {
// This construction makes sure I know which context is addressed. I can now hand vm (view-model) inside an object and the context doesn't change.
this.changeHandler = angular.bind(this, changeHandler);
this.item = "";
this.value = "";
}
angular
.module('test')
.controller('OneCtrl', OneCtrl);
var changeHandler = function() {
this.value = this.item;
console.log(this.item);
};
})();
(function(){
function TwoController(){
// This construction makes sure I know which context is addressed. I can now hand vm (view-model) inside an object and the context doesn't change.
this.changeHandler = angular.bind(this, changeHandler);
this.item = "";
this.value = "";
}
angular
.module('test')
.controller('TwoController', TwoController);
var changeHandler = function() {
this.value = this.item;
};
})();
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular.min.js"></script>
<body ng-app="test">
<h1>Choice array</h1>
<div>
<form novalidate ng-controller="OneCtrl as one">
<input
type="text"
ng-change="one.changeHandler()" ng-model="one.item">
<div>{{one.value}}</div>
</form>
<br>
<br>
<br>
</div>
<div>
<form novalidate ng-controller="TwoController as two">
<input
type="text"
ng-change="two.changeHandler()" ng-model="two.item">
<div>{{two.value}}</div>
</form>
</div>
</body>
答案 1 :(得分:1)
您遇到的部分问题是您在没有vm
关键字的情况下声明var
,这使其成为全局变量。
但是,带有vm
关键字的var
位于控制器的本地范围内。结果,changeHandler()
不再可用。如果您重新排序代码并在控制器内声明changeHandler()
,它将起作用。
(function() {
angular.module('test', []);
function OneCtrl() {
var vm = this;
vm.item = "";
vm.value = "";
vm.changeHandler = function() {
vm.value = vm.item;
console.log(vm.item);
}
}
angular
.module('test')
.controller('OneCtrl', OneCtrl);
})();
(function(){
function TwoController() {
var vm = this;
vm.item = "";
vm.value = "";
vm.changeHandler = function() {
vm.value = vm.item;
console.log(vm.item);
}
}
angular
.module('test')
.controller('TwoController', TwoController);
})();
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular.min.js"></script>
<body ng-app="test">
<h1>Choice array</h1>
<div>
<form novalidate ng-controller="OneCtrl as one">
<input type="text" ng-change="one.changeHandler()" ng-model="one.item">
<div>{{one.value}}</div>
</form>
<br><br><br>
</div>
<div>
<form novalidate ng-controller="TwoController as two">
<input type="text" ng-change="two.changeHandler()" ng-model="two.item">
<div>{{two.value}}</div>
</form>
</div>
</body>
答案 2 :(得分:0)
这是一篇关于Controller As语法的好文章。
http://www.johnpapa.net/angularjss-controller-as-and-the-vm-variable/
如果在每个控制器中声明vm变量,它将阻止您看到的覆盖行为。 Javascript是功能范围的,这意味着如果它在当前函数中找不到vm的变量声明,它将上升到原型链,直到找到声明(var vm)。如果它在全局范围内没有找到任何声明,它将自动为您创建一个声明。通过在每个控制器内部声明,您将阻止它们共享相同的全局范围。
function OneCtrl() {
// This construction makes sure I know which context is addressed. I can now hand vm (view-model) inside an object and the context doesn't change.
var vm = this;
vm.item = "";
vm.value = "";
vm.changeHandler = function() {
console.log(vm.item);
vm.value = vm.item;
};
}