我是控制器的新手作为angular的语法,只是试图理解它如何与指令一起工作。我已经为密码验证创建了一个指令。我想根据条件使一些标志为真,并且这些将在父模板中用于显示错误消息。我不知道怎么能实现这个目标!
查看
<div ng-app="myapp">
<fieldset ng-controller="PersonCtrl as person">
<input name="emailID" type="text" ng-model="person.first" >
<input name="pass" type="password" ng-model="person.pass" password-validator>
<p ng-show="person.showMsg">Password validation message here.</p>
</fieldset>
</div>
指令
myapp.directive('passwordValidator',function() {
return {
controller : PasswordCtrl,
controllerAs : 'dvm',
bindToController : true,
require : ['ngModel','passwordValidator'],
link : function(scope,ele,attrs,ctrls) {
var person = ctrls[1];
var ngModelCtrl = ctrls[0];
scope.$watch(function() {
return ngModelCtrl.$modelValue;
},function(newVal) {
if(newVal!='') {
person.showMsg = true;
} else {
person.showMsg = false;
}
console.log(person.showMsg);
});
}
}
function PasswordCtrl() {
}
});
特别想知道为什么以及如何在手表下工作正常!
// Why this below is also working, can anyone explain what's going behind!!
scope.$watch('person.pass',function(newVal) {
console.log("Watch fires");
});
这仅用于学习目的,因此请说明controllerAs
和bindToController
的工作原理!
答案 0 :(得分:1)
你的例子有点乱,但生病了,试着回答你的问题。
// Why this below is also working, can anyone explain what's going behind!!
scope.$watch('person.pass',function(newVal) {
console.log("Watch fires");
});
这是有效的,因为您的指令使用SAME作用域和变量作为其父控制器。
this.checkDirCtrl = function() {
console.log($scope.dvm);
}
this
未定义,因为您在SAME范围上使用controllerAs,因此未创建名为dvm
的新变量,并且所有dvm
控制器变量都在父范围内初始化。
这意味着你不需要注射&#39; person controller into指令,因为你已经在指令范围内有控制器实例。所以只需设置你的变量&#39; showMsg&#39;像这样,它将像魔术一样工作!
if(newVal!='') {
scope.person.showMsg = true;
} else {
scope.person.showMsg = false;
}
console.log(scope.person.showMsg);
我为你做了一个小提琴:JSFiddle
答案 1 :(得分:1)
我知道这不是你问题的一部分,我会谈到它,但使用指令'ng-controller'是一种反模式。如果有兴趣为什么我可以在一个单独的帖子中解释,但简而言之,它使代码更难以遵循。
现在,了解你问题的核心。
通过阅读bindToController
的Angular文档,如果您还没有创建一个孤立的范围,即scope: true
或scope: {}
,它似乎无法执行任何操作。
就我个人而言,我以前从未使用它,似乎没什么用处。
使用ng-controller本质上是使用该控制器对象向当前作用域添加属性。
所以:
<fieldset ng-controller="PersonCtrl as person">
有效地说,(以一种人为的方式):
$scope.person = new PersonCtrl();
在其中使用passwordValidator
语法的指令controllerAs
基本上是这样做的:
$scope.dvm= new PasswordCtrl();
在这种情况下,您实际上有一个范围对象,如下所示:
$scope = {
person = new PersonCtrl(),
dvm: new PasswordCtrl()
}
您的person
控制器和dvm
控制器是兄弟对象。
在您的passwordValidator
指令中,您需要在其控制器中,即dvm
对象。使用dvm
对象设置person.showMsg
与执行操作相同:
$scope.dvm.person.showMsg = <value>
dvm
对象没有办法在$ scope上访问person
对象,因为它们是兄弟姐妹。因此,您需要使用$ scope本身来访问person对象。你需要这样做:
$scope.person.showMsg = <value>
虽然这假设范围内存在person
,这是一个危险的假设。