Formulaires réactifs - attribut désactivé

97

J'essaye d'utiliser l' disabledattribut d'un formControl. Quand je le mets dans le modèle, cela fonctionne:

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

Mais le navigateur m'alerte:

Il semble que vous utilisez l'attribut désactivé avec une directive de formulaire réactive. Si vous définissez disabled sur true lorsque vous configurez ce contrôle dans votre classe de composant, l'attribut désactivé sera en fait défini dans le DOM pour vous. Nous vous recommandons d'utiliser cette approche pour éviter les erreurs «modifié après vérification».

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

Je l'ai donc mis dans le FormControlet supprimé du modèle:

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

Mais cela ne fonctionne pas (cela ne désactive pas le input). Quel est le problème?

FacundoGFlores
la source
1
Cela semble fonctionner très bien avec la version actuelle d'Angular 2: plnkr.co/edit/CQQtkYC9D5EoH0sAlNCV?p=preview
silentsod
J'utilise le dernier projet angular cli pour les tests
FacundoGFlores
2
Vous utilisez @ angular / material, donc, pour leurs problèmes github: github.com/angular/material2/issues/1171 Ce n'est pas encore pris en charge et ils sont en alpha, vous ne pouvez donc pas vous attendre à ce qu'il soit complet.
silentsod
Oui, c'était le problème
FacundoGFlores
6
Vous pouvez essayer de mettre this.myForm.controls['id'].disable()quelque part dans le constructeur. J'ai fait une bibliothèque qui facilite le travail avec les formulaires dynamiques: github.com/mat3e/dorf
mat3e

Réponses:

116

J'utilise [attr.disabled]parce que j'aime toujours ce modèle piloté par le programme enable () / disable () car il est supérieur à l'OMI.

Changement

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

à

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

Si vous êtes sur un nouveau matériel, passez md-inputà mat-input.

bhantol
la source
1
Cela fonctionne, merci! Mais je ne comprends pas pourquoi je devrais utiliser "attr.disabled" (pas seulement "disabled")?
Sergey Andreev
6
Juste pour noter, avec [attr.disabled] vous ne pouvez pas utiliser le bind de deux manières. Cela ne fonctionne qu'une seule fois. Avec [disabled]et l'avertissement dans la console fonctionne. J'utilise Angular 4.1.3
The.Bear
2
Je pense que [attr.disabled]cela ne déclenche tout simplement pas l'avertissement qui [disabled]montre
K1ngjulien_
3
Pouvez-vous expliquer pourquoi pensez-vous que c'est «supérieur»?
Lazar Ljubenović
1
Les propriétés du champ de formulaire sont lisibles à partir du modèle HTML. Disons qu'un beau jour vous décidez de regarder ce qui désactive un champ donné, l'instinct est de marcher du modèle HTML vers le code dactylographié plutôt que les autres.
bhantol
13

Vous pouvez activer / désactiver un contrôle de formulaire à l'aide des méthodes suivantes:

control.disable () ou control.enable ()

Si cela n'a pas fonctionné, vous pouvez utiliser une directive

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

}

Alors tu pourrais l'utiliser comme ça

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

Cette technique est décrite ici:

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

J'espère que ça aide

Kaloyan Stamatov
la source
pouvez-vous s'il vous plaît montrer un extrait de code js comment faire cela
kumaresan_sd
veuillez fournir des échantillons de stackb
kumaresan_sd
voici un exemple: netbasal.com
...
Cela ne fonctionne pas avec Angular 8. Cela donneNgControl (`No provider for NgControl`)
pantonis
1
Je peux confirmer que cette solution ne fonctionne plus à partir d'Angular 8 !!
Martijn Hiemstra le
10

J'ai trouvé que je devais avoir une valeur par défaut, même s'il s'agissait d'une chaîne vide pour que cela fonctionne. Donc ça:

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

... devait devenir ceci:

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

Voir ma question (que je ne crois pas être un doublon): Passer 'disabled' dans l'objet d'état de formulaire au constructeur FormControl ne fonctionne pas

BBaysinger
la source
9

Dans mon cas avec Angular 8 . Je voulais activer / désactiver l'entrée en fonction de la condition.

[attr.disabled] n'a pas fonctionné pour moi, voici ma solution.

