Angular 在设置另一个下拉菜单中的值之前禁用响应式表单中的下拉菜单

Angular disable dropdown menu in Reactive Form until value in another dropdown menu has been set

我希望在用户从下拉菜单“类别”中选择一个值之前,使用灰色背景禁用下拉菜单“子类别”(并且不可能打开带有定义的占位符的下拉菜单)。我正在使用反应形式。我的列表“类别”和“子类别”在组件 class 中进行了硬编码,并且我在顶部声明了一个列表 selectedSubcategories 以保留基于所选类别的子类别列表。

在模板驱动的方法中,我设法通过使用 [disabled] 属性禁用了这个下拉菜单。

我的 html 下拉菜单“类别”:

<select class="form-control" (change)="selectChangeCategory($event)">
          <option disabled selected>Select...</option>
          <option *ngFor="let category of categories">
            {{category.name}}
          </option>
        </select>

跟踪在下拉菜单“类别”中选择的值的 selectChangeCategory 方法:

selectChangeCategory(event: any){
    this.selectedCategory = event.target.value;
    this.selectedSubcategories = this.selectSubcategory(this.selectedCategory);
  }

selectSubcategory 方法 returns 右边的子类别列表:

selectSubcategory(selectedCategory: string){
  if(selectedCategory == "Category 1"){
    this.selectedSubcategories = this.subcategoriesCategory1;
  }
  else if(selectedCategory == "Category 2"){
    this.selectedSubcategories = this.subcategoriesCategory2;
  }
  else{
    this.selectedSubcategories = [{name: 'empty!'}];
  }
  return this.selectedSubcategories;
  }

我的 html 下拉菜单“子类别”:

<select class="form-control" (change)="selectSubcategory(selectedCategory)" value="subcategory.name" [disabled]="selectedCategory===''">
          <option disabled selected >Select...</option>
          <option *ngFor="let subcategory of selectedSubcategories">
            {{subcategory.name}}
          </option>
        </select>

[disabled]="selectedCategory===''" 在模板驱动方法中工作得很好。下拉菜单“子类别”具有漂亮的灰色背景,并且在用户选择类别之前处于禁用状态。在反应形式方法中,此代码失败。选择类别后,我设法只显示子类别,但您仍然可以打开“子类别”的下拉菜单并看到“Select...”标签。

编辑:这是我在 ngOnchanges() 方法中的代码:

ngOnChanges(){
    this.selectedSubcategories = this.selectSubcategory(this.selectedCategory);
  }

非常感谢任何帮助。

在反应形式中,您应该禁用其中一种形式的控件

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

或反应性

control.disable() 
control.enable()

因为在模板驱动形式中,您实际上在控件上设置了 disable attribute。 或者如果你想要一个更简单的解决方案,你可以创建一个像这样的自定义指令

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

}

该指令在反应形式

的上下文中完全disable属性

我认为问题在于响应式表单的实现。检查下面的示例,这应该可以解决您的问题。您可以直接在 [disabled]="!categoryForm.controls['category'].value" 条件 formControlName 上使用,以便如果选择了某些子类别,则只会启用。还要尽量避免在 ngOnChanges 中赋值,因为它会被调用很多次。尝试在服务初始化后或 ngAfterViewInit 挂钩后分配。

      constructor( private formBuilder: FormBuilder){} //take an instance of FormBuilder
                
                this.categoryForm= this.formBuilder.group({
                  'category': [''], //if you want to initialize any selected value you can pass it directly here
                  'subCategory': ['']
            }); // initialize a form group
                 
             selectChangeCategory(event: any){
              this.selectedCategory = this.categoryForm.controls['category'].value;
              this.selectedSubcategories = this.selectSubcategory(this.selectedCategory);
             }
            selectSubcategory(selectedCategory: string){
              if(selectedCategory == "Category 1"){
              this.selectedSubcategories = this.subcategoriesCategory1;
            }
           else if(selectedCategory == "Category 2"){
            this.selectedSubcategories = this.subcategoriesCategory2;
           }
           else{
            this.selectedSubcategories = [{name: 'empty!'}];
           }
          return this.selectedSubcategories;
         }
//html file
    <form  [formGroup]="categoryForm" >
               <select class="form-control" formControlName="category" (change)="selectChangeCategory($event)">
                      <option value="" disabled selected>Select...</option>
                      <option *ngFor="let cat of categories" [value]="cat.name">
                        {{cat.name}}
                      </option>
                    </select>
            <select class="form-control" formControlName="subCategory"(change)="selectSubcategory(selectedCategory)[disabled]="!categoryForm.controls['category'].value">
                      <option value="" disabled selected >Select...</option>
                      <option *ngFor="let scat of selectedSubcategories" [value]="scat.name">
                        {{scat.name}}
                      </option>
                    </select>
                </form>

如果您仍然面临任何挑战,请告诉我。谢谢。

其他方式:而不是在html中添加禁用条件 this.categoryForm= this.formBuilder.group({ 'category': [''], //如果你想初始化任何选择的值你可以直接在这里传递 'subCategory': [{值: '', 禁用: !this.selectedCategory}] }); // 初始化一个表单组