【问题标题】:Angular.js programmatically setting a form field to dirtyAngular.js 以编程方式将表单字段设置为脏
【发布时间】:2013-08-06 04:07:55
【问题描述】:

我正在使用值以编程方式更新表单上的某些字段,并且我想将字段状态设置为$dirty。做类似的事情:

$scope.myForm.username.$dirty = true; 似乎不起作用。

有一种方法$setPristine 可以用来重置字段的状态,但没有$setDirty 方法?

那么如何做到这一点呢?

我看到了这个帖子https://groups.google.com/forum/#!topic/angular/NQKGAFlsln4,但我似乎找不到$setDirty 方法。我使用的是 Angular 1.1.5 版。

【问题讨论】:

  • 也许你只需要设置一些(默认)值?
  • 这里记录了 $setDirty 方法:docs.angularjs.org/api/ng.directive:form.FormController
  • 这似乎是在表单级别。我需要一个字段级别的$setDirty
  • 在这里有点困难,但一种可能但相当老套的解决方案是找出事件侦听器角度用于绑定到该类型的字段,并在之后立即手动触发该侦听器更新。
  • 我正在考虑以编程方式更改类,但它不会以我认为的正确方式更改表单字段的状态...

标签: angularjs


【解决方案1】:

您可以使用$setDirty(); 方法。见文档https://docs.angularjs.org/api/ng/type/form.FormController

例子:

$scope.myForm.$setDirty();

