Reaktive Formulare - deaktiviertes Attribut

96

Ich versuche, das disabledAttribut von a zu verwenden formControl. Wenn ich es in die Vorlage einfüge, funktioniert es:

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

Aber der Browser warnt mich:

Es sieht so aus, als würden Sie das Attribut disabled mit einer reaktiven Formularanweisung verwenden. Wenn Sie beim Einrichten dieses Steuerelements in Ihrer Komponentenklasse deaktiviert auf true setzen, wird das Attribut disabled tatsächlich im DOM für Sie festgelegt. Wir empfehlen diesen Ansatz, um Fehler zu vermeiden, die nach Überprüfung geändert wurden.

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

Also habe ich es in die FormControlund aus der Vorlage gelöscht:

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

Aber es funktioniert nicht (es deaktiviert das nicht input). Was ist das Problem?

FacundoGFlores
quelle
1
Dies scheint gut mit der aktuellen Version von Angular 2 zu funktionieren
silentsod
Ich benutze das letzte Winkel-Cli-Projekt zum Testen
FacundoGFlores
2
Sie verwenden @ angle / material, also gemäß den Github-Problemen: github.com/angular/material2/issues/1171 Es wird noch nicht unterstützt und sie sind in Alpha, sodass Sie nicht erwarten können, dass die Funktion vollständig ist.
Silentsod
Ja, es war das Problem
FacundoGFlores
6
Sie können versuchen, this.myForm.controls['id'].disable()irgendwo in den Konstruktor zu setzen. Ich habe eine Bibliothek erstellt, die das Arbeiten mit dynamischen Formularen erleichtert: github.com/mat3e/dorf
mat3e

Antworten:

112

Ich habe verwendet, [attr.disabled]weil ich diese Vorlage immer noch als programmgesteuertes enable () / disable () mag, da sie IMO überlegen ist.

Veränderung

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

zu

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

Wenn Sie auf neuerem Material sind, wechseln Sie md-inputzu mat-input.

Bhantol
quelle
1
Es funktioniert, danke! Aber ich verstehe nicht, warum ich "attr.disabled" verwenden soll (nicht nur "disabled")?
Sergey Andreev
6
Nur um zu beachten, mit [attr.disabled] können Sie es nicht auf zwei Arten binden. Es funktioniert nur einmal. Mit[disabled] und die Warnung in der Konsole funktioniert. Ich benutze Angular 4.1.3
The.Bear
2
ich denke, dass [attr.disabled] das löst einfach nicht die Warnung aus, die [disabled]zeigt
K1ngjulien_
3
Können Sie näher erläutern, warum Sie es für "überlegen" halten?
Lazar Ljubenović
1
Die Eigenschaften des Formularfelds können aus der HTML-Vorlage gelesen werden. Angenommen, Sie entscheiden sich eines schönen Tages dafür, zu prüfen, was ein bestimmtes Feld deaktiviert. Der Instinkt besteht darin, von der HTML-Vorlage zum Typoskript-Code zu wechseln, als auf andere Weise.
Bhantol
13

Sie können ein Formularsteuerelement mithilfe der folgenden Methoden aktivieren / deaktivieren:

control.disable () oder control.enable ()

Wenn das bei Ihnen nicht funktioniert hat, können Sie eine Direktive verwenden

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

}

Dann könnten Sie es so verwenden

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

Diese Technik wird hier beschrieben:

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

Ich hoffe es hilft

Kaloyan Stamatov
quelle
Können Sie bitte einige JS-Code-Schnipsel zeigen, wie das geht
kumaresan_sd
Bitte geben Sie alle Stackb-Beispiele an
kumaresan_sd
Hier ist ein Beispiel: netbasal.com/…
Janatbek Sharsheyev
Das funktioniert nicht mit Angular 8. Es gibtNgControl (`No provider for NgControl`)
pantonis
1
Ich kann bestätigen, dass diese Lösung ab Angular 8 nicht mehr funktioniert !!
Martijn Hiemstra
10

Ich stellte fest, dass ich einen Standardwert haben musste, auch wenn es eine leere Zeichenfolge war, damit es funktionierte. Also das:

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

... musste das werden:

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

Siehe meine Frage (von der ich nicht glaube, dass sie ein Duplikat ist): Die Übergabe von 'disabled' im Formularstatusobjekt an den FormControl-Konstruktor funktioniert nicht

BBaysinger
quelle
9

In meinem Fall mit Angular 8 . Ich wollte das Aktivieren / Deaktivieren des Eingangs je nach Bedingung umschalten.

[attr.disabled] hat bei mir nicht funktioniert, also hier ist meine Lösung.

