【问题标题】:Customizing mat select to allow nested values in angular自定义垫选择以允许角度嵌套值
【发布时间】:2020-11-17 21:10:36
【问题描述】:

我正在自定义角度材料选择/自动完成以允许嵌套下拉菜单。

在这里,我想要一个包含许多孩子的父下拉列表。如果我展开特定的父下拉列表,则只有该下拉列表的子项应该展开或折叠。同理,checkbox事件应该在同一个场景中被选中。

我这里有一些错误

案例 1。

选择 A Parent 复选框,C Parent 复选框,展开两者,取消选择 C ​​的每个值,然后最后取消选择父 C 复选框将只给出 A 的第一个值。预期应该是 A 的所有值,因为父 A 已被选中。

还有一些额外的错误,希望如果案例 1 解决了,那将会得到解决。

任何帮助将不胜感激。

STACKBLITZ

HTML

<mat-form-field appearance="fill">
  <mat-label>Toppings</mat-label>
  <input type="text" matInput placeholder="Select Users" aria-label="Select Users" matInput [matAutocomplete]="auto" [formControl]="states">
  <mat-autocomplete #auto="matAutocomplete">

    <mat-select-trigger>
      {{states.value ? states.value[0] : ''}}
      <span *ngIf="states.value?.length > 1" class="example-additional-selection">
            (+{{states.value.length - 1}} {{states.value?.length === 2 ? 'other' : 'others'}})
          </span>
    </mat-select-trigger>

    <mat-optgroup *ngFor="let group of stateList">
      <div>
        <mat-checkbox [checked]="group.selected" (change)="toggleParent($event, group)" (click)="$event.stopPropagation()">
          {{group.letter}}
        </mat-checkbox>
        <button mat-button (click)="expandDocumentTypes(group)">
                <mat-icon>keyboard_arrow_down</mat-icon>
              </button>
      </div>
      <mat-option *ngFor="let name of group.names" [value]="name" [ngClass]="isExpandCategory[group.letter] ? 'list-show' : 'list-hide'">
        <mat-checkbox [checked]="group.checked" (change)="toggleSelection($event, name, group)" (click)="$event.stopPropagation()">
          {{name}}
        </mat-checkbox>
      </mat-option>
    </mat-optgroup>

  </mat-autocomplete>
</mat-form-field>

TS 代码:

export class SelectCustomTriggerExample {
  constructor(private _formBuilder: FormBuilder) {}

  isExpandCategory: boolean[] = [];
  toppingList: string[] = ['Extra cheese', 'Mushroom', 'Onion', 'Pepperoni', 'Sausage', 'Tomato'];
  stateRecord: any = [];
  states = new FormControl();

  expandDocumentTypes(group: any) {
    console.log("expanding dropdown", group);
    this.isExpandCategory[group.letter] = !this.isExpandCategory[group.letter];
  }

  toggleSelection(event: any, name: any, group: any) {
    console.log("toggleSelection", name, event.checked, group);
    if (event.checked) {
      console.log("stastateRecordtelist", this.stateRecord);
      this.stateRecord.push(name);
      this.states.setValue(this.stateRecord);
      console.log("toggleselection ", this.states.value);
    } else {
      console.log("else toggleselection", name, group, this.states.value);
      this.states.setValue(this.states.value.filter((x: any) => x !== name));
      console.log("after filter ", this.states.value);
    }
  }

  toggleParent(event: any, group: any) {
    group.checked = event.checked;
    console.log("event", event.checked, "group", group, "states value", this.states.value);
    let states = this.states.value;
    states = states ? states : [];
    if (event.checked) {
      states.push(...group.names)
    } else {
      console.log("else", states);
      group.names.forEach((x: string) => states.splice(states.indexOf(x), 1));
    }
    this.states.setValue(states);
    console.log("statesvalue", this.states.value);
    if (!event.checked) {
      this.states.setValue(this.states.value.filter((x: any) => !x.includes(group.names)))
    }
    console.log("final statesvalue", this.states.value);
  }

