2016-09-29 30 views
4

我剛剛接觸到了controllerAs的angular語法,並試圖瞭解它如何與指令一起工作。我創建了一個用於密碼驗證的指令。我想根據條件使標記爲真,並且這些標記將用於父模板中以顯示錯誤消息。我沒有得到我該如何實現這一點!

JSFiddle

VIEW

<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"); 
}); 

這僅僅是學習的目的,所以請解釋如何controllerAsbindToController作品!

+0

你的要求是什麼?解釋或解決方案 –

+0

解決方案詳細說明它的工作原理。 –

+0

在angularjs中使用指令時(或者只是使用angularjs),它對於理解摘要生命週期很重要,它基本上是對作用域模型和視圖之間的變化進行髒檢查。這是使我們的生活更容易的核心功能。這是我讀過的關於該主題的最好的文章https://www.sitepoint.com/understanding-angulars-apply-digest/ –

回答

1

我知道這不是你的問題的一部分,我會得到它,但使用的指令「NG控制器」是一個反模式。如果如果如果有興趣,我可以在另一篇文章中解釋,但總之,它使代碼更難以遵循。

現在,去問你的問題的核心。

從閱讀bindToController的Angular文檔可以看出,如果您還沒有創建隔離範圍,即scope: truescope: {},那麼它不會執行任何操作。

我個人從來沒有使用過它,似乎並不特別有用。

使用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對象,因爲它們是兄弟姐妹,在$範圍。所以你需要使用$ scope來訪問person對象。你需要做的:

$scope.person.showMsg = <value> 

雖然這個假設person存在的範圍,這是一個危險的假設。

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因爲您使用的是相同的範圍內使新的變量controllerAs稱爲dvm沒有創建和所有的控制器dvm變量是在父範圍初始化是不確定的。

這意味着您不需要將人員控制器注入指令,因爲您已經在指令範圍上有控制器實例。所以只需設置你的變量'showMsg'就可以了,它就像魔術一樣工作!

 if(newVal!='') { 
     scope.person.showMsg = true; 
     } else { 
     scope.person.showMsg = false; 
     } 
     console.log(scope.person.showMsg); 

我做了一個搗鼓你:JSFiddle

+0

我不想使用範圍.. –

相關問題