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


109

Я пытаюсь использовать disabledатрибут из файла formControl. Когда я вставляю его в шаблон, он работает:

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

Но браузер предупреждает меня:

Похоже, вы используете атрибут disabled с директивой реактивной формы. Если вы установите для disabled значение 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
silntsod 08

Я использую для тестирования
последний

2
Вы используете @ angular / material, поэтому из-за их проблем с github: github.com/angular/material2/issues/1171 Он еще не поддерживается и находится в альфа-версии, поэтому вы не можете ожидать, что это будет полная функция.
silntsod 08

Да, это была проблема
ФакундоГФлорес

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

Ответы:


125

Я использую, [attr.disabled]потому что мне все еще нравится этот шаблон, управляемый, чем программный enable () / disable (), поскольку он превосходит 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_

4
Не могли бы вы уточнить, почему вы думаете, что это «лучше»?
Лазар Любенович

1
Свойства поля формы доступны для чтения из HTML-шаблона. Скажем, в один прекрасный день вы решили посмотреть, что отключает данное поле, инстинкт состоит в том, чтобы перейти от шаблона HTML к коду машинописного текста, чем другими способами.
bhantol 01

14

Вы можете включить / отключить элемент управления формой, используя следующие методы:

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/disables-form-controls-when-working-with-reactive-forms-in-angular-549dd7b42110

Надеюсь, это поможет


не могли бы вы показать какой-нибудь фрагмент js-кода, как это сделать
kumaresan_sd

пожалуйста, предоставьте любые образцы stackb
kumaresan_sd


Это не работает с Angular 8. Это даетNgControl (`No provider for NgControl`)
pantonis

1
Я могу подтвердить, что это решение больше не работает с Angular 8 !!
Martijn Hiemstra

13

В моем случае с Angular 8 . Я хотел включить / выключить ввод в зависимости от условия.

[attr.disabled] у меня не сработало, так что вот мое решение.

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

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

12

Я обнаружил, что мне нужно иметь значение по умолчанию, даже если это была пустая строка для работы. Итак, это:

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

... должен был стать таким:

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

См. Мой вопрос (который я не считаю дубликатом): передача «отключен» в объекте состояния формы в конструктор FormControl не работает


4

Инициализация (компонент) с использованием:

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

Тогда вместо использования (шаблона):

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

Просто удалите атрибут disabled:

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

И когда у вас есть элементы для отображения, запустите (в компоненте): this.selector.enable();


3

Только те, кто использует реактивные формы: для собственных HTML-элементов [attr.disabled] будет работать, но для материальных элементов нам нужно динамически отключить элемент.

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

В противном случае это будет отображаться в предупреждающем сообщении консоли.


3

Я пробовал это в angular 7. Он успешно работал.

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

Для одного formcontrol отключает

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

Или метод начальной установки.

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

1

Используйте [attr.disabled] вместо [disabled], в моем случае он работает нормально


2
Хотя это возможно, вам не следует использовать решение на основе шаблонов при работе с реактивными формами. Проблема со смешиванием этих двух состоит в том, что состоянию реактивной формы больше нельзя доверять.
enf0rcer

он использует для отключения, но если я установил это как false, также управление отключением
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

Этот ответ не будет работать в обратной форме. Это связано с формой, управляемой шаблоном,
Намби Н Раджан

1

Прелесть реактивных форм в том, что вы можете очень легко уловить событие изменения значений любого элемента ввода и в то же время вы можете изменить их значения / статус. Итак, вот еще один способ решить вашу проблему, используяenable disable .

Вот полное решение stackblitz .


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

1

отключение полей формы mat исключено, если вы используете проверку формы, поэтому убедитесь, что ваше поле формы не имеет никаких проверок, таких как (validators.required), это сработало для меня. например:

editUserPhone: новый FormControl ({значение: '', отключено: 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 и спасибо за ответ! Хотя, безусловно, замечательно предоставлять рабочее решение в коде, это может помочь другим сейчас и в будущем лучше понять ваш ответ, если вы добавите немного пояснений помимо кода.
robsiemb 08

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

Когда вы создаете новый элемент управления Form, используйте следующее:

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

Если вы хотите изменить активность, используйте следующее:

this.variable.enable() 

или

this.variable.disable()

-1

добавьте атрибут name к вашему md-input. если это не решит проблему, опубликуйте свой шаблон


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