Реактивні форми - відключений атрибут


97

Я намагаюся використати disabledатрибут із formControl. Коли я вкладаю його в шаблон, він працює:

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

Але браузер попереджає мене:

Схоже, ви використовуєте атрибут disabled з директивою реактивної форми. Якщо ви встановили значення true для true, коли ви встановлюєте цей елемент керування у своєму класі компонентів, атрибут disabled буде фактично встановлений для вас у DOM. Ми рекомендуємо використовувати цей підхід, щоб уникнути помилок "змінено після перевірки".

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

Тому я помістив його в FormControlшаблон і видалив із шаблону:

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

Але це не працює (це не відключає input). В чому проблема?


1
Здається, це прекрасно працює з поточною версією Angular 2: plnkr.co/edit/CQQtkYC9D5EoH0sAlNCV?p=preview
silentsod

Я використовую останній кутовий проект cli для тестування
FacundoGFlores

2
Ви використовуєте @ angular / material, тож за їх видами github: github.com/angular/material2/issues/1171 Це ще не підтримується, і вони перебувають в альфа-версії, тому ви не можете очікувати, що ця функція буде повною.
silentsod

Так, це була проблема
FacundoGFlores

6
Ви можете спробувати помістити this.myForm.controls['id'].disable()десь у конструктор. Я зробив бібліотеку, яка полегшує роботу з динамічними формами: github.com/mat3e/dorf
mat3e

Відповіді:


116

Я використовую [attr.disabled] тому що мені все ще подобається цей шаблон, керований програмним увімкненням () / відключенням (), оскільки він чудовий IMO.

Зміна

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

до

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

Якщо ви використовуєте новіші матеріали, змініть md-inputна mat-input.


1
Це працює, дякую! Але я не розумію, чому мені слід використовувати "attr.disabled" (а не тільки "disabled")?
Сергій Андрєєв

6
Зауважимо, що з [attr.disabled] ви не можете використовувати прив’язку двояко. Це працює лише один раз. З [disabled]і попередження в консолі працює. Я використовую Angular 4.1.3
The.Bear

2
Я думаю, що це [attr.disabled]просто не викликає попередження, яке [disabled]відображається
K1ngjulien_

3
Чи можете ви детальніше пояснити, чому, на вашу думку, це "вищо"?
Лазар Любенович

1
Властивості поля форми можна прочитати з шаблону HTML. Скажімо, одного чудового дня ви вирішите подивитися, що відключає дане поле, інстинктом є перехід від шаблону HTML до коду машинопису, ніж інші способи.
bhantol

13

Ви можете ввімкнути / вимкнути елемент керування формою, використовуючи такі методи:

control.disable () або control.enable ()

Якщо це не спрацювало, ви можете скористатися директивою

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

}

Тоді ви могли б використовувати його таким чином

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

Цей прийом описаний тут:

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

Сподіваюся, це допоможе


чи не можете ви показати фрагмент коду js, як це зробити
kumaresan_sd

будь-ласка, надайте будь-які зразки
стека


Це не працює з Angular 8. Це даєNgControl (`No provider for NgControl`)
pantonis

1
Я можу підтвердити, що це рішення вже не працює, починаючи з Angular 8 !!
Martijn Hiemstra,

10

Я виявив, що мені потрібно мати значення за замовчуванням, навіть якщо це було порожнім рядком для його роботи. Отже це:

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

... повинен був стати таким:

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

Перегляньте моє запитання (яке, на мою думку, не є дублікатом): Передача об'єкта стану "відключеного" у конструктор FormControl не працює


9

У моєму випадку з Angular 8 . Я хотів увімкнути / вимкнути вхід в залежності від стану.

[attr.disabled] не працював для мене, тому ось моє рішення.

Я видалив [attr.disabled]з HTML і у функції компонента виконав цю перевірку:

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

4

Ініціалізація (компонент) за допомогою:

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

Тоді замість використання (шаблон):

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

Просто видаліть вимкнений атрибут:

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

І коли у вас є елементи для показу, запустіть (у компоненті): this.selector.enable();


2

Тільки ті, хто використовує реактивні форми: для власних елементів HTML [attr.disabled] буде працювати, але для елементів матеріалу нам потрібно динамічно вимкнути елемент.

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

В іншому випадку він відображатиметься у попереджувальному повідомленні консолі.


2

Я спробував їх у кутовому 7. Це спрацювало успішно.

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

Для однієї формиcontrol робить відключення

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

Або метод початкового набору.

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

1

Використовуйте [attr.disabled] замість [вимкнено], у моєму випадку це працює нормально


2
Незважаючи на те, що це можливо, не слід використовувати шаблонне рішення під час роботи з реактивними формами. Проблема змішування цих двох полягає в тому, що стану реактивної форми більше не можна довіряти.
enf0rcer

він використовує для вимкнення, але якщо я встановив це як false, також контролюю отримати disable
kumaresan_sd

1

додати disable = "true" до поля html Приклад: вимкнути

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

Не працює . зразок посилання - stackblitz.com/edit/angular-zdpavf?file=src/app/…
kumaresan_sd

Ця відповідь не буде працювати у реактивній формі. Це пов’язано з шаблоном, керованою шаблоном
Nambi N Rajan,

1

Краса реактивних форм полягає в тому, що ви можете дуже легко вловлювати події змін значень будь-якого вхідного елемента і одночасно ви можете змінювати їх значення / статус. Тож ось ще один спосіб вирішити вашу проблему за допомогою enable disable.

Ось повне рішення щодо стекбліцу .


Я пропоную вам розмістити тут код, або принаймні фрагмент. Я знайшов це рішення корисним, тому підписка на зміну значення та активація увімкнення / вимкнення представляється хорошим варіантом.
Джон Вайт

1

відключення полів матової форми звільняється, якщо ви використовуєте перевірку форми, тому переконайтеся, що у вашому полі форми немає жодних перевірок, таких як (validators.required), це спрацювало для мене. наприклад:

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

це робить телефонні номери користувача недоступними для редагування.


1

Це було моє рішення:

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

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

1
Привіт, Френк, ласкаво просимо до StackOverflow та дякуємо за вашу відповідь! Хоча, звичайно, чудово надати робоче рішення в коді, це може допомогти іншим зараз і в майбутньому краще зрозуміти вашу відповідь, якщо ви додасте трохи пояснень поза кодом.
Робсіемб

1

в Angular-9 якщо ви хочете відключити / увімкнути кнопку, натисніть тут просте рішення, якщо ви використовуєте реактивні форми.

визначити функцію у файлі component.ts

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

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

Зателефонуйте йому з вашого component.html

напр

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

0

Створюючи новий елемент керування формою, використовуйте наступне:

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

Якщо ви хочете змінити діяльність, використовуйте наступне:

this.variable.enable() 

або

this.variable.disable()

-1

додати атрибут name до вашого md-вводу. якщо це не вирішує проблему, надішліть шаблон


-4

Кінцевий спосіб зробити це.

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.
  })
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.