[英]Change parent controller model through directive $watch using controllerAs syntax
我是控制器的新手作為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
如何工作!
你的例子有點亂,但生病了,試着回答你的問題。
// 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
控制器變量都在父范圍內初始化。
這意味着你不需要將人控制器“注入”指令,因為你已經在指令范圍內有控制器實例。 所以只需像這樣設置你的變量'showMsg',它就像魔術一樣!
if(newVal!='') {
scope.person.showMsg = true;
} else {
scope.person.showMsg = false;
}
console.log(scope.person.showMsg);
我為你做了一個小提琴: JSFiddle
我知道這不是你問題的一部分,我會接受它,但使用指令'ng-controller'是一種反模式。 如果有興趣為什么我可以在一個單獨的帖子中解釋,但簡而言之,它使代碼更難以遵循。
現在,了解你的問題的核心。
通過閱讀bindToController
的Angular文檔,看起來如果你還沒有創建一個獨立的范圍,即scope: true
或scope: {}
它不會做任何事情。
我個人以前從未使用它,似乎沒有特別有用。
使用ng-controller本質上是使用該控制器對象向當前作用域添加屬性。
所以:
<fieldset ng-controller="PersonCtrl as person">
有效地說,(以一種人為的方式):
$scope.person = new PersonCtrl();
你在其中使用controllerAs
語法的指令passwordValidator
基本上是這樣做的:
$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
存在於范圍內,這是一個危險的假設。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.