Forme reattive - attributo disabilitato


97

Sto cercando di utilizzare l' disabledattributo di un file formControl. Quando lo metto nel modello, funziona:

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

Ma il browser mi avvisa:

Sembra che tu stia utilizzando l'attributo disabilitato con una direttiva del modulo reattivo. Se imposti disabled su true quando imposti questo controllo nella classe del tuo componente, l'attributo disabled verrà effettivamente impostato nel DOM per te. Si consiglia di utilizzare questo approccio per evitare errori "modificati dopo il controllo".

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

Quindi l'ho inserito in FormControl, e eliminato dal modello:

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

Ma non funziona (non disabilita il input). Qual è il problema?


1
Questo sembra funzionare bene con la versione corrente di Angular 2: plnkr.co/edit/CQQtkYC9D5EoH0sAlNCV?p=preview
silentsod

Sto usando l'
ultimo

2
Stai usando @ angular / material, quindi, per i loro problemi con github: github.com/angular/material2/issues/1171 Non è ancora supportato e sono in alpha, quindi non puoi aspettarti che sia completo di funzionalità.
silenzioso

Sì, era il problema
FacundoGFlores

6
Puoi provare a inserire this.myForm.controls['id'].disable()da qualche parte nel costruttore. Ho
creato

Risposte:


116

Ho usato [attr.disabled]perché mi piace ancora questo modello guidato da abilitazione () / disabilitazione () programmatica in quanto è IMO superiore.

Modificare

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

per

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

Se stai utilizzando materiale più recente, cambia md-inputin mat-input.


1
Funziona, grazie! Ma non capisco perché dovrei usare "attr.disabled" (non solo "disabled")?
Sergey Andreev

6
Solo per notare, con [attr.disabled] non puoi usare bind in due modi. Funziona solo una volta. Con [disabled]e l'avviso nella console funziona. Sto usando Angular 4.1.3
The.Bear

2
Penso che [attr.disabled]semplicemente non [disabled]
attivi

3
Puoi approfondire perché pensi che sia "superiore"?
Lazar Ljubenović

1
Le proprietà del campo modulo sono leggibili dal modello HTML. Diciamo che un bel giorno decidi di guardare cosa disabilita un dato campo, l'istinto è di passare dal modello HTML al codice dattiloscritto rispetto agli altri modi.
bhantol

13

È possibile abilitare / disabilitare un controllo del modulo utilizzando i seguenti metodi:

control.disable () o control.enable ()

Se ciò non ha funzionato, puoi utilizzare una direttiva

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

}

Quindi potresti usarlo in questo modo

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

Questa tecnica è descritta qui:

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

Spero che sia d'aiuto


puoi per favore mostrare alcuni frammenti di codice js come fare questo
kumaresan_sd

si prega di fornire eventuali campioni
stackb


Non funziona con Angular 8. FornisceNgControl (`No provider for NgControl`)
pantonis

1
Posso confermare che questa soluzione non funziona più a partire da Angular 8 !!
Martijn Hiemstra,

10

Ho scoperto che avevo bisogno di un valore predefinito, anche se era una stringa vuota perché funzionasse. Così questo:

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

... doveva diventare questo:

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

Vedi la mia domanda (che non credo sia un duplicato): il passaggio di "disabilitato" nell'oggetto dello stato del modulo al costruttore di FormControl non funziona


9

Nel mio caso con Angular 8 . Volevo attivare / disattivare l'ingresso a seconda delle condizioni.

[attr.disabled] non ha funzionato per me quindi ecco la mia soluzione.

Ho rimosso [attr.disabled]dall'HTML e nella funzione componente ho eseguito questo controllo:

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

4

Inizializzazione (componente) utilizzando:

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

Quindi invece di usare (template):

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

Basta rimuovere l'attributo disabilitato:

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

E quando hai elementi da mostrare, avvia (nel componente): this.selector.enable();


2

Solo chi utilizza moduli reattivi: Per gli elementi HTML nativi [attr.disabled] funzionerà, ma per gli elementi materiali dobbiamo disabilitare dinamicamente l'elemento.

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

Altrimenti apparirà nel messaggio di avviso della console.


2

Ho provato questi in angolare 7. Ha funzionato con successo.

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

Per un formcontrol rende disabilitato

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

O metodo di impostazione iniziale.

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

1

Usa [attr.disabled] invece [disabled], nel mio caso funziona bene


2
Anche se questo potrebbe essere possibile, non dovresti usare una soluzione basata su modelli quando lavori con moduli reattivi. Il problema con la combinazione di questi due è che non ci si può più fidare dello stato della forma reattiva.
enf0rcer

usa per disabilitare ma se lo imposto come false anche il controllo get disable
kumaresan_sd

1

aggiungi disable = "true" al campo html Esempio: disable

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


Questa risposta non funzionerà in forma reattiva. È correlata al modulo basato su modelli
Nambi N Rajan,

1

La bellezza delle forme reattive è che puoi catturare i cambiamenti dei valori in caso di qualsiasi elemento di input molto facilmente e allo stesso tempo puoi cambiare i loro valori / stato. Quindi ecco un altro modo per affrontare il tuo problema utilizzando enable disable.

Ecco la soluzione completa su Stackblitz .


Ti suggerisco di inserire anche il codice qui, o almeno uno snippet. Ho trovato utile questa soluzione, quindi la sottoscrizione alla modifica del valore e l'attivazione di abilitazione / disabilitazione sembra una buona opzione.
John White il

1

la disabilitazione dei campi del modulo mat è esentata se stai usando la convalida del modulo, quindi assicurati che il tuo campo del modulo non abbia alcuna convalida come (validators.required), questo ha funzionato per me. per es:

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

questo rende i numeri di telefono dell'utente non modificabili.


1

Questa era la mia soluzione:

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

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

1
Ciao Frank, benvenuto in StackOverflow e grazie per la tua risposta! Sebbene sia certamente fantastico fornire una soluzione funzionante nel codice, può aiutare gli altri ora e in futuro a comprendere meglio la tua risposta se aggiungi un po 'di spiegazione oltre il codice.
robsiemb

1

in Angular-9 se si desidera disabilitare / abilitare il pulsante fare clic qui è una soluzione semplice se si utilizzano forme reattive.

definire una funzione nel file component.ts

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

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

Chiamalo dal tuo component.html

per esempio

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

0

Quando crei un nuovo controllo modulo, usa next:

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

Se desideri modificare l'attività, utilizza Avanti:

this.variable.enable() 

o

this.variable.disable()

-1

aggiungi l'attributo name al tuo input md. se non risolve il problema, pubblica il tuo modello


-4

Il modo migliore per farlo.

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.
  })
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.