Angular.js программно устанавливает поле формы в грязный

Я программно обновляю некоторые поля в моей форме значением, и я хотел бы установить состояние поля в $dirty, Делать что-то вроде:

$scope.myForm.username.$dirty = true; не похоже на работу.

Есть метод $setPristine что я могу использовать для сброса состояния поля, но нет $setDirty метод?

Так как же это сделать?

Я видел этот пост https://groups.google.com/forum/, но не могу найти $setDirty метод. Я использую Angular версии 1.1.5.

11 ответов

Решение

Начиная с AngularJS 1.3.4 вы можете использовать $setDirty() на полях ( источник). Например, для каждого поля с ошибкой и пометкой "обязательный" вы можете сделать следующее:

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

В твоем случае, $scope.myForm.username.$setViewValue($scope.myForm.username.$viewValue); делает трюк - это делает форму и поле грязными, и добавляет соответствующие классы CSS.

Просто если честно, я нашел это решение в новом посте в теме по ссылке из вашего вопроса. Это отлично сработало для меня, поэтому я привожу это здесь как отдельный ответ, чтобы его было легче найти.

РЕДАКТИРОВАТЬ:

Вышеупомянутое решение лучше всего работает для угловой версии до 1.3.3. Начиная с 1.3.4, вы должны использовать новый метод API $setDirty() от ngModel.NgModelController,

Вам придется вручную установить $dirty в true а также $pristine в false для поля. Если вы хотите, чтобы классы появлялись на вашем входе, то вам придется добавить вручную ng-dirty и удалить ng-pristine классы от элемента. Ты можешь использовать $setDirty() на уровне формы, чтобы сделать все это на самой форме, но не на входах формы, входные данные формы в настоящее время не имеют $setDirty() как вы упомянули.

Этот ответ может измениться в будущем, поскольку они должны добавить $setDirty() на входы, кажется логичным.

Если у вас есть доступ к 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);

Сделал jsFiddle только для вас, чтобы решить эту проблему. просто установите $dirty на true, но с $timeout 0 поэтому он запускается после загрузки DOM.

Найдите это здесь: JsFiddle

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

Ты можешь использовать $setDirty(); метод. См документацию https://docs.angularjs.org/api/ng/type/form.FormController

Пример:

$scope.myForm.$setDirty();

Это то, что сработало для меня

$scope.form_name.field_name.$setDirty()

Вспомогательная функция для выполнения работы:

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

Угловой 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
        }
    }
}

Небольшая дополнительная заметка к ответу @rmag. Если у вас есть пустые, но обязательные поля, которые вы хотите испачкать, используйте это:

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

Я не совсем уверен, почему вы пытаетесь пометить поля как грязные, но я оказался в подобной ситуации, потому что хотел, чтобы ошибки проверки появлялись, когда кто-то пытался отправить неверную форму. В итоге я использовал 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();
    }
}
Другие вопросы по тегам