64

フォームフィールドを元の状態にリセットする(ダーティ状態をリセットする)機能は、AngularJS1.1.xのロードマップにあります。残念ながら、このような機能は現在の安定版リリースにはありません。

AngularJS 1.0.xのすべてのフォームフィールドを初期の元の状態にリセットするための最良の方法は何ですか?

これがディレクティブまたは他の簡単な回避策で修正可能かどうか知りたいです。元のAngularJSソースに触れる必要のないソリューションを好みます。問題を明確にして実証するために、JSFiddleへのリンク。http://jsfiddle.net/juurlink/FWGxG/7/

必要な機能はロードマップにあります-http : //blog.angularjs.org/2012/07/angularjs-10-12-roadmap.html
機能リクエスト-https : //github.com/angular/angular.js/issues/856
提案されたソリューションプルリクエスト-https: //github.com/angular/angular.js/pull/1127

可能な回避策で更新

十分な回避策はありますか?

HTML部分を再コンパイルしてDOMに戻すことができると思いました。それは機能し、一時的な解決策としては問題ありませんが、コメントで@bleshが述べているように:

コントローラは、DOMではなく、ビジネスロジックにのみ使用する必要があります。

<div id="myform">
  <form class="form-horizontal" name="form">
  </form>
</div>

そして私のコントローラーでresetForm()

  • 元の手付かずのHTMLを保存します
  • 保存した元のHTMLを再コンパイルします
  • DOMから現在のフォームを削除します
  • 新しくコンパイルされたテンプレートをDOMに挿入します

JavaScript:

var pristineFormTemplate = $('#myform').html();
$scope.resetForm = function () {
    $('#myform').empty().append($compile(pristineFormTemplate)($scope));
}
4

7 に答える 7

85

$setPristineAngularの新しいバージョン(例:1.1.5)では、フォームを呼び出すことができることを言及する価値があると思います。

$scope.formName.$setPristine(true)

これにより、すべてのフォームコントロールも元の状態に設定されます。

FormController。$setPristine

于 2013-09-23T16:10:24.453 に答える
32

回避策のないソリューション

回避策なしでAngularJSを使用するソリューションを思いつきました。ここでの秘訣は、AngularJS機能を使用して、同じ名前の複数のディレクティブを持つことです。

