Angular.js lập trình đặt trường biểu mẫu thành bẩn


105

Tôi đang cập nhật theo chương trình một số trường trên biểu mẫu của mình với một giá trị và tôi muốn đặt trạng thái trường thành $dirty. Làm điều gì đó như:

$scope.myForm.username.$dirty = true; dường như không hoạt động.

Có một phương pháp $setPristinemà tôi có thể sử dụng để đặt lại trạng thái của trường nhưng không có $setDirtyphương pháp nào?

Vì vậy, làm thế nào để làm điều này?

Tôi đã thấy bài đăng này https://groups.google.com/forum/#!topic/angular/NQKGAFlsln4 nhưng dường như tôi không thể tìm thấy $setDirtyphương pháp. Tôi đang sử dụng phiên bản Angular 1.1.5.


có thể bạn chỉ cần đặt một số giá trị (mặc định)?
Cherniv

3
Phương pháp $ setDirty được ghi lại ở đây: docs.angularjs.org/api/ng.directive:form.FormController
David Lin

2
Có vẻ là ở mức độ hình thức. Tôi cần một $setDirtycấp độ trường.
super9

đang tiếp tục ở đây, nhưng một giải pháp có thể, nhưng đúng hơn là khó khăn, cho điều này là tìm ra góc của trình xử lý sự kiện nào sử dụng để liên kết với loại trường đó và kích hoạt trình nghe đó theo cách thủ công ngay sau khi cập nhật. </uglyHack>
bguiz

Tôi đã nghĩ đến việc thay đổi theo chương trình lớp nhưng nó sẽ không thay đổi trạng thái của các trường mẫu theo cách đúng tôi sẽ phải suy nghĩ ...
super9

Câu trả lời:


51

Kể từ AngularJS 1.3.4, bạn có thể sử dụng $setDirty()trên các trường ( nguồn ). Ví dụ: đối với mỗi trường có lỗi và được đánh dấu là bắt buộc, bạn có thể thực hiện như sau:

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

87

Trong trường hợp của bạn, $scope.myForm.username.$setViewValue($scope.myForm.username.$viewValue); có phải là mẹo - nó làm cho cả biểu mẫu và trường trở nên bẩn thỉu, đồng thời gắn thêm các lớp CSS thích hợp.

Thành thật mà nói, tôi đã tìm thấy giải pháp này trong bài đăng mới trong chủ đề từ liên kết từ câu hỏi của bạn. Nó hoạt động hoàn hảo đối với tôi, vì vậy tôi đặt câu trả lời này ở đây như một câu trả lời độc lập để giúp tìm thấy nó dễ dàng hơn.

BIÊN TẬP:

Giải pháp trên hoạt động tốt nhất cho phiên bản Angular lên đến 1.3.3. Bắt đầu với 1.3.4, bạn nên sử dụng phương pháp API mới được tiếp xúc $setDirty()từ ngModel.NgModelController.


Điều này dường như thay đổi đối với tôi giữa Angular 1.3.0-beta5 và 1.3.0, trong đó 1.3.0 giữ nguyên trường $ miễn là $ viewValue không thay đổi. Tôi đã phải làm $scope.myForm.myField.$pristine = false; $scope.myForm.myField.$setViewValue(...). Trông giống như câu trả lời dưới đây nói rằng field.$setDirty()đã được bổ sung trong góc 1.3.4 sẽ là giải pháp tốt hơn
Johann

4
Cảm ơn bạn đã lưu tâm bạn đã lưu trong ngày của tôi "lên đến 1.3.3 Bắt đầu với 1.3.4 bạn nên sử dụng mới được tiếp xúc với phương pháp API."
Ahmed Mahmoud

người dùng rmag, còn góc 2 thì sao?
user5260143

17

bạn sẽ phải thiết lập thủ công $dirtyđến true$pristineđến falsetrường. Nếu bạn muốn các lớp xuất hiện trên đầu vào của mình, thì bạn sẽ phải thêm ng-dirtyvà xóa ng-pristinecác lớp khỏi phần tử theo cách thủ công . Bạn có thể sử dụng $setDirty()ở cấp biểu mẫu để thực hiện tất cả điều này trên chính biểu mẫu, nhưng không phải các đầu vào biểu mẫu, đầu vào biểu mẫu hiện không có $setDirty()như bạn đã đề cập.

Câu trả lời này có thể thay đổi trong tương lai vì chúng sẽ thêm $setDirty()vào đầu vào, có vẻ hợp lý.


3
$ setPristine () ở cấp đầu vào trường nhưng vẫn không có $ setDirty trong 1.2.26 :-(
Sebastian

10

Nếu bạn có quyền truy cập vào NgModelController (bạn chỉ có thể truy cập vào nó từ một chỉ thị) thì bạn có thể gọi

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

Cảm ơn bạn! Chính xác những gì tôi đang tìm kiếm.
dreyln

10

Tạo một jsFiddle dành riêng cho bạn để giải quyết vấn đề này. chỉ cần đặt $ dirty thành true, nhưng với $timeout 0điều đó, nó sẽ chạy sau khi DOM được tải.

Tìm nó ở đây: JsFiddle

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

6

Đây là những gì làm việc cho tôi

$scope.form_name.field_name.$setDirty()


5

Chức năng trợ giúp để thực hiện công việc:

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

Này, tôi không may đã vô tình phản đối cái này. Làm cách nào để hoàn nguyên nó. Vì vậy, nói với tôi rằng tôi không thể làm điều này mà không có câu trả lời được chỉnh sửa ..
smk

Điều này hoạt động tốt; ủng hộ khi kiểm tra 'biểu mẫu. $ error' đảm bảo chúng tôi không phải là trường 'phân tích' mà người dùng không chạm vào, nhưng là trường hợp lệ.
Sam T

Cảm ơn bạn! Giải pháp dễ dàng và đơn giản. Có thể không phải là nhanh nhất nhưng nó không làm bất cứ điều gì nặng nề nên nó thực sự không quan trọng với imo. Làm tốt lắm!
jwanglof

4

Góc 2

Đối với bất kỳ ai muốn làm điều tương tự trong Angular 2, nó rất giống nhau ngoài việc nắm giữ biểu mẫu

<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

Ghi chú nhỏ bổ sung cho câu trả lời của @ rmag. Nếu bạn có các trường trống nhưng bắt buộc mà bạn muốn sử dụng sai mục đích này:

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

Đây là câu trả lời cuối cùng đã giúp tôi!
Kirk Liemohn

-1

Tôi không chắc chính xác lý do tại sao bạn đang cố gắng đánh dấu các trường là bẩn, nhưng tôi thấy mình đang ở trong tình huống tương tự vì tôi muốn lỗi xác thực hiển thị khi ai đó cố gắng gửi biểu mẫu không hợp lệ. Tôi đã kết thúc bằng cách sử dụng jQuery để xóa các .ng-pristinethẻ lớp và thêm .ng-dirtythẻ lớp vào các trường thích hợp. Ví dụ:

$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
Cho rằng chúng tôi đã sử dụng AngularJS, một giải pháp jQuery có vẻ quá mức cần thiết. Ví dụ, nhiều người không muốn sử dụng jQuery với AngularJS.
StevenClontz
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.