32

DOM イベントをトリガーするウォッチがあります。

scope.$watch(function() { return controller.selected; }, function(selected) {
    if (selected) {
        $input.trigger('focus');
    }
});

問題は、「フォーカス」にハンドラーがあり、scope.$apply.

$input.bind('focus', function() {
    scope.$apply(function() { controller.focused = true; });
});

したがって、 my$watchが a の内部$digestから起動されると、別の をトリガーしようとするため、エラーが発生します$digest

私が持っている回避策は、トリガーを$timeout.

scope.$watch(function() { return controller.selected; }, function(selected) {
    if (selected) {
        $timeout(function() { $input.trigger('focus'); });
    }
});

これは機能します...これまでのところ。これはこれを処理する適切な方法ですか?これがすべてのケースをキャッチするかどうかはわかりません。ダイジェスト後にコードの一部を延期する角度のある承認された方法があるかどうかを確認したいと思います。

ありがとう!

4

2 に答える 2

66

$timeoutは、通常、ダイジェスト サイクルの(およびブラウザーがレンダリングした後)に何かを実行するために使用されます。

$timeout関数が実行された後、別のダイジェスト サイクルが実行されます。triggerAngular に何の影響も与えない場合は、invokeApply引数をに設定して、false別のダイジェスト サイクルを実行しないようにすることができます。

ブラウザーがレンダリングする前にコールバックを実行したい場合: コードが$evalAsync ディレクティブを使用してキューに入れられた場合、DOM が Angular によって操作された後、ブラウザーがレンダリングする前に実行する必要があります。ただし、コードが$evalAsync コントローラーを使用してキューに入れられた場合、DOM が Angular によって操作される前 (およびブラウザーがレンダリングする前) に実行されます。https://stackoverflow.com/a/17303759/215945も参照してください。

于 2013-04-17T17:32:55.470 に答える