簡體   English   中英

使用controllerAs語法通過指令$ watch更改父控制器模型

[英]Change parent controller model through directive $watch using controllerAs syntax

我是控制器的新手作為angular的語法,只是試圖理解它如何與指令一起工作。 我已經為密碼驗證創建了一個指令。 我想根據條件使一些標志為真,並且這些將在父模板中用於顯示錯誤消息。 我不知道怎么能實現這個目標!

的jsfiddle

視圖

<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如何工作!

你的例子有點亂,但生病了,試着回答你的問題。

// 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: truescope: {}它不會做任何事情。

我個人以前從未使用它,似乎沒有特別有用。

使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM