Angular.js програмно встановлює брутне поле форми


105

Я програмно оновлюю деякі поля моєї форми зі значенням, і я хотів би встановити стан поля $dirty. Робити щось на кшталт:

$scope.myForm.username.$dirty = true; Схоже, не працює.

Є метод, $setPristineякий я можу використовувати для скидання стану поля, але немає $setDirtyметоду?

То як же це робити?

Я побачив цю публікацію https://groups.google.com/forum/#!topic/angular/NQKGAFlsln4, але я не можу знайти $setDirtyспосіб. Я використовую кутову версію 1.1.5.


може вам просто потрібно встановити якесь значення (за замовчуванням)?
Чернів

3
Метод $ setDirty задокументований тут: docs.angularjs.org/api/ng.directive:form.FormController
Девід Лін

2
Схоже, це на рівні форми. Мені потрібен $setDirtyпольовий рівень.
супер9

тут йдеться про кінцівку, але одне з можливих, але досить хакітних варіантів вирішення цього питання - це з’ясувати, який користувач слухача подій використовує для прив’язки до цього типу поля, і запустити цього слухача вручну відразу після оновлення. </uglyHack>
bguiz

Я думав про те, щоб програмно змінити клас, але це не змінить стан поля форми правильним чином, я б подумав ...
super9

Відповіді:


51

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

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

87

У вашому випадку $scope.myForm.username.$setViewValue($scope.myForm.username.$viewValue);робить фокус - він робить і форму, і поле брудним, і додає відповідні класи CSS.

Якщо чесно кажучи, я знайшов це рішення в новій публікації в темі за посиланням з вашого питання. Це прекрасно працювало для мене, тому я викладаю це тут як окрему відповідь, щоб полегшити його пошук.

Редагувати:

Вищевказане рішення найкраще працює для кутової версії до 1.3.3. Починаючи з 1.3.4, ви повинні використовувати недавно відкритий метод API $setDirty()від ngModel.NgModelController.


Це, здавалося, змінилося між кутовими 1.3.0-beta5 та 1.3.0, де 1.3.0 зберігає поле $ незайманим до тих пір, поки $ viewValue не змінився. Мені довелося це робити $scope.myForm.myField.$pristine = false; $scope.myForm.myField.$setViewValue(...). Схоже, відповідь нижче, в якій сказано, що field.$setDirty()доданий у кутовий 1.3.4 буде кращим рішенням
Йоганн

4
Дякуємо за вашу замітку, що ви зберегли мій день "до 1.3.3. Починаючи з 1.3.4, ви повинні використовувати метод, що відкрився API,"
Ахмед Махмуд

користувач rmag, а як щодо кутового 2?
користувач5260143

17

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

Ця відповідь може змінитися в майбутньому, оскільки їх слід додати $setDirty()до вхідних даних, здається логічним.


3
$ setPristine () знаходиться на рівні вхідного поля, але все ще немає $ setДіти в 1.2.26 :-(
Себастьян

10

Якщо у вас є доступ до 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);

Дякую! Саме те, що я шукав.
dreyln

10

Створив jsFiddle саме для вас, який вирішує це питання. просто встановіть $ dirty на істинне, але з таким $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

Це добре працює; звернення як перевірка на "форму. $ помилка" гарантує, що ми не є "брудними" полями, до яких користувач не торкався, але які є дійсними.
Сем Т

Дякую! Легке та просте рішення. Може бути не найшвидшим, але це не робить нічого важкого, так що насправді це не має значення. Гарна робота!
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 : '');

Це відповідь, яка нарешті мені допомогла!
Кірк Лімохн

-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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.