2

私はまだ AngularJS にかなり慣れていないので、$scope のタイミングを理解するのに苦労していると思います。コントローラーでは、さまざまなフォーム要素にバインドされたモデル データのウォッチャーをセットアップしました。ウォッチャーは、フォームが無効な場合を除き、データが変更されると ajax リクエストを送信します。myForm.$valid でフォームの有効性をチェックしています。ただし、モデル データがフォームではなくコントローラーで更新される場合を除いて、これはすべて非常に簡単です。検証は期待どおりに実行されますが、form.$valid には、更新されたデータの値ではなく、以前の値が残っています。たとえば、フォームが以前に有効だった場合、必要な入力にバインドされたモデル値を削除すると、モデル データが変更されたためにウォッチャーが起動しますが、myForm.$valid の値をログに記録すると、その値はまだ true です。

だから私の質問は、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/

4

1 に答える 1

3

カスタム ディレクティブは正しい方法です。一般に、いくつかの理由から、ウォッチをコントローラーではなくディレクティブに配置することをお勧めします。大まかに言えば、1 つの理由は、Angular がコントローラーをシンであり、ビューとサービスの間の接着剤としてのみ動作することを推奨していることです。しかし、あなたは特定の興味深い理由にぶつかっています。

ngModelWatch()コントローラーは、Angular ディレクティブがリンクされる前に実行されます。したがって、コントローラー ウォッチは、Angularが for を行う前にウォッチ リストに追加されmyDataます。 ngModelWatch()Angular が実行される場所です (とりわけ、モデルに変更が発生したときに検証がトリガーされる場所であること $formattersを思い出してください)。$formatters

ウォッチはウォッチ リストに追加された順序で実行されるため、コントローラは によって$watch検証が行われる前に実行され$formattersます。

代わりにディレクティブ内に同じものを入れると、ウォッチ リストに追加された$watch後、リンク中に追加されます。ngModelWatch()したがって、検証が完了した後にディレクティブ$watchが実行されます。

と eachの実行順序を確認できる更新されたフィドルを次に示します。そして、ディレクティブのバージョンが期待どおりに動作することがわかります- running after 。$formatters$watch$formatters

于 2014-01-10T19:03:51.323 に答える