【问题标题】:Angular disable dropdown menu in Reactive Form until value in another dropdown menu has been set反应形式中的角度禁用下拉菜单,直到设置另一个下拉菜单中的值
【发布时间】:2021-07-04 12:42:31
【问题描述】:

我希望在用户从下拉菜单“类别”中选择一个值之前,以灰色背景禁用下拉菜单“子类别”(并且无法打开具有定义占位符的下拉菜单)。我正在使用反应形式。我的列表“类别”和“子类别”在组件类中进行了硬编码,并且我在顶部声明了一个 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方法:

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===''" 在模板驱动的方法中完美运行。下拉菜单“子类别”具有漂亮的灰色背景,并且在用户选择类别之前被禁用。在反应形式方法中,此代码失败。选择类别后,我设法仅显示子类别,但您仍然可以打开“子类别”的下拉菜单并看到“选择...”标签。

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

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

我非常感谢这里的任何帮助。

【问题讨论】:

    标签: angular drop-down-menu angular-reactive-forms disable


    【解决方案1】:

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

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

    【讨论】:

    • 我想试试你的第一种方法。你能解释一下我可以把control.disable()放在哪里(所以没有单独的指令)?如何添加只有选择了类别才能启用控件的条件?
    【解决方案2】:

    我认为问题在于反应式表单实现。检查下面的示例,这应该可以解决您的问题。您可以直接在 formControlName 上使用 [disabled]="!categoryForm.controls['category'].value" 条件,这样如果选择了某些内容,则仅启用子类别.还要尽量避免在 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': [{value: '', disabled: !this.selectedCategory}] }); // 初始化表单组

    【讨论】:

    • 我试过你的代码,现在我的类别下拉列表是空的。我删除了 html 并再次填充了类别的下拉列表。子类别的下拉菜单未被禁用。我可以打开它并看到 Select... 选项,但其中没有值。
    • 请检查更新的答案..也许 formControlName 和 *ngFor 让 var 名称相同,这就是下拉列表未加载的原因,在禁用条件下 formGroup 也是 categoryForm。再试一次。
    • 我认为更改 ngFor 中的名称以避免与 formControlName 混淆是一个很好的建议。值再次出现。我喜欢您创造性地思考禁用下拉列表的解决方案。不幸的是,它仍然无法正常工作...下拉菜单被禁用,但即使我选择了一个类别,它仍然保持禁用状态。
    • 你是否在 formGroup 或 html 中添加了禁用条件?
    • 我已将禁用条件添加到 FormControl 并将 this.form.controls['subcategory'].enable() 添加到 selectChangeCategory 方法。这样可行!感谢您的意见。
    猜你喜欢
    • 2021-12-31
    • 2019-02-14
    • 2019-10-21
    • 2020-09-27
    • 1970-01-01
    • 2017-05-08
    • 1970-01-01
    • 1970-01-01
    • 2015-06-15
    相关资源
    最近更新 更多