2

我對AngularJS還是比較新的,我想我無法理解$ scope的時機。在一個控制器中,我爲一些綁定到各種表單元素的模型數據設置了一個觀察器。當數據發生變化時,監視器會觸發ajax請求,除非表單無效。我正在使用myForm。$ valid檢查表單有效性。然而,除非在控制器中更新了模型數據,而且沒有形式,否則這非常簡單。驗證按預期運行,但形式。$ valid仍然具有先前的值,而不是更新後的數據。例如,如果表單先前是有效的,那麼我刪除綁定到所需輸入的模型值,觀察者將因爲模型數據已更改而觸發,但是當我記錄myForm。$ valid的值時,它的值仍然爲真,即使它應該是錯誤的。當模型數據在angularjs中的表單之外更改時,如何正確檢查觀察者中的表單有效性?

所以我的問題是A.爲什麼會發生這種情況?但更重要的是B.什麼是正確的方式來處理我想要完成的事情?自定義指令是否有意義?

這裏是一個簡化的例子。

HTML:

<div ng-controller="MyCtrl"> 
    <form name="myForm"> 
     <input type="text" name="myField" ng-model="myData" required> 
     <button type="button" ng-click="myData=''">Delete</button> 
    </form> 

    <div> 
     The watcher says the form is: <strong>{{ formStatus }}</strong>  
    </div> 
</div> 

控制器:

myApp.controller('MyCtrl', ['$scope', function($scope) { 
    $scope.myData = 'abc'; 
    $scope.formStatus = ''; 

    $scope.$watch('myData', function(newVal, oldVal) { 
     if (newVal != oldVal) { 
      console.log("my data changed"); 
      console.log("my form valid = ", $scope.myForm.$valid);   
      $scope.formStatus = $scope.myForm.$valid ? 'Valid' : 'Invalid'; 
     } 
    }); 
}]); 

小提琴:http://jsfiddle.net/anpsince83/cK6cc/1/

+0

似乎工作[在這個小提琴](http://jsfiddle.net/h9tUK/)。這是否符合您的期望? – KayakDave

+0

會把手錶放在'$ valid'本身上嗎?像這樣:http://jsfiddle.net/h9tUK/1/ – KayakDave

+0

嗯。小提琴肯定是在工作。在我的應用程序中,我有一個嵌套表單更復雜的設置,我想知道它是否與此有關。 – aaronp

回答

3

自定義指令是正確的道路要走。通常建議出於少數幾個原因,手錶應置於指令與控制器之間。在很高的層面上,一個原因是Angular推薦的控制器很薄,只能作爲視圖和服務之間的粘合劑。但是你正在碰到一個特殊的,有趣的原因。

控制器在Angular指令鏈接之前運行。因此,在Angular的ngModelWatch()myData執行操作之前,您的控制器手錶會被添加到監視列表中。 ngModelWatch()是Angular運行的地方$formatters(回想起$formatters是其中之一,當模型發生變化時觸發驗證的地方)。

由於手錶是在它們被添加到監視列表的順序執行,您控制器$watch之前驗證$formatters正在做執行。

如果您將相同的$watch放在指令中,那麼在ngModelWatch()已被添加到監視列表中後,它將在鏈接期間添加。因此指令的$watch將在驗證完成後執行。

這裏是an updated fiddle在這裏你可以觀看執行的順序$formatters和每個$watch。您將看到指令版本按預期工作 - 在$formatters之後運行。

+0

感謝您的明確解釋和更新小提琴!這正是我所期待的。 – aaronp

相關問題