使用controllerAs语法通过$watch指令更改父控制器模型
Change parent controller model through directive $watch using controllerAs syntax
我是新的控制器的语法角,只是试图了解它是如何与指令工作。我创建了一个密码验证指令。我想根据条件使一些标志为真,这些将在父模板中用于显示错误消息。我不明白我怎么能做到这一点!
JSFiddle
<视图/strong>
<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
是如何工作的!
我知道这不是你问题的一部分,我会得到它,但使用指令'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
对象没有访问person
对象的方法,因为它们是$作用域上的兄弟对象。因此需要使用$作用域本身来访问person对象。你需要这样做:
$scope.person.showMsg = <value>
虽然这里假设person
存在于作用域中,但这是一个危险的假设。
你的例子有点乱,但我会尽量回答你的问题。
// Why this below is also working, can anyone explain what's going behind!!
scope.$watch('person.pass',function(newVal) {
console.log("Watch fires");
});
这样做是因为你的指令在它的父控制器上使用了相同的作用域和变量。
this.checkDirCtrl = function() {
console.log($scope.dvm);
}
this
是未定义的,因为你在同一个作用域中使用了控制器,所以没有创建新的变量dvm
,所有的dvm
控制器变量都在父作用域中初始化。
这意味着你不需要将person controller"注入"到指令中,因为你已经在指令范围中有了控制器实例。所以只要像这样设置你的变量'showMsg',它就会像魔术一样工作!
if(newVal!='') {
scope.person.showMsg = true;
} else {
scope.person.showMsg = false;
}
console.log(scope.person.showMsg);
我为你做了一个小提琴:JSFiddle
- 将不在模型中的数据返回到mvc控制器
- 当显式定义控制器参数时,默认模型绑定器会发生异常
- 模型数据未通过窗体传播到控制器ASP.NET MVC4
- 概念验证模型控制器调用正确的实例
- 如何从其他控制器更改角度模型值
- 如何在打开模型时动态加载控制器文件
- 如何从另一个控制器更新控制器的ng重复模型
- 控制器内部无法访问Angular js输入模型
- 将视图链接到模型并将视图链接至控制器的代码位于何处
- 一个控制器如何在 Ember .js 中观察任意控制器/模型上的事件
- Angularjs 绑定 2 指令将模型范围限定为父控制器模型
- 角度文件上传指令不更新控制器模型
- 在javascript中阅读弹簧控制器模型
- UI-select2 内部指令未更新控制器模型
- EmberJS:基于另一个属性重新加载控制器模型的最佳方法
- AngularJS -在指令中改变控制器模型
- 如何在javascript中获取springmvc控制器模型键值
- 使用controllerAs语法通过$watch指令更改父控制器模型
- 使用控制器模型向数组中添加对象
- 如何使用Ajax进程显示来自控制器/模型的数据