Bentuk reaktif - atribut dinonaktifkan


109

Saya mencoba menggunakan disabledatribut dari a formControl. Saat saya memasukkannya ke dalam template, ini berfungsi:

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

Tapi browser memberi tahu saya:

Sepertinya Anda menggunakan atribut yang dinonaktifkan dengan perintah formulir reaktif. Jika Anda menyetel nonaktif ke true saat menyiapkan kontrol ini di kelas komponen Anda, atribut yang dinonaktifkan sebenarnya akan disetel di DOM untuk Anda. Kami merekomendasikan penggunaan pendekatan ini untuk menghindari kesalahan 'diubah setelah diperiksa'.

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

Jadi saya memasukkannya ke dalam FormControl, dan menghapus dari template:

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);
}

Tapi itu tidak berhasil (tidak menonaktifkan input). Apa masalahnya?


1
Ini tampaknya berfungsi dengan baik dengan versi Angular 2 saat ini: plnkr.co/edit/CQQtkYC9D5EoH0sAlNCV?p=preview
silentsod

Saya menggunakan proyek cli sudut terakhir untuk pengujian
FacundoGFlores

2
Anda menggunakan @ angular / material, jadi, sesuai dengan masalah github mereka: github.com/angular/material2/issues/1171 Ini belum didukung dan mereka dalam versi alfa sehingga Anda tidak dapat mengharapkannya menjadi fitur lengkap.
silentsod

Ya, itu masalahnya
FacundoGFlores

6
Anda dapat mencoba meletakkan this.myForm.controls['id'].disable()di suatu tempat di konstruktor. Saya membuat perpustakaan yang membuatnya lebih mudah untuk bekerja dengan bentuk dinamis: github.com/mat3e/dorf
mat3e

Jawaban:


124

Saya telah menggunakan [attr.disabled]karena saya masih suka template ini didorong daripada programmatic enable () / disable () karena IMO superior.

Perubahan

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

untuk

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

Jika Anda menggunakan materi baru, ubah md-inputke mat-input.


1
Berhasil, terima kasih! Tetapi saya tidak mengerti mengapa saya harus menggunakan "attr.disabled" (tidak hanya "nonaktif")?
Sergey Andreev

6
Sekadar catatan, dengan [attr.disabled] Anda tidak dapat menggunakan bind dengan dua cara. Ini hanya bekerja sekali. Dengan [disabled]dan peringatan di konsol berfungsi. Saya menggunakan Angular 4.1.3
The.Bear

2
Saya pikir itu [attr.disabled]tidak memicu peringatan yang [disabled]menunjukkan
K1ngjulien_

4
Bisakah Anda menjelaskan mengapa menurut Anda itu "superior"?
Lazar Ljubenović

1
Properti bidang formulir dapat dibaca dari template HTML. Katakanlah suatu hari Anda memutuskan untuk melihat apa yang menonaktifkan bidang tertentu, instingnya adalah berjalan dari template HTML menuju kode skrip daripada cara lain.
bhantol

14

Anda dapat mengaktifkan / menonaktifkan kontrol formulir dengan menggunakan metode berikut ini:

control.disable () atau control.enable ()

Jika itu tidak berhasil, Anda dapat menggunakan arahan

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 ) {
  }

}

Kemudian Anda bisa menggunakannya seperti ini

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

Teknik ini dijelaskan di sini:

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

Semoga membantu


bisakah Anda menunjukkan beberapa potongan kode js bagaimana melakukan ini
kumaresan_sd

berikan contoh
stackb

berikut ini contohnya: netbasal.com/…
Janatbek Sharsheyev

Itu tidak bekerja dengan Angular 8. Ini memberiNgControl (`No provider for NgControl`)
pantonis

1
Saya dapat mengonfirmasi bahwa solusi ini tidak berfungsi lagi pada Angular 8 !!
Martijn Hiemstra

13

Dalam kasus saya dengan Angular 8 . Saya ingin mengaktifkan / menonaktifkan input tergantung pada kondisinya.

[attr.disabled] tidak berhasil untuk saya jadi inilah solusi saya.

Saya menghapus [attr.disabled]dari HTML dan dalam fungsi komponen melakukan pemeriksaan ini:

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

12

Saya menemukan bahwa saya perlu memiliki nilai default, bahkan jika itu adalah string kosong agar dapat berfungsi. Jadi ini:

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

... harus menjadi ini:

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

Lihat pertanyaan saya (yang saya tidak percaya adalah duplikat): Meneruskan 'dinonaktifkan' dalam objek status bentuk ke konstruktor FormControl tidak berfungsi


4

Inisialisasi (komponen) menggunakan:

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

Kemudian alih-alih menggunakan (template):

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

Hapus saja atribut yang dinonaktifkan:

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

Dan ketika Anda memiliki item untuk ditampilkan, luncurkan (dalam komponen): this.selector.enable();


3

Hanya yang menggunakan formulir reaktif: Untuk elemen HTML asli [attr.disabled] akan berfungsi, tetapi untuk elemen material kita perlu menonaktifkan elemen tersebut secara dinamis.

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

Jika tidak, itu akan ditampilkan di pesan peringatan konsol.


3

Saya mencoba ini di sudut 7. Berhasil.

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

3
this.form.disable()
this.form.enable()

Untuk satu formcontrol membuat disable

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

Atau metode set awal.

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

1

Gunakan [attr.disabled] alih-alih [dinonaktifkan], dalam kasus saya ini berfungsi dengan baik


2
Meskipun ini dimungkinkan, Anda tidak boleh menggunakan solusi berbasis template saat bekerja dengan formulir reaktif. Masalah dengan pencampuran keduanya adalah bahwa keadaan bentuk reaktif tidak lagi dapat dipercaya.
enf0rcer

itu digunakan untuk menonaktifkan tetapi jika saya menetapkan ini sebagai salah juga mengontrol menonaktifkan
kumaresan_sd

1

tambahkan disable = "true" ke kolom html Contoh: nonaktifkan

<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>


Jawaban ini tidak akan berfungsi dalam bentuk reavtive. Ini terkait dengan formulir yang didorong template
Nambi N Rajan

1

Keindahan bentuk reaktif adalah Anda dapat menangkap peristiwa perubahan nilai dari setiap elemen masukan dengan sangat mudah dan pada saat yang sama Anda dapat mengubah nilai / statusnya. Jadi, inilah cara lain untuk mengatasi masalah Anda dengan menggunakan enable disable.

Berikut adalah solusi lengkap di stackblitz .


Saya sarankan Anda memposting kode di sini juga, atau setidaknya satu cuplikan. Saya menemukan solusi ini berguna, jadi berlangganan perubahan nilai dan mengaktifkan / menonaktifkan tampaknya merupakan opsi yang baik.
John White

1

penonaktifan bidang formulir tikar dikecualikan jika Anda menggunakan validasi formulir, jadi pastikan bidang formulir Anda tidak memiliki validasi seperti (validators.required), ini berfungsi untuk saya. misalnya:

editUserPhone: FormControl baru ({value: '', disabled: true})

ini membuat nomor telepon pengguna tidak dapat diedit.


1

Ini adalah solusi saya:

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

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

1
Halo Frank, selamat datang di StackOverflow, dan terima kasih atas jawaban Anda! Meskipun sangat bagus untuk memberikan solusi yang berfungsi dalam kode, ini dapat membantu orang lain sekarang dan di masa depan memahami jawaban Anda dengan lebih baik jika Anda menambahkan sedikit penjelasan di luar kode.
robsiemb

1

di Angular-9 jika Anda ingin menonaktifkan / mengaktifkan tombol klik di sini adalah solusi sederhana jika Anda menggunakan formulir reaktif.

mendefinisikan fungsi dalam file component.ts

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

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

Sebut saja dari component.html Anda

misalnya

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

0

Saat Anda membuat kontrol formulir baru, gunakan berikutnya:

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

Jika Anda ingin mengubah aktivitas, gunakan next:

this.variable.enable() 

atau

this.variable.disable()

-1

tambahkan atribut name ke md-input Anda. jika tidak menyelesaikan masalah, silakan posting template Anda


-4

Cara terbaik untuk melakukan ini.

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.
  })
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.