Cách kích hoạt Trình xác thực biểu mẫu trong Angular2


82

Trong angle2, tôi muốn kích hoạt Trình xác thực cho một số điều khiển khi một điều khiển khác được thay đổi. Có cách nào để tôi có thể yêu cầu biểu mẫu xác thực lại không? Vẫn tốt hơn, tôi có thể yêu cầu xác thực các trường cụ thể không?

Ví dụ: Cho Hộp kiểm X và đầu vào P. Đầu vào P có trình xác thực hoạt động khác nhau dựa trên giá trị mô hình của X. Khi X được chọn / bỏ chọn, tôi cần gọi trình xác thực trên P. Trình xác thực trên P sẽ xem xét mô hình để xác định trạng thái của X và sẽ xác nhận P tương ứng.

Đây là một số mã:

constructor(builder: FormBuilder) {
    this.formData = { num: '', checkbox: false };

    this.formGp = builder.group({
        numberFld: [this.formData.num, myValidators.numericRange],
        checkboxFld: [this.formData.checkbox],
    });
}

this.formGp.controls['checkboxFld'].valueChanges.observer({
    next: (value) => {
        // I want to be able to do something like the following line:
        this.formGp.controls['numberFld'].validator(this.formGp.controls['numberFld']);
    }
});

Bất kỳ ai có một giải pháp? Cảm ơn!


Bạn chỉ đang cố gắng bật / tắt xác thực dựa trên giá trị của X? Bạn đang sử dụng loại trình xác thực nào? Bạn có thể khiến trình xác thực thực thi dựa trên một điều kiện trong phạm vi của bạn, nhưng tôi không chắc liệu cách tiếp cận đó có hiệu quả với bạn hay không. Xem: stackoverflow.com/questions/21370006/…
stephen.vakil,

@ stephen.vakil - Tôi đang sử dụng angle2.
Bonneville

@Bonneville, bạn có thể vui lòng giải thích cách bạn đang chuyển trạng thái hộp kiểm sang chức năng xác thực không?
Varun Mulloli

Câu trả lời:


79

Tôi không biết nếu bạn vẫn đang tìm kiếm câu trả lời, vì vậy đây là gợi ý của tôi:

Hãy xem cái này: Angular 2 - AbstractControl

Tôi nghĩ những gì bạn có thể làm là sau:

this.formGp.controls['checkboxFld'].valueChanges.observer({
    next: (value) => {
       this.formGp.controls['numberFld'].updateValueAndValidity();
    }
});

Điều này sẽ kích hoạt và chạy trình xác thực. Hơn nữa, trạng thái cũng được cập nhật. Bây giờ bạn sẽ có thể tham khảo giá trị hộp kiểm trong logic trình xác thực của mình.

Hi vọng điêu nay co ich!

CHỈNH SỬA: Liên kết cập nhật và ví dụ. Mã đã thay đổi trong khi tôi đang viết câu trả lời của mình.

EDIT_2: alpha.48 thay đổi EventEmitter.observer thành EventEmitter.subscribe!

EDIT_3: Đã thay đổi liên kết thành triển khai thực tế, thêm liên kết vào tài liệu

Validaton-Hướng dẫn

Tài liệu FormControl


Cảm ơn @Nightking về đề xuất, tôi sẽ dùng thử. Lưu ý rằng liên kết của bạn không hoạt động.
Bonneville

@Bonneville Cảm ơn vì thông tin. Họ trích xuất mã biểu mẫu vào không gian tên chung. Mọi thứ thay đổi một chút thành nhanh :). Tôi đã cập nhật liên kết đến nguồn.
Đi đêm

Cuối cùng tôi đã sử dụng đoạn mã này và nó có vẻ hiệu quả với tôi. Cảm ơn! BTW, có lỗi đánh máy trong mã của bạn: thiếu chữ 'e' trong hàm updateValueAndValidity (). Mã của bạn có cập nhật thay vì cập nhật. Chúc mừng, đây là một trợ giúp lớn!
Bonneville

1
Liên kết bị hỏng; có thể được cập nhật thành github.com/angular/angular/blob/master/packages/forms/src/… mặc dù không hoàn toàn giống nhau. Cũng có thể liên kết đến tài liệu Angular
Thuốc nổ

1
Cứu mạng !! Trường hợp sử dụng mà tôi gặp khó khăn là khi người dùng gửi biểu mẫu mà không chạm vào điều khiển biểu mẫu duy nhất. Các hình thức không hợp lệ nhưng các điều khiển mà không hiển thị bất kỳ thông báo lỗi
Pravin

42

với ControlGroup của tôi, tôi làm điều này vì tôi có lỗi kiểm tra divs nếu được chạm vào

for (var i in this.form.controls) {
  this.form.controls[i].markAsTouched();
}

(this.form là ControlGroup của tôi)


đây thực sự là câu trả lời đúng. Nếu bạn muốn nhập một lần this.form.controls ['name']. MarkAsTouched ();
chris_r

19

Với sự giúp đỡ của blog này

liên kết blog

Tôi đã tìm ra một giải pháp với sự kết hợp của câu trả lời Nightking

Object.keys(this.orderForm.controls).forEach(field => {
       const control = this.orderForm.get(field);
       control.updateValueAndValidity();

});

this.orderForm là nhóm biểu mẫu


8

Điều này đã làm nên mẹo cho tôi

this.myForm.markAllAsTouched();

6

Có nhiều cách đơn giản hơn để mô hình hóa hành vi này - ví dụ: đặt trạng thái của bạn vào một ReplaySubject và quan sát điều đó, sau đó sử dụng trình xác thực không đồng bộ quan sát trạng thái - nhưng phương pháp mã giả bên dưới sẽ hoạt động. Bạn chỉ cần quan sát các thay đổi giá trị trong hộp kiểm, cập nhật mô hình nếu thích hợp, sau đó buộc xác thực lại numberFld bằng cal updateValueAndValidity.

constructor(builder: FormBuilder) {
  this.formData = { num: '', checkbox: false };
  const numberFld = builder.control(this.formData.num, myValidators.numericRange);

  const checkbox = builder.control(this.formData.checkbox);
  checkbox.valueChanges.map(mapToBoolean).subscribe((bool) => {
    this.formData.checked = bool;
    numberFld.updateValueAndValidity(); //triggers numberFld validation
  });

  this.formGp = builder.group({
      numberFld: numberFld,
      checkboxFld: checkbox
  });
}

0
static minMaxRange(min: number, max: number): ValidatorFn {
    return (control: AbstractControl): ValidationErrors | null => {
        if (Validators.min(min)(control)) { // if min not valid
            return Validators.min(min)(control);
        } else {
            return Validators.max(max)(control);
        }
    };
}
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.