J'ai supprimé [attr.disabled]du HTML et dans la fonction du composant effectué cette vérification:

if (condition) {
    this.form.controls.myField.disable();
} else {
    this.form.controls.myField.enable();
}
Anuj TBE
la source
4

Initialisation (composant) avec:

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

Puis au lieu d'utiliser (template):

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

Supprimez simplement l'attribut désactivé:

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

Et lorsque vous avez des éléments à afficher, lancez (dans le composant): this.selector.enable();

Ignacio Ara
la source
2

Uniquement pour ceux qui utilisent des formulaires réactifs: pour les éléments HTML natifs, [attr.disabled] fonctionnera mais pour les éléments matériels, nous devons désactiver dynamiquement l'élément.

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

Sinon, il s'affichera dans le message d'avertissement de la console.

Tilak Bhandari
la source
2

J'ai essayé ceux-ci en angulaire 7. Cela a fonctionné avec succès.

this.form.controls['fromField'].reset();
if(condition){
      this.form.controls['fromField'].enable();
}
else{
      this.form.controls['fromField'].disable();
}
Recep Duman
la source
2
this.form.disable()
this.form.enable()

Pour un formcontrol fait désactiver

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

Ou méthode de réglage initial.

first: new FormControl({disabled: true}, Validators.required)
Pu ChengLie
la source
1

Utilisez [attr.disabled] à la place [disabled], dans mon cas cela fonctionne bien

Exari Constantin
la source
2
Bien que cela soit possible, vous ne devez pas utiliser une solution basée sur un modèle lorsque vous travaillez avec des formulaires réactifs. Le problème avec le mélange de ces deux éléments est que l'état de forme réactif ne peut plus être fiable.
enf0rcer
il utilise pour désactiver, mais si je le définis comme faux, contrôlez également désactiver
kumaresan_sd
1

ajouter disable = "true" au champ html Exemple: désactiver

<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>
Sagar Jadhav
la source
Ca ne fonctionne pas . exemple de lien - stackblitz.com/edit/angular-zdpavf?file=src/app/…
kumaresan_sd
Cette réponse ne fonctionnera pas sous forme réactive.Cela est lié au formulaire piloté par modèle
Nambi N Rajan
1

La beauté des formulaires réactifs est que vous pouvez détecter très facilement les changements de valeurs de tout élément d'entrée et en même temps, vous pouvez modifier leurs valeurs / leur statut. Voici donc une autre façon de résoudre votre problème en utilisant enable disable.

Voici la solution complète sur stackblitz .

Kedar9444
la source
Je vous suggère de publier le code ici également, ou du moins un extrait de code. J'ai trouvé cette solution utile, donc souscrire au changement de valeur et activer / désactiver le déclenchement semble une bonne option.
John White
1

la désactivation des champs de formulaire mat est exemptée si vous utilisez la validation de formulaire, alors assurez-vous que votre champ de formulaire n'a pas de validations comme (validators.required), cela a fonctionné pour moi. par ex:

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

cela rend les numéros de téléphone de l'utilisateur non modifiables.

un peu T
la source
1

C'était ma solution:

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

<input fxFlex [matDatepicker]="picker" placeholder="Select Date" formControlName="socDate" [attr.disabled]="true" />
Frank Corona
la source
1
Bonjour Frank, bienvenue sur StackOverflow et merci pour votre réponse! Bien qu'il soit certainement formidable de fournir une solution de travail dans le code, cela peut aider les autres maintenant et à l'avenir à mieux comprendre votre réponse si vous ajoutez un peu d'explication au-delà du code.
robsiemb
1

dans Angular-9 si vous souhaitez désactiver / activer sur le bouton cliquez ici est une solution simple si vous utilisez des formulaires réactifs.

définir une fonction dans le fichier component.ts

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

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

Appelez-le depuis votre component.html

par exemple

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

Lorsque vous créez un nouveau contrôle de formulaire, utilisez suivant:

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

Si vous voulez changer d'activité, utilisez suivant:

this.variable.enable() 

ou

this.variable.disable()
Aleksandr Zelenskiy
la source
-1

ajoutez l'attribut de nom à votre entrée md. si cela ne résout pas le problème, veuillez publier votre modèle

Taha Zgued
la source
-4

Meilleure façon de faire cela.

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.
  })
}
user3345544
la source