  stateList: StateGroup[] = [{
    letter: 'A',
    checked: false,
    names: ['Alabama', 'Alaska', 'Arizona', 'Arkansas']
  }, {
    letter: 'C',
    checked: false,
    names: ['California', 'Colorado', 'Connecticut']
  }, {
    letter: 'D',
    checked: false,
    names: ['Delaware']
  }, {
    letter: 'F',
    checked: false,
    names: ['Florida']
  }, {
    letter: 'G',
    checked: false,
    names: ['Georgia']
  }, {
    letter: 'H',
    checked: false,
    names: ['Hawaii']
  }, {
    letter: 'I',
    checked: false,
    names: ['Idaho', 'Illinois', 'Indiana', 'Iowa']
  }, {
    letter: 'K',
    checked: false,
    names: ['Kansas', 'Kentucky']
  }, {
    letter: 'L',
    checked: false,
    names: ['Louisiana']
  }, {
    letter: 'M',
    checked: false,
    names: ['Maine', 'Maryland', 'Massachusetts', 'Michigan',
      'Minnesota', 'Mississippi', 'Missouri', 'Montana'
    ]
  }, {
    letter: 'N',
    checked: false,
    names: ['Nebraska', 'Nevada', 'New Hampshire', 'New Jersey',
      'New Mexico', 'New York', 'North Carolina', 'North Dakota'
    ]
  }, {
    letter: 'O',
    checked: false,
    names: ['Ohio', 'Oklahoma', 'Oregon']
  }, {
    letter: 'P',
    checked: false,
    names: ['Pennsylvania']
  }, {
    letter: 'R',
    checked: false,
    names: ['Rhode Island']
  }, {
    letter: 'S',
    checked: false,
    names: ['South Carolina', 'South Dakota']
  }, {
    letter: 'T',
    checked: false,
    names: ['Tennessee', 'Texas']
  }, {
    letter: 'U',
    checked: false,
    names: ['Utah']
  }, {
    letter: 'V',
    checked: false,
    names: ['Vermont', 'Virginia']
  }, {
    letter: 'W',
    checked: false,
    names: ['Washington', 'West Virginia', 'Wisconsin', 'Wyoming']
  }];
}

输出应如下所示。

【问题讨论】:

    标签: javascript html css angular angular-material


    【解决方案1】:

    在这里找到你的答案::https://stackblitz.com/edit/angular-f5mizr-n7gmx5

    这将通过您的测试用例 1。 我又发现了一个案例

    多次选择和取消选择任何子元素将重复重复选定的值。

    这种情况在我给定的堆栈闪电战中也得到了解决。

    【讨论】:

    • 谢谢,但随机测试时有些情况会失败。
    • 请让我知道它失败的情况。
    • 是这种情况...同时选择 A 和 C 父复选框。取消选择 A 中的任何值。取消选择 C ​​中的任何值。现在取消选择父 C 下拉菜单。 ..选择父C下拉列表..取消选择A下拉列表中的任何其他值..选择A下拉列表中的任何其他值..
    • 请您现在验证一下。
    • 请在您之前的帖子中也批准我之前的回答。 stackoverflow.com/questions/63053819/…
    【解决方案2】:

    也许这条评论不是你的确切答案,但可以让你知道如何解决它。

    基本上,您的问题是您正在组合不同的组件,例如 mat-autocomplete 与 mat-select 与 mat-optgroup 的多个选择。这可能非常危险,并且会给您带来很多麻烦。另外不建议这样做。

    另外你有一个formControl,它是: [formControl]="states" 在输入里面,没问题,这就是你得到所有用逗号分隔的字符串的原因,这是因为formControl的值。

    你可以看一下formControls的文档: https://angular.io/guide/reactive-forms

    所以我强烈建议将 formControl 更改为 mat-select。 (我知道您将使用子数组存储所有数组的值。)

    您需要将输入编辑为类似的内容:

    <mat-form-field appearance="fill">
      <mat-label>Toppings</mat-label>
        <!-- <input type="text" matInput placeholder="States Group" formControlName="stateGroup" required [matAutocomplete]="autoGroup">
         <mat-autocomplete #autoGroup="matAutocomplete"> -->
               <input type="text" matInput placeholder="" aria-label="" matInput [matAutocomplete]="auto" [formControl]="" style="">
               <span *ngIf="states.value">
               {{states.value ? states.value[0] : ''}}
               (+{{states.value.length - 1}} {{states.value?.length === 2 ? 'other' : 'others'}})
               </span>
    

    这里是堆栈闪电战: https://stackblitz.com/edit/angular-f5mizr-wefuik

    【讨论】:

      猜你喜欢
      • 2020-11-19
      • 1970-01-01
      • 2021-09-07
      • 2021-10-15
      • 1970-01-01
      • 2010-10-02
      • 1970-01-01
      • 2020-10-18
      • 1970-01-01
      相关资源
      最近更新 更多