他の人が述べたように、実際にはプルリクエスト(https://github.com/angular/angular.js/pull/1127)があり、フォームをリセットできるAngularJS1.1.xブランチになりました。このプルリクエストへのコミットにより、ngModelおよびform / ngFormディレクティブが変更されます(リンクを追加したかったのですが、Stackoverflowでは3つ以上のリンクを追加したくありません)。

これで、独自のngModelおよびform / ngFormディレクティブを定義し、プルリクエストで提供される機能でそれらを拡張できます。

これらのディレクティブをresettableFormという名前のAngularJSモジュールにラップしました。このモジュールをプロジェクトに含めるだけで、AngularJSバージョン1.0.xは、この点でAngular1.1.xバージョンであるかのように動作します。

「1.1.xに更新したら、コードを更新する必要はありません。モジュールを削除するだけで完了です!」

このモジュールは、フォームリセット機能のために1.1.xブランチに追加されたすべてのテストにも合格します。

私が作成したjsFiddle(http://jsfiddle.net/jupiter/7jwZR/1/)の例でモジュールが機能しているのを見ることができます。

ステップ1:プロジェクトにresettableformモジュールを含める

(function(angular) {

// Copied from AngluarJS
function indexOf(array, obj) {
  if (array.indexOf) return array.indexOf(obj);

  for ( var i = 0; i < array.length; i++) {
    if (obj === array[i]) return i;
  }
  return -1;
}

// Copied from AngularJS
function arrayRemove(array, value) {
  var index = indexOf(array, value);
  if (index >=0)
    array.splice(index, 1);
  return value;
}

// Copied from AngularJS
var PRISTINE_CLASS = 'ng-pristine';
var DIRTY_CLASS = 'ng-dirty';

var formDirectiveFactory = function(isNgForm) {
    return function() {
        var formDirective = {
            restrict: 'E',
            require: ['form'],
            compile: function() {
                return {
                    pre: function(scope, element, attrs, ctrls) {
                        var form = ctrls[0];
                        var $addControl = form.$addControl;
                        var $removeControl = form.$removeControl;
                        var controls = [];
                        form.$addControl = function(control) {
                            controls.push(control);
                            $addControl.apply(this, arguments);
                        }
                        form.$removeControl = function(control) {
                            arrayRemove(controls, control);
                            $removeControl.apply(this, arguments);
                        }
                        form.$setPristine = function() {
                            element.removeClass(DIRTY_CLASS).addClass(PRISTINE_CLASS);
                            form.$dirty = false;
                            form.$pristine = true;
                            angular.forEach(controls, function(control) {
                                control.$setPristine();
                            });
                        }
                    },
                };
            },
        };
        return isNgForm ? angular.extend(angular.copy(formDirective), {restrict: 'EAC'}) : formDirective;
    };
}
var ngFormDirective = formDirectiveFactory(true);
var formDirective = formDirectiveFactory();
angular.module('resettableForm', []).
    directive('ngForm', ngFormDirective).
    directive('form', formDirective).
    directive('ngModel', function() {
        return {
            require: ['ngModel'],
            link: function(scope, element, attrs, ctrls) {
                var control = ctrls[0];
                control.$setPristine = function() {
                    this.$dirty = false;
                    this.$pristine = true;
                    element.removeClass(DIRTY_CLASS).addClass(PRISTINE_CLASS);
                }
            },
        };
    });
})(angular);

ステップ2:モデルをリセットするメソッドをコントローラーに提供します

フォームをリセットするときは、モデルをリセットする必要があることに注意してください。コントローラでは、次のように書くことができます。

var myApp = angular.module('myApp', ['resettableForm']);

function MyCtrl($scope) {
    $scope.reset = function() {
        $scope.form.$setPristine();
        $scope.model = '';
    };
}

ステップ3:このメソッドをHTMLテンプレートに含める

<div ng-app="myApp">
<div ng-controller="MyCtrl">
<form name="form">
    <input name="requiredField" ng-model="model.requiredField" required/> (Required, but no other validators)
    <p ng-show="form.requiredField.$errror.required">Field is required</p>
    <button ng-click="reset()">Reset form</button>
</form>
<p>Pristine: {{form.$pristine}}</p>
</div>
</dvi>
于 2013-04-30T09:50:36.473 に答える
7

編集...それは適切ではなかったので、私は私の古い答えを削除しています。

私は実際に自分でこの問題に遭遇しました。これが私の解決策でした。Angularの拡張メソッドを作成しました。$scope.form。$setValidity()が(逆に)行っていたことを少しフォローすることでこれを行いました...

これが実際のplnkrデモです

これが私が作ったヘルパーメソッドです。これはハックですが、機能します。

angular.resetForm = function (scope, formName, defaults) {
    $('form[name=' + formName + '], form[name=' + formName + '] .ng-dirty').removeClass('ng-dirty').addClass('ng-pristine');
    var form = scope[formName];
    form.$dirty = false;
    form.$pristine = true;
    for(var field in form) {
      if(form[field].$pristine === false) {
        form[field].$pristine = true;
      }
      if(form[field].$dirty === true) {
        form[field].$dirty = false;
      }
    }
    for(var d in defaults) {
      scope[d] = defaults[d];
    }
};

うまくいけば、これは誰かに役立つでしょう。

于 2012-09-26T21:34:05.530 に答える
4

フォームフィールドは、$scope内の変数にリンクする必要があります。変数をリセットすることでフォームをリセットできます。おそらく$scope.formのような単一のオブジェクトである必要があります。

ユーザー向けのシンプルなフォームがあるとします。

app.controller('Ctrl', function Ctrl($scope){
  var defaultForm = {
    first_name : "",
    last_name : "",
    address: "",
    email: ""
  };
  $scope.resetForm = function(){
    $scope.form = defaultForm;
  };
});

これは、HTMLが次のようになっている限りうまく機能します。

<form>
  <input ng-model="form.first_name"/>
  <input ng-model="form.last_name"/>
  <input ng-model="form.address"/>
  <input ng-model="form.email"/>
  <button ng-click="resetForm()">Reset Form</button>
</form>

たぶん私はここで問題を理解していないので、これがあなたの質問に対処しない場合、あなたはその理由を正確に説明できますか?

于 2012-09-26T19:22:02.520 に答える
2

ここで、fromを元の状態にするための解決策を見つけました。

var def = {
    name: '',
    password: '',
    email: '',
    mobile: ''
};

$scope.submited = false;

$scope.regd = function (user) {
    if ($scope.user.$valid) {
        $http.post('saveUser', user).success(function (d) {
            angular.extend($scope.user, def);
            $scope.user.$setPristine(true);
            $scope.user.submited = false;
        }).error(function (e) {});
    } else {
        $scope.user.submited = true;
    }
};

angle.extends(src、dst)と書くだけで、元のオブジェクトが空白のオブジェクトを拡張するだけで、空白として表示され、残りはすべてデフォルトになります。

于 2014-01-11T11:28:10.603 に答える
1

外部ディレクティブと多くのjqueryを使用する

app.controller('a', function($scope) {
    $scope.caca = function() {
        $scope.$emit('resetForm');
    }
});

app.directive('form', function() {
    return {
        restrict: 'E',
        link: function(scope, iElem) {
            scope.$on('resetForm', function() {
                iElem.find('[ng-model]').andSelf().add('[ng-form]').each(function(i, elem) {
                    var target = $(elem).addClass('ng-pristine').removeClass('ng-dirty');
                    var control = target.controller('ngModel') || target.controller('form');
                    control.$pristine = true;
                    control.$dirty = false;
                });
            });
        }
    };
});

http://jsfiddle.net/pPbzz/2/

于 2014-03-31T19:48:04.780 に答える
0

簡単な方法:フォームをコントローラー関数に渡すだけです。フォームの下にある「myForm」はこれによって参照されます。これは$scopeと同等です。

<div ng-controller="MyController as mc">
    <ng-form name="myform">
        <input ng-model="mc.myFormValues.name" type="text" required>
        <button ng-click="mc.doSometing(this.myform)" type="submit" 
                ng-disabled="myform.$invalid||myform.$pristine">Do It!</button>
    </ng-form>
</div>

コントローラー:

function MyController(MyService) {
    var self = this;
    self.myFormValues = {
        name: 'Chris'
    };
    self.doSomething = function (form) {
        var aform = form;
        MyService.saveSomething(self.myFromValues)
            .then(function (result) {
                ...
                aform.$setPristine();
            }).catch(function (e) {
                ...
            aform.$setDirty();
        })
    }
}
于 2016-05-14T16:12:55.200 に答える