Biểu mẫu phản ứng - thuộc tính bị vô hiệu hóa


97

Tôi đang cố gắng sử dụng disabledthuộc tính từ a formControl. Khi tôi đặt nó vào mẫu, nó hoạt động:

<md-input formControlName="id" placeholder="ID" [disabled]="true"></md-input>

Nhưng trình duyệt cảnh báo tôi:

Có vẻ như bạn đang sử dụng thuộc tính bị vô hiệu hóa với chỉ thị biểu mẫu phản ứng. Nếu bạn đặt bị vô hiệu hóa thành true khi thiết lập điều khiển này trong lớp thành phần của mình, thì thuộc tính bị vô hiệu hóa sẽ thực sự được đặt trong DOM cho bạn. Chúng tôi khuyên bạn nên sử dụng phương pháp này để tránh lỗi 'đã thay đổi sau khi đã kiểm tra'.

  Example: 
  form = new FormGroup({
    first: new FormControl({value: 'Nancy', disabled: true}, Validators.required),
    last: new FormControl('Drew', Validators.required)
  });

Vì vậy, tôi đặt nó vào FormControlvà xóa khỏi mẫu:

constructor(private itemsService: ItemsService) {
    this._items = [];
    this.myForm = new FormGroup({
        id: new FormControl({value: '', disabled: true}, Validators.required),
        title: new FormControl(),
        description: new FormControl()
    });
    this.id = this.myForm.controls['id'];
    this.title = this.myForm.controls['title'];
    this.description = this.myForm.controls['description'];
    this.id.patchValue(this._items.length);
}

Nhưng nó không hoạt động (nó không vô hiệu hóa input). Vấn đề là gì?


1
Điều này dường như chỉ làm việc tốt với các phiên bản hiện tại của Angular 2: plnkr.co/edit/CQQtkYC9D5EoH0sAlNCV?p=preview
silentsod

Tôi đang sử dụng dự án cli góc cạnh nhất để thử nghiệm
FacundoGFlores

2
Bạn đang sử dụng @ angle / material, do đó, theo sự cố github của họ: github.com/angular/material2/issues/1171 Nó chưa được hỗ trợ và chúng đang ở giai đoạn alpha nên bạn không thể mong đợi nó có tính năng hoàn chỉnh.
silentsod

Vâng, đó là vấn đề
FacundoGFlores

6
Bạn có thể thử đặt this.myForm.controls['id'].disable()ở đâu đó trong hàm tạo. Tôi đã tạo một thư viện giúp làm việc với các biểu mẫu động dễ dàng hơn: github.com/mat3e/dorf
mat3e

Câu trả lời:


116

Tôi đã và đang sử dụng [attr.disabled]vì tôi vẫn thích mẫu này được điều khiển hơn là enable () / disable () có lập trình vì nó là IMO vượt trội.

Thay đổi

<md-input formControlName="id" placeholder="ID" [disabled]="true"></md-input>

đến

<md-input formControlName="id" placeholder="ID" [attr.disabled]="true"></md-input>

Nếu bạn đang sử dụng vật liệu mới hơn, hãy thay đổi md-inputthành mat-input.


1
Nó hoạt động, cảm ơn! Nhưng tôi không hiểu tại sao tôi nên sử dụng "attr.disabled" (không chỉ "vô hiệu hóa")?
Sergey Andreev

6
Chỉ cần lưu ý, với [attr.disabled], bạn không thể sử dụng ràng buộc nó theo hai cách. Nó chỉ hoạt động một lần. Với [disabled]và cảnh báo trong bảng điều khiển đang hoạt động. Tôi đang sử dụng Angular 4.1.3
The.Bear 20/02/18

2
Tôi nghĩ rằng điều [attr.disabled]đó không kích hoạt cảnh báo [disabled]hiển thị
K1ngjulien_

3
Bạn có thể nói rõ hơn tại sao bạn cho rằng nó "cao cấp"?
Lazar Ljubenović

1
Thuộc tính của trường biểu mẫu có thể đọc được từ mẫu HTML. Giả sử một ngày đẹp trời nào đó, bạn quyết định xem điều gì sẽ vô hiệu hóa một trường nhất định mà bản năng là đi từ mẫu HTML sang mã typecript hơn những cách khác.
bhantol

13

Bạn có thể bật / tắt điều khiển biểu mẫu bằng cách sử dụng các phương pháp sau:

