11

http://jsfiddle.net/2NJ7y/3/ (AngularJS 1.0.1 のバージョン) の例を見てください。ラッキーナンバーの入力を待つシンプルなアプリがあります。数字が 7 の場合、ラッキー ナンバーを null にリセットします。数字の 7 を数回入力すると、時々/ランダムにラッキー ナンバーが入力フィールドに残ります。なんで?この動作はどのように解決しますか? ありがとう。

4

3 に答える 3

6

私はいくつかのデバッグを行いました。

まず、ラッキーナンバーはランダムではなく入力フィールドにとどまります。

enter 3 (model==3, input==3)=>enter 7 (alert, model==null, input="")

=> enter 3 (model==3, input==3)=>remove 3 (model=="", input=="")

=>enter 7 (alert, model==null, input="")

=>enter 7 (alert, model==null, input="7")

7 前のモデル値が null の場合にのみ、入力フィールドに留まります。

何が起こるか:入力ディレクティブのリスナー関数によって処理される 7 起動された入力イベントを入力すると。リスナー関数は$setViewValueを呼び出します。$setViewValue は $viewValue、$modelValue、モデル値を設定し、$viewChangeListeners を呼び出します (ngChangeDirective は $viewChangeListenersにハンドラを追加するだけです)。アラートが表示され、ラッキーナンバーが null に設定されます。結局、luckynumber が以前のダーティ チェックで以前の値と異なる場合、$watch ハンドラ$renderが呼び出されます。

私の例では、前のモデル値が「3」または「」の場合に $render が呼び出されました。前のモデルの値が null の場合、$render は呼び出されません。

$timeout with 0 delay が機能する理由: 0 delay 関数を指定して $timeout を呼び出し、luckynumber を null に変更すると、イベント キューの最後で延期されます(ブラウザー内のすべての JavaScript は単一のスレッドで実行されます)。$viewChangeListener はモデル値を 7 から null に変更しません。$digest が終了します。次に、$timeout ハンドラが呼び出されます。モデル値が null に設定されています。$watch ハンドラと $render が呼び出されます。$render は入力値を "" に設定します。

于 2012-09-08T14:02:45.067 に答える
3

ついに、解決策。ng-change の代わりに $watch を使用します。

$scope.$watch('luckynumber', function() {
    if ($scope.luckynumber == 7) {
        alert('The lucky number mustn\'t be equal 7.');
        $scope.luckynumber = null;
    }
})

フィドル

@Valentynによるこの他のSOの回答により、この質問に対するその解決策を試すことを考えさせられました。

于 2013-01-20T00:53:06.843 に答える
1

簡単に言えば

$scope.luckynumber = undefined;

アラートの前に競合状態を排除しませんが、7 が適切にクリアされるように変更しますが、アラートが 2 回発生することがあります。

エラーを表示するように DOM を変更するなど、アラート コードがべき等なものに置き換えられた場合、この問題は重要ではなくなります。

于 2012-09-07T16:38:53.983 に答える