将表单字段重置为原始状态(重置脏状态)的功能位于 AngularJS 1.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:

Controller 应该只用于业务逻辑,而不是用于 DOM!

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

在我的 Controller resetForm() 上:
  • 保存原封不动的 HTML
  • 重新编译保存的原始HTML
  • 从 DOM 中移除当前表单
  • 将新编译的模板插入DOM

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

    最佳答案

    没有解决方法的解决方案

    我想出了一个使用 AngularJS 的解决方案,没有任何解决方法。这里的技巧是使用 AngularJS 的能力来拥有多个同名的指令。

    正如其他人提到的,实际上有一个拉取请求( https://github.com/angular/angular.js/pull/1127 )进入了 AngularJS 1.1.x 分支,允许重置表单。对这个拉取请求的提交改变了 ngModel 和 form/ngForm 指令(我本来想添加一个链接,但 Stackoverflow 不希望我添加两个以上的链接)。

    我们现在可以定义我们自己的 ngModel 和 form/ngForm 指令,并使用拉取请求中提供的功能扩展它们。

    我将这些指令包装在一个名为 resettableForm 的 AngularJS 模块中。您所要做的就是将此模块包含到您的项目中,并且您的 AngularJS 1.0.x 版在这方面就像是 Angular 1.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 步:在 Controller 上提供一个方法来重置模型

    请注意,您必须在重置表单时重置模型。在您的 Controller 中,您可以编写:
    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>
    

    关于angularjs - 将表单重置为原始状态 (AngularJS 1.0.x),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12603914/

    10-16 00:13