control.disable () hoặc control.enable ()

Nếu điều đó không hiệu quả với bạn, bạn có thể sử dụng lệnh

import { NgControl } from '@angular/forms';

@Directive({
  selector: '[disableControl]'
})
export class DisableControlDirective {

  @Input() set disableControl( condition : boolean ) {
    const action = condition ? 'disable' : 'enable';
    this.ngControl.control[action]();
  }

  constructor( private ngControl : NgControl ) {
  }

}

Sau đó, bạn có thể sử dụng nó như thế này

<input [formControl]="formControl" [disableControl]="disable">
<button (click)="disable = true">Disable</button>
<button (click)="disable = false">Enable</button>

Kỹ thuật này được mô tả ở đây:

https://netbasal.com/disabling-form-controls-when-working-with-reactive-forms-in-angular-549dd7b42110

Hy vọng nó giúp


bạn có thể vui lòng cho một số đoạn js đang làm thế nào để làm điều này
kumaresan_sd

vui lòng cung cấp bất kỳ mẫu stackb nào
kumaresan_sd

đây là ví dụ: netbasal.com/…
Janatbek Sharsheyev

Điều đó không hoạt động với Angular 8. Nó mang lạiNgControl (`No provider for NgControl`)
pantonis

1
Tôi có thể xác nhận rằng giải pháp này không hoạt động nữa kể từ Angular 8 !!
Martijn Hiemstra

10

Tôi thấy rằng tôi cần phải có một giá trị mặc định, ngay cả khi đó là một chuỗi trống để nó hoạt động. Vì vậy, điều này:

this.registerForm('someName', {
  firstName: new FormControl({disabled: true}),
});

... phải trở thành cái này:

this.registerForm('someName', {
  firstName: new FormControl({value: '', disabled: true}),
});

Xem câu hỏi của tôi (mà tôi không tin là trùng lặp): Chuyển 'bị vô hiệu hóa' ở đối tượng trạng thái biểu mẫu đến hàm tạo FormControl không hoạt động


9

Trong trường hợp của tôi với Angular 8 . Tôi muốn bật / tắt đầu vào tùy thuộc vào điều kiện.

[attr.disabled] không làm việc cho tôi vì vậy đây là giải pháp của tôi.

Tôi đã xóa [attr.disabled]khỏi HTML và trong hàm thành phần đã thực hiện kiểm tra này:

if (condition) {
    this.form.controls.myField.disable();
} else {
    this.form.controls.myField.enable();
}

4

Khởi tạo (thành phần) bằng cách sử dụng:

public selector = new FormControl({value: '', disabled: true});

Sau đó, thay vì sử dụng (mẫu):

<ngx-select
[multiple]="true"
[disabled]="errorSelector"
[(ngModel)]="ngxval_selector"
[items]="items"
</ngx-select>

Chỉ cần xóa thuộc tính bị vô hiệu hóa:

<ngx-select
[multiple]="true"
[(ngModel)]="ngxval_selector"
[items]="items"
</ngx-select>

Và khi bạn có các mục để hiển thị, hãy khởi chạy (trong thành phần): this.selector.enable();


2

Chỉ những người đang sử dụng biểu mẫu phản ứng: Đối với các phần tử HTML gốc [attr.disabled] sẽ hoạt động nhưng đối với các phần tử material, chúng tôi cần vô hiệu hóa phần tử đó một cách tự động.

this.form.get('controlname').disable();

Nếu không, nó sẽ hiển thị trong thông báo cảnh báo bảng điều khiển.


2

Tôi đã thử những điều này trong góc 7. Nó hoạt động thành công.

this.form.controls['fromField'].reset();
if(condition){
      this.form.controls['fromField'].enable();
}
else{
      this.form.controls['fromField'].disable();
}

2
this.form.disable()
this.form.enable()

Đối với một điều khiển biểu mẫu làm cho vô hiệu hóa

this.form.get('first').disable()
this.form.get('first').enable()

Hoặc phương pháp thiết lập ban đầu.

first: new FormControl({disabled: true}, Validators.required)

1

Sử dụng [attr.disabled] thay vì [đã tắt], trong trường hợp của tôi, nó hoạt động tốt


2
Mặc dù điều này có thể thực hiện được, nhưng bạn không nên sử dụng giải pháp hướng mẫu khi làm việc với các biểu mẫu phản ứng. Vấn đề với việc trộn hai thứ đó là trạng thái dạng phản ứng không còn đáng tin cậy nữa.
enf0rcer