【讨论】:

    【解决方案2】:

    这对我有用

    $scope.form_name.field_name.$setDirty()
    

    【讨论】:

      【解决方案3】:

      为您制作了一个解决此问题的 jsFiddle。只需将 $dirty 设置为 true,但使用 $timeout 0,以便在加载 DOM 后运行。

      在这里找到它:JsFiddle

      $timeout(function () {
        $scope.form.uName.$dirty = true;
      }, 0);
      

      【讨论】:

        【解决方案4】:

        在您的情况下,$scope.myForm.username.$setViewValue($scope.myForm.username.$viewValue); 可以解决问题 - 它使表单和字段都变脏,并附加适当的 CSS 类。

        老实说,我从您问题的链接中的主题的新帖子中找到了这个解决方案。它对我来说非常有效,所以我把它作为一个独立的答案放在这里,以便更容易找到。

        编辑:

        上述解决方案最适合 Angular 1.3.3 及以下版本。从 1.3.4 开始,您应该使用来自 ngModel.NgModelController 的新公开的 API 方法 $setDirty()

        【讨论】:

        • 这对我来说似乎在 Angular 1.3.0-beta5 和 1.3.0 之间发生了变化,只要 $viewValue 没有改变,1.3.0 就会保持字段 $pristine。我不得不做$scope.myForm.myField.$pristine = false; $scope.myForm.myField.$setViewValue(...)。看起来下面的答案表明在 Angular 1.3.4 中添加了field.$setDirty() 将是更好的解决方案
        • 感谢您在 1.3.3 之前为我节省了一天的时间。从 1.3.4 开始,您应该使用新公开的 API 方法“
        • 用户 rmag,那么 angular 2 呢?
        【解决方案5】:

        从 AngularJS 1.3.4 开始,您可以在字段 (source) 上使用 $setDirty()。例如,对于每个有错误并标记为必填项的字段,您可以执行以下操作:

        angular.forEach($scope.form.$error.required, function(field) {
            field.$setDirty();
        });
        

        【讨论】:

          【解决方案6】:

          一个辅助函数来完成这项工作:

          function setDirtyForm(form) {
              angular.forEach(form.$error, function(type) {
                  angular.forEach(type, function(field) {
                      field.$setDirty();
                  });
              });
              return form;
          }
          

          【讨论】:

          • 嘿,不幸的是,我不小心对此投了反对票。我该如何恢复它。所以告诉我,如果不编辑答案,我就无法做到这一点..
          • 这很好用;赞成检查“form.$error”可确保我们不会“污染”用户未触及但有效的字段。
          • 谢谢!简单而简单的解决方案。可能不是最快的,但它不会做任何繁重的事情,所以在我看来真的没关系。干得好!
          【解决方案7】:

          您必须手动将字段的$dirty 设置为true$pristinefalse。如果您希望类出现在您的输入中,那么您必须手动添加 ng-dirty 并从元素中删除 ng-pristine 类。您可以在表单级别使用$setDirty() 在表单本身上执行所有这些操作,但不能在表单输入上执行所有这些操作,因为您提到的表单输入当前没有$setDirty()

          这个答案将来可能会改变,因为他们应该在输入中添加$setDirty(),这似乎是合乎逻辑的。

          【讨论】:

          • $setPristine() 处于输入字段级别,但在 1.2.26 中仍然没有 $setDirty :-(
          【解决方案8】:

          如果您可以访问NgModelController(您只能通过指令访问它),那么您可以调用

          ngModel.$setViewValue("your new view value");
          // or to keep the view value the same and just change it to dirty
          ngModel.$setViewValue(ngModel.$viewValue);
          

          【讨论】:

          • 谢谢!正是我想要的。
          【解决方案9】:

          Angular 2

          对于任何希望在 Angular 2 中做同样事情的人来说,除了获取表单之外,它非常相似

          <form role="form" [ngFormModel]="myFormModel" (ngSubmit)="onSubmit()" #myForm="ngForm">
          <div class="form-group">
              <label for="name">Name</label>
              <input autofocus type="text" ngControl="usename" #name="ngForm" class="form-control" id="name" placeholder="Name">
              <div [hidden]="name.valid || name.pristine" class="alert alert-danger">
                  Name is required
              </div>
          </div>
          </form>
          <button type="submit" class="btn btn-primary" (click)="myForm.ngSubmit.emit()">Add</button>
          

          import { Component, } from '@angular/core';
          import { FormBuilder, Validators } from '@angular/common';
          
          @Component({
              selector: 'my-example-form',
              templateUrl: 'app/my-example-form.component.html',
              directives: []
          })
          export class MyFormComponent {
              myFormModel: any;
          
              constructor(private _formBuilder: FormBuilder) {
                  this.myFormModel = this._formBuilder.group({
                      'username': ['', Validators.required],
                      'password': ['', Validators.required]
                  });
              }
          
              onSubmit() {
                  this.myFormModel.markAsDirty();
                  for (let control in this.myFormModel.controls) {
                      this.myFormModel.controls[control].markAsDirty();
                  };
          
                  if (this.myFormModel.dirty && this.myFormModel.valid) {
                      // My submit logic
                  }
              }
          }
          

          【讨论】:

            【解决方案10】:

            对@rmag 的回答的补充说明。如果您有空但必填的字段,您想弄脏,请使用:

            $scope.myForm.username.$setViewValue($scope.myForm.username.$viewValue !== undefined 
                ? $scope.myForm.username.$viewValue : '');
            

            【讨论】:

            • 这是最终帮助我的答案!
            【解决方案11】:

            我不确定您为什么要尝试将字段标记为脏,但我发现自己处于类似情况,因为我希望在有人尝试提交无效表单时显示验证错误。我最终使用 jQuery 删除了 .ng-pristine 类标签并将 .ng-dirty 类标签添加到相应的字段中。例如:

            $scope.submit = function() {
                // `formName` is the value of the `name` attribute on your `form` tag
                if (this.formName.$invalid)
                {
                    $('.ng-invalid:not("form")').each(function() {
                        $(this).removeClass('ng-pristine').addClass('ng-dirty');
                    });
                    // the form element itself is index zero, so the first input is typically at index 1
                    $('.ng-invalid')[1].focus();
                }
            }
            

            【讨论】:

            • 鉴于我们已经在使用 AngularJS,jQuery 解决方案似乎有点过头了。例如,许多人不喜欢将 jQuery 与 AngularJS 一起使用。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-08-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多