18

ページに ng フォームがあります。フォーム内には、フォームが汚れている場合に保存ダイアログを表示する必要があるいくつかのコントロールがあります。つまり、form.$dirty = true です。ただし、フォームを汚したくないフォームにはいくつかのナビゲーション コントロールがあります。コントロールをフォームの外に移動できないとします。

参照: http://plnkr.co/edit/bfig4B

選択ボックスがフォームを汚さないようにするにはどうすればよいですか?

4

7 に答える 7

14

@overthink のソリューションを使用しましたが、@dmitankin が言及した問題に遭遇しました。ただし、ハンドラーを focus イベントにアタッチしたくありませんでした。そこで代わりに、$pristine プロパティ自体をオーバーライドして、常に false を返すようにしました。IE8以下ではサポートされていない Object.defineProperty を使用してしまいました。これらの従来のブラウザーでこれを行うための回避策がありますが、私はそれらを必要としなかったため、以下のソリューションには含まれていません。

(function () {
    angular
        .module("myapp")
        .directive("noDirtyCheck", noDirtyCheck);

    function noDirtyCheck() {
        return {
            restrict: 'A',
            require: 'ngModel',
            link: function (scope, elem, attrs, ctrl) {
                var alwaysFalse = {
                    get: function () { return false; },
                    set: function () { }
                };
                Object.defineProperty(ctrl, '$pristine', alwaysFalse);
                Object.defineProperty(ctrl, '$dirty', alwaysFalse);
            }
        };
    }
})();

$dirty もオーバーライドしているので、ダーティとして設定することもできません。

于 2014-12-11T19:36:21.323 に答える
13

初期化時にのみ $pristine プロパティを false に設定すると、フォームで $setPristine() を呼び出すまで機能します。次に、コントロールの $pristine が true に戻り、入力の値を変更するとフォームが汚れます。これを避けるには、$pristine をフォーカスに設定します。

link: function(scope, elm, attrs, ctrl) {
    elm.focus(function () {
        ctrl.$pristine = false;
    });
}
于 2014-07-23T13:29:45.453 に答える
7

Angular は、コントロールが手付かずの場合にのみ、フォームをダーティに設定します。したがって、ここでの秘訣は、コントロールの $pristine を false に設定することです。コントローラーのタイムアウトで実行できます。

参照: http://plnkr.co/edit/by3qTM

于 2013-06-20T14:51:37.370 に答える
0

その実装でいくつかの問題に遭遇したので、これが私のものです(より複雑です):

app.directive('noDirtyCheck', [function () {
        // Interacting with input elements having this directive won't cause the
        // form to be marked dirty.
        // http://stackoverflow.com/questions/17089090/prevent-input-from-setting-form-dirty-angularjs
        return {
            restrict: 'A',           
            require: ['^form', '^ngModel'],

            link: function (scope, element, attrs, controllers) {
                var form = controllers[0];
                
                var currentControl = controllers[1];

                var formDirtyState = false;

                var manualFocus = false;

                element.bind('focus',function () {
                    manualFocus = true;
                    if (form) {                        
                        window.console && console.log('Saving current form ' + form.$name + ' dirty status: ' + form.$dirty);
                        formDirtyState = form.$dirty; // save form's dirty state
                    }
                 });
                
                element.bind('blur', function () {
                    if (currentControl) {
                        window.console && console.log('Resetting current control (' + currentControl.$name + ') dirty status to false (called from blur)');
                        currentControl.$dirty = false; // Remove dirty state but keep the value
                        if (!formDirtyState && form && manualFocus) {
                            window.console && console.log('Resetting ' + form.$name + ' form pristine state...');
                            form.$setPristine();
                        }
                        manualFocus = false;
                        //          scope.$apply();
                    }
                });
            }
        };
    }]);

于 2015-04-01T22:05:10.173 に答える