nó sử dụng để vô hiệu hóa nhưng nếu tôi đặt này là sai sự thật cũng kiểm soát được vô hiệu hóa
kumaresan_sd

1

thêm disable = "true" vào trường html Ví dụ: vô hiệu hóa

<amexio-text-input formControlName="LastName" disable="true" [(ngModel)]="emplpoyeeRegistration.lastName" [field-label]="'Last Name'" [place-holder]="'Please enter last name'" [allow-blank]="true" [error-msg]="'errorMsg'" [enable-popover]="true" [min-length]="2"
[min-error-msg]="'Minimum 2 char allowed'" [max-error-msg]="'Maximum 20 char allowed'" name="xyz" [max-length]="20">
[icon-feedback]="true">
</amexio-text-input>

Không làm việc . liên kết mẫu - stackblitz.com/edit/angular-zdpavf?file=src/app/…
kumaresan_sd

Câu trả lời này sẽ không làm việc trong form.this reavtive có liên quan đến mẫu thúc đẩy hình thức
Nambi N Rajan

1

Vẻ đẹp của biểu mẫu phản ứng là bạn có thể nắm bắt sự kiện thay đổi giá trị của bất kỳ phần tử đầu vào nào rất dễ dàng và đồng thời bạn có thể thay đổi giá trị / trạng thái của chúng. Vì vậy, đây là một cách khác để giải quyết vấn đề của bạn bằng cách sử dụng enable disable.

Đây là giải pháp hoàn chỉnh trên stackblitz .


Tôi khuyên bạn nên đăng mã ở đây hoặc ít nhất là một đoạn mã. Tôi thấy giải pháp này hữu ích, vì vậy đăng ký thay đổi giá trị và kích hoạt bật / tắt có vẻ là một lựa chọn tốt.
John White

1

Việc vô hiệu hóa các trường biểu mẫu mat được miễn nếu bạn đang sử dụng xác thực biểu mẫu, vì vậy hãy đảm bảo rằng trường biểu mẫu của bạn không có bất kỳ xác thực nào như (validators.required), điều này phù hợp với tôi. cho người yêu cũ:

editUserPhone: new FormControl ({value: '', vô hiệu hóa: true})

điều này làm cho số điện thoại của người dùng không thể chỉnh sửa được.


1

Đây là giải pháp của tôi:

this.myForm = this._formBuilder.group({
    socDate: [[{ value: '', disabled: true }], Validators.required],
    ...
)}

<input fxFlex [matDatepicker]="picker" placeholder="Select Date" formControlName="socDate" [attr.disabled]="true" />

1
Xin chào Frank, chào mừng bạn đến với StackOverflow và cảm ơn câu trả lời của bạn! Mặc dù chắc chắn là tuyệt vời để cung cấp một giải pháp làm việc trong mã, nhưng nó có thể giúp những người khác hiện tại và trong tương lai hiểu câu trả lời của bạn tốt hơn nếu bạn thêm một chút giải thích ngoài mã.
robsiemb

1

trong Angular-9 nếu bạn muốn tắt / bật trên nút bấm vào đây là một giải pháp đơn giản nếu bạn đang sử dụng các biểu mẫu phản ứng.

xác định một hàm trong tệp component.ts

//enable example you can use the same approach for disable with .disable()

toggleEnable() {
  this.yourFormName.controls.formFieldName.enable();
  console.log("Clicked")
} 

Gọi nó từ component.html của bạn

ví dụ

<button type="button" data-toggle="form-control" class="bg-primary text-white btn- 
                reset" style="width:100%"(click)="toggleEnable()">

0

Khi bạn tạo điều khiển Biểu mẫu mới, hãy sử dụng tiếp theo:

variable: FormControl = new FormControl({value: '', disabled: true});

Nếu bạn muốn thay đổi hoạt động, hãy sử dụng tiếp theo:

this.variable.enable() 

hoặc là

this.variable.disable()

-1

thêm thuộc tính name vào md-input của bạn. nếu nó không giải quyết được vấn đề, vui lòng đăng mẫu của bạn


-4

Cách cuối cùng để làm điều này.

ngOnInit() {
  this.interPretationForm.controls.InterpretationType.valueChanges.takeWhile(()=> this.alive).subscribe(val =>{
    console.log(val); // You check code. it will be executed every time value change.
  })
}
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.