รูปแบบปฏิกิริยา - แอตทริบิวต์ที่ปิดใช้งาน


114

ฉันพยายามใช้disabledแอตทริบิวต์จากไฟล์formControl. เมื่อฉันใส่ลงในเทมเพลตมันใช้งานได้:

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

แต่เบราว์เซอร์แจ้งเตือนฉัน:

ดูเหมือนว่าคุณกำลังใช้แอตทริบิวต์ที่ปิดใช้งานกับคำสั่งรูปแบบปฏิกิริยา หากคุณตั้งค่าปิดใช้งานเป็นจริงเมื่อคุณตั้งค่าการควบคุมนี้ในคลาสคอมโพเนนต์ของคุณแอตทริบิวต์ที่ปิดใช้งานจะถูกตั้งค่าใน 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

7
คุณสามารถลองวางthis.myForm.controls['id'].disable()ที่ไหนสักแห่งในตัวสร้าง ฉันสร้างห้องสมุดซึ่งทำให้ง่ายต่อการทำงานกับรูปแบบไดนามิก: github.com/mat3e/dorf
mat3e

คำตอบ:


132

ฉันใช้[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.


2
ได้ผลขอบคุณ! แต่ฉันไม่เข้าใจว่าทำไมฉันจึงควรใช้ "attr.disabled" (ไม่ใช่เฉพาะ "disabled")
Sergey Andreev

7
โปรดทราบว่าด้วย [attr.disabled] คุณไม่สามารถใช้การผูกได้สองทาง ใช้งานได้เพียงครั้งเดียว ด้วย[disabled]และคำเตือนในคอนโซลกำลังทำงาน ฉันใช้ Angular 4.1.3
The.Bear

2
ฉันคิดว่า[attr.disabled]มันไม่ทำให้เกิดการเตือนที่[disabled]แสดง
K1ngjulien_

4
คุณช่วยอธิบายให้ละเอียดได้ไหมว่าทำไมคุณถึงคิดว่า "เหนือกว่า"
Lazar Ljubenović

2
ฉันไม่คิดว่าวิธีแก้ปัญหานี้ใช้ได้อีกต่อไป อาจใช้งานได้กับ Angular เวอร์ชันเก่ากว่า แต่จะส่งเสียงเตือนเกี่ยวกับฉัน (Angular 7.2.12)
จุน

18

ในกรณีของฉันกับเชิงมุม 8 ฉันต้องการเปิด / ปิดการใช้งานอินพุตขึ้นอยู่กับเงื่อนไข

[attr.disabled] ไม่ได้ผลสำหรับฉันดังนั้นนี่คือทางออกของฉัน

ฉันลบออก[attr.disabled]จาก HTML และในฟังก์ชันส่วนประกอบทำการตรวจสอบนี้:

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

17

คุณสามารถเปิด / ปิดการใช้งานการควบคุมฟอร์มโดยใช้วิธีการต่อไปนี้:

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

โปรดระบุตัวอย่าง
stackb

นี่คือตัวอย่าง netbasal.com/…
Janatbek Sharsheyev

มันใช้ไม่ได้กับ Angular 8 มันให้NgControl (`No provider for NgControl`)
pantonis

1
ฉันสามารถยืนยันได้ว่าโซลูชันนี้ใช้ไม่ได้อีกต่อไปสำหรับ Angular 8 !!
Martijn Hiemstra

14

ฉันพบว่าฉันต้องมีค่าเริ่มต้นแม้ว่ามันจะเป็นสตริงว่างเปล่าเพื่อให้มันทำงานได้ ดังนั้นสิ่งนี้:

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

... ต้องกลายเป็นสิ่งนี้:

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

ดูคำถามของฉัน (ซึ่งฉันไม่เชื่อว่าซ้ำกัน): การส่ง 'ปิดใช้งาน' ในรูปแบบออบเจ็กต์ไปยังตัวสร้าง FormControl ไม่ทำงาน


5
this.form.disable()
this.form.enable()

สำหรับ formcontrol หนึ่งทำให้ปิดใช้งาน

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

หรือวิธีการตั้งค่าเริ่มต้น.

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

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


3

เฉพาะผู้ที่ใช้รูปแบบปฏิกิริยา: สำหรับองค์ประกอบ HTML ดั้งเดิม [attr.disabled] จะทำงานได้ แต่สำหรับองค์ประกอบวัสดุเราจำเป็นต้องปิดใช้งานองค์ประกอบแบบไดนามิก

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

มิฉะนั้นจะแสดงในข้อความเตือนคอนโซล


3

ฉันลองสิ่งเหล่านี้ในเชิงมุม 7 มันได้ผลสำเร็จ

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

2

นี่คือทางออกของฉัน:

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

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

1
สวัสดี Frank ยินดีต้อนรับสู่ StackOverflow และขอบคุณสำหรับคำตอบของคุณ! แม้ว่าจะเป็นการดีอย่างแน่นอนในการจัดเตรียมการแก้รหัสที่ใช้งานได้ แต่ก็สามารถช่วยให้ผู้อื่นเข้าใจคำตอบของคุณได้ดีขึ้นในปัจจุบันและอนาคตหากคุณเพิ่มคำอธิบายเล็กน้อยนอกเหนือจากรหัส
robsiemb

วิธีแก้ปัญหาของฉันชอบของคุณ แต่องค์ประกอบ "อินพุต" ไม่จำเป็นต้อง 'ปิดการใช้งาน' this.myForm = this._formBuilder.group({ socDate: [[{ value: '', disabled: true }], Validators.required], ... )}มันเหมือนกับและใช้งานได้ดี
ไฮด์

2

ใน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()">

1

ใช้ [attr.disabled] แทน [disabled] ในกรณีของฉันมันใช้ได้


2
แม้ว่าจะเป็นไปได้ แต่คุณไม่ควรใช้โซลูชันที่ขับเคลื่อนด้วยเทมเพลตเมื่อทำงานกับแบบฟอร์มที่มีปฏิกิริยา ปัญหาในการผสมสองอย่างนี้คือสถานะรูปแบบปฏิกิริยาไม่สามารถเชื่อถือได้อีกต่อไป
enf0rcer

มันใช้เพื่อปิดการใช้งาน แต่ถ้าฉันตั้งค่านี้เป็นเท็จก็ควบคุมการปิดการใช้งานด้วย
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

คำตอบนี้จะใช้ไม่ได้ในรูปแบบ reavtive ซึ่งเกี่ยวข้องกับแบบฟอร์มที่ขับเคลื่อนด้วยเทมเพลต
Nambi N Rajan

1

ความสวยงามของรูปแบบปฏิกิริยาคือคุณสามารถตรวจจับเหตุการณ์การเปลี่ยนแปลงค่าขององค์ประกอบอินพุตใด ๆ ได้อย่างง่ายดายและในเวลาเดียวกันคุณสามารถเปลี่ยนค่า / สถานะได้ ดังนั้นนี่คืออีกวิธีหนึ่งในการจัดการปัญหาของคุณโดยใช้enable disableดังนั้นนี่คือวิธีที่จะจัดการปัญหาของคุณโดยใช้อีก

นี่เป็นทางออกที่สมบูรณ์แบบบนstackblitz


ฉันขอแนะนำให้คุณโพสต์รหัสที่นี่เช่นกันหรืออย่างน้อยตัวอย่าง ฉันพบว่าโซลูชันนี้มีประโยชน์ดังนั้นการสมัครรับการเปลี่ยนแปลงค่าและการเปิด / ปิดการใช้งานจึงเป็นตัวเลือกที่ดี
John White

1

การปิดใช้งานฟิลด์แบบฟอร์ม mat จะได้รับการยกเว้นหากคุณใช้การตรวจสอบแบบฟอร์มดังนั้นโปรดตรวจสอบให้แน่ใจว่าฟิลด์แบบฟอร์มของคุณไม่มีการตรวจสอบความถูกต้องใด ๆ เช่น (validators.required) สิ่งนี้ใช้ได้กับฉัน สำหรับอดีต:

editUserPhone: FormControl ใหม่ ({value: '', disabled: true})

ทำให้หมายเลขโทรศัพท์ของผู้ใช้ไม่สามารถแก้ไขได้


1

เมื่อคุณสร้างตัวควบคุมฟอร์มใหม่ให้ใช้ถัดไป:

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

หากคุณต้องการเปลี่ยนแปลงกิจกรรมให้ใช้ต่อไป:

this.variable.enable() 

หรือ

this.variable.disable()

-1

เพิ่มแอตทริบิวต์ชื่อในการป้อนข้อมูล 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.
  })
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.