Ich habe [attr.disabled]aus HTML entfernt und in der Komponentenfunktion diese Prüfung durchgeführt:

if (condition) {
    this.form.controls.myField.disable();
} else {
    this.form.controls.myField.enable();
}
Anuj FSME
quelle
4

Initialisierung (Komponente) mit:

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

Dann anstatt (Vorlage) zu verwenden:

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

Entfernen Sie einfach das deaktivierte Attribut:

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

Und wenn Sie Elemente anzeigen möchten, starten Sie (in der Komponente): this.selector.enable();

Ignacio Ara
quelle
2

Ich habe diese in Winkel 7 ausprobiert. Es hat erfolgreich funktioniert.

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

Zum einen macht formcontrol deaktivieren

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

Oder anfängliche Einstellmethode.

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

Verwenden Sie stattdessen [attr.disabled] [disabled], in meinem Fall funktioniert es in Ordnung

Exari Constantin
quelle
2
Dies ist zwar möglich, Sie sollten jedoch keine vorlagengesteuerte Lösung verwenden, wenn Sie mit reaktiven Formularen arbeiten. Das Problem beim Mischen dieser beiden ist, dass dem reaktiven Formzustand nicht mehr vertraut werden kann.
Enf0rcer
es verwendet, um zu deaktivieren, aber wenn ich dies als falsch setze, wird auch die Steuerung deaktiviert
kumaresan_sd
1

add disable = "true" zum HTML-Feld Beispiel: 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>
Sagar Jadhav
quelle
Funktioniert nicht . Beispiel Link - Stackblitz.com/edit/angular-zdpavf?file=src/app/…
Kumaresan_sd
Diese Antwort wird nicht in reaktiver Form funktionieren. Dies bezieht sich auf die vorlagengesteuerte Form
Nambi N Rajan
1

Das Schöne an reaktiven Formen ist, dass Sie Werteänderungsereignisse für jedes Eingabeelement sehr einfach erfassen und gleichzeitig deren Werte / Status ändern können. Hier ist eine andere Möglichkeit, Ihr Problem mithilfe von zu lösenenable disable .

Hier ist die Komplettlösung auf stackblitz .

Kedar9444
quelle
Ich schlage vor, dass Sie den Code auch hier posten oder zumindest einen Ausschnitt. Ich fand diese Lösung nützlich, daher scheint es eine gute Option zu sein, die Wertänderung zu abonnieren und das Aktivieren / Deaktivieren auszulösen.
John White
1

Das Deaktivieren von Mattenformularfeldern ist ausgenommen, wenn Sie die Formularvalidierung verwenden. Stellen Sie daher sicher, dass Ihr Formularfeld keine Validierungen wie (validators.required) enthält. Dies hat bei mir funktioniert. zum Beispiel:

editUserPhone: neues FormControl ({Wert: '', deaktiviert: true})

Dadurch können die Telefonnummern des Benutzers nicht bearbeitet werden.

etwas T.
quelle
1

Das war meine Lösung:

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
quelle
1
Hallo Frank, willkommen bei StackOverflow und danke für deine Antwort! Es ist sicherlich großartig, eine funktionierende Lösung für Code bereitzustellen, aber es kann anderen jetzt und in Zukunft helfen, Ihre Antwort besser zu verstehen, wenn Sie über den Code hinaus eine Erklärung hinzufügen.
Robsiemb
1

Nur wer reaktive Formulare verwendet: Für native HTML-Elemente [attr.disabled] funktioniert dies, für Materialelemente muss das Element jedoch dynamisch deaktiviert werden.

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

Andernfalls wird eine Warnmeldung in der Konsole angezeigt.

Tilak Bhandari
quelle
1

Wenn Sie in Angular-9 die Schaltfläche deaktivieren / aktivieren möchten, klicken Sie hier. Dies ist eine einfache Lösung, wenn Sie reaktive Formulare verwenden.

Definieren Sie eine Funktion in der Datei component.ts

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

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

Rufen Sie es von Ihrer component.html auf

z.B

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

Verwenden Sie beim Erstellen eines neuen Formularsteuerelements Folgendes:

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

Wenn Sie die Aktivität ändern möchten, verwenden Sie als Nächstes:

this.variable.enable() 

oder

this.variable.disable()
Aleksandr Zelenskiy
quelle
-1

füge deinem md-input ein name-Attribut hinzu. Wenn das Problem dadurch nicht behoben wird, veröffentlichen Sie bitte Ihre Vorlage

Taha Zgued
quelle
-4

Ultimative Möglichkeit, dies zu tun.

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
quelle