Angular.js以编程方式将表单字段设置为dirty


105

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

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

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

那么如何去做呢?

我看到了这篇文章https://groups.google.com/forum/#!topic/angular/NQKGAFlsln4,但我似乎找不到该$setDirty方法。我正在使用Angular 1.1.5版本。


可能只是您需要设置一些(默认)值?
2013年

3
$ setDirty方法记录在这里:docs.angularjs.org/api/ng.directive
David Lin

2
似乎是在窗体级别。我需要一个$setDirty现场水平。
super9

要解决这个问题,但可能的办法是,但很棘手的解决方案是找出事件侦听器angular用来绑定到该类型的字段,并在更新后立即手动触发该侦听器。</ uglyHack>
bguiz

我正在考虑以编程方式更改类,但是它不会以我
原本

Answers:


51

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

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

87

在您的情况下,可以$scope.myForm.username.$setViewValue($scope.myForm.username.$viewValue);做到这一点-会使表单和字段变脏,并附加适当的CSS类。

老实说,我在您问题的链接的主题的新文章中找到了此解决方案。它对我来说效果很好,因此我将其作为一个独立的答案放在此处,以使其更容易找到。

编辑:

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


这对我来说似乎在Angular 1.3.0-beta5和1.3.0之间发生了变化,只要$ viewValue不变,那么1.3.0会将字段$ pristine保留为$ pristine。我不得不做$scope.myForm.myField.$pristine = false; $scope.myForm.myField.$setViewValue(...)。看起来下面的答案说明field.$setDirty()了在Angular 1.3.4中添加的答案将是更好的解决方案
Johann 2015年

4
感谢您的来信,您保存了我的一天“直到1.3.3。从1.3.4开始,您应该使用新暴露的API方法”
Ahmed Mahmoud

用户rmag,角度2呢?
user5260143 '16

17

你将不得不手动设置$dirtytrue$pristinefalse田间。如果希望类显示在输入中,则必须手动从元素中添加ng-dirty和删除ng-pristine类。您可以$setDirty()在表单级别上使用它来对表单本身进行所有操作,但是不能对表单输入进行操作,因为表单输入当前没有$setDirty()您所提到的。

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


3
$ setPristine()在输入字段级别,但在1.2.26中仍然没有$ setDirty :-(
Sebastian


10

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

在这里找到它:JsFiddle

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



5

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

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

嘿,不幸的是我无意中对此表示反对。我该如何还原它。所以告诉我,如果不编辑答案,我将无法做到这一点
。– smk

这很好用;赞成检查“ form。$ error”,以确保我们不会“脏化”用户没有触摸但有效的字段。
山姆T

谢谢!简单的解决方案。可能不是最快的,但它并不会做任何繁重的工作,因此imo真的无关紧要。干得好!
jwanglof

4

角度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
        }
    }
}

3

@rmag的答案的小注释。如果要清空但有空但必填的字段,请使用以下命令:

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

这是最终帮助我的答案!
Kirk Liemohn '16

-1

我不确定您为什么要尝试将字段标记为肮脏,但是我发现自己处于类似情况,因为当有人尝试提交无效表单时,我希望显示验证错误。我最终使用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();
    }
}

5
鉴于我们已经在使用AngularJS,jQuery解决方案似乎有些过时了。例如,许多人喜欢不将jQuery与AngularJS一起使用。
StevenClontz 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.