首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法修复和实现级联下拉列表-使用所有选项(在父和子下拉列表中)

无法修复和实现级联下拉列表-使用所有选项(在父和子下拉列表中)
EN

Stack Overflow用户
提问于 2021-12-10 08:01:50
回答 1查看 186关注 0票数 1

在创建用户的同时,尝试实现基于角色的限制,这就是使用角材料选择多个带有“All”选项的级联选择选项。

stackblitz

但不能再往前走了,停留在第一步本身。这里的问题是,我无法找到并加载与使用childModule的父类相关的parentModuleId数据

代码语言:javascript
复制
this.loadChildModule = this.parentModuleList.find((parent: any) => parent.parentModuleName === event.target.value).parentModuleName;

场景1如果从父下拉列表中选择“All”选项,则应该加载相应的数据。

示例:

代码语言:javascript
复制
dropdown 1 // selecting All
parentModuleName: 'All'

dropdown 2 // load child of parent
    childModuleName: 'PM0 CH-1'
    childModuleName: 'PM0 CH-2'
    childModuleName: 'PM0 CH-3'

    childModuleName: 'PM1 CH-1'
    childModuleName: 'PM2 CH-2'
    childModuleName: 'PM3 CH-3'

    childModuleName: 'PM2 CH-1'
    childModuleName: 'PM2 CH-2'
    childModuleName: 'PM3 CH-3'

场景2如果从父下拉列表中选择单个选项,则应加载相应父类的子下拉列表

代码语言:javascript
复制
     example:

        dropdown 1 // selecting single item
        parentModuleName: 'Parent Module 0'
    
        dropdown 2 // load child of parent
            childModuleName: 'PM0 CH-1'
            childModuleName: 'PM0 CH-2'
            childModuleName: 'PM0 CH-3'

代码语言:javascript
复制
 <mat-form-field class="permission-module">
    <mat-select multiple ngDefaultControl formControlName="parentModule" placeholder="Select Package Files"
        [compareWith]="compareFn">
        <mat-option #selectAllParentModule (click)="selectAll()" [value]="0">
            All
        </mat-option>
        <mat-option *ngFor="let module of parentModuleList"
            [value]="{id:module.parenModuleId, name: module.parentModuleName}"
            (click)="selectSingleItem(selectAllModule.viewValue, $event)">
            {{module.parentModuleName}}
        </mat-option>
    </mat-select>
</mat-form-field>


<mat-form-field class="permission-module">
    <mat-select multiple ngDefaultControl formControlName="childModule" placeholder="Select Package Files"
        [compareWith]="compareFn">
        <mat-option #selectAllChildModule (click)="selectAll()" [value]="0">
            All
        </mat-option>
        <mat-option *ngFor="let module of childModuleList"
            [value]="{id:module.childModuleId, name: module.childModuleName}"
            (click)="selectSingleItem(selectAllModule.viewValue)">
            {{module.childModuleName}}
        </mat-option>
    </mat-select>
</mat-form-field>

TS

代码语言:javascript
复制
@ViewChild('selectAllParentModule') private selectAllParentModule: MatOption;
@ViewChild('selectAllChildModule') private selectAllChildModule: MatOption;

parentModuleList = [
    { parenModuleId: 0, parentModuleName: 'Parent Module 0' },
    { parenModuleId: 1, parentModuleName: 'Parent Module 1' },
    { parenModuleId: 2, parentModuleName: 'Parent Module 2' },
  ];

  childModuleList = [
    { childModuleId: 0, childModuleName: 'PM0 CH-1', parenModuleId: 0 },
    { childModuleId: 1, childModuleName: 'PM0 CH-2', parenModuleId: 0 },
    { childModuleId: 2, childModuleName: 'PM0 CH-3', parenModuleId: 0 },
    { childModuleId: 3, childModuleName: 'PM0 CH-4', parenModuleId: 0 },

    { childModuleId: 4, childModuleName: 'PM1 CH-1', parenModuleId: 1 },
    { childModuleId: 5, childModuleName: 'PM1 CH-2', parenModuleId: 1 },
    { childModuleId: 6, childModuleName: 'PM1 CH-3', parenModuleId: 1 },

    { childModuleId: 7, childModuleName: 'PM2 CH-1', parenModuleId: 2 },
    { childModuleId: 8, childModuleName: 'PM2 CH-2', parenModuleId: 2 },
    { childModuleId: 9, childModuleName: 'PM2 CH-3', parenModuleId: 3 },
    { childModuleId: 10, childModuleName: 'PM2 CH-4', parenModuleId: 3 },
  ];
  testForm: FormGroup;

  this.testForm = this.formBuilder.group({
    parentModule: [''],
    childModule: ['']
  });


  selectAll(): void {

    /*  select all for parent module */
    console.log('select all', this.rolesForm.controls.parentModule.value);
    if (this.selectAllParentModule.selected) {
      this.rolesForm.controls.parentModule.patchValue([
        ...this.parentModuleList.map((item) => {
          return {
            id: item.parenModuleId,
            name: item.parentModuleName
          };
        }), 0,
      ]);
    } else {
      this.rolesForm.controls.parentModule.patchValue([]);
    }

    /*  select all for child module */
    if (this.selectAllChildModule.selected) {
      this.rolesForm.controls.childModule.patchValue([
        ...this.childModuleList.map((item) => {
          return {
            id: item.childModuleId,
            name: item.childModuleName
          };
        }), 0,
      ]);
    } else {
      this.rolesForm.controls.childModule.patchValue([]);
    }

  }

  selectSingleItem(event): any {
    console.log('single select', this.rolesForm.controls.parentModule.value);

    // this.loadChildModule = this.parentModuleList.find((parent: any) => parent.parentModuleName === event.target.value).parentModuleName;

    /*  single select for parent module */
    if (this.selectAllParentModule.selected) {
      this.selectAllParentModule.deselect();
      return false;
    }
    if (this.rolesForm.controls.parentModule.value !== null &&
      (this.rolesForm.controls.parentModule.value.length === this.parentModuleList.length)) {
      this.selectAllParentModule.select();
    }

    /*  single select for child module */
    if (this.selectAllChildModule.selected) {
      this.selectAllChildModule.deselect();
      return false;
    }
    if (this.rolesForm.controls.childModle.value !== null &&
      (this.rolesForm.controls.childModle.value.length === this.childModuleList.length)) {
      this.selectAllChildModule.select();
    }


  }

  compareFn(obj1: any, obj2: any): boolean {
    return obj1 && obj2 ? obj1.moduleId === obj2.moduleId : obj1 === obj2;
  }

我不明白是怎么回事。

有人能帮我吗?在过去的1.5天里打我的头

更新

我的另一个简化版本,也不起作用。在checkUncheckAll()方法中迭代时获得未定义错误的id

my another try

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-14 19:16:20

fisrt步骤很简单--代码添加了一个类似于这个checkAll的所以。它只在select和选项之间添加一个div

代码语言:javascript
复制
  <mat-select ...>
      <div class="mat-option">
        <mat-checkbox ...>Select All</mat-checkbox>
      </div>
        <!--here the mat-options-->
      <mat-option...>
      <mat-option...>
    </div>

我们将使用两个辅助变量来控制这个"allChecked“。

代码语言:javascript
复制
  selectAllParent:boolean=false
  allSelected:boolean=false

此外,我选择只在FormControls中存储"id“(您正在存储对象,但这是不必要的(*),您可以简单地创建两个函数)

代码语言:javascript
复制
getparent(){
  const value=this.testForm.value.parentModule
  return this.parentModuleList.filter(x=>value.includes(x.parenModuleId))
}
getchild(){
  const value=this.testForm.value.childModule
  return this.childModuleList.filter(x=>value.includes(x.childModuleId)).map(x=>(
      {childModuleId:x.childModuleId,
        childModuleName:x.childModuleName
      }
    ))
}

并在需要时使用,例如,当您想要发送到某个服务或希望将-tipical存储在submit函数中时-

记住,多个matselect将值存储在数组中。

由于我们使用的是[(ngModel)],所以-the变量不属于need组--我们需要使用[ngModelOptions]={standalone:true}。对于每个函数,我们需要两个函数,一个用于“切换”选择,另一个在更改select时更改变量以显示选中与否。

第二个mat-select包含有parenModuleId的所有选项,包含在testForm.get('parentModule'):*ngIf="testForm.get('parentModule').value && testForm.get('parentModule').value.includes(child.parenModuleId))"的值中。

所以我们的.html变成了:

代码语言:javascript
复制
<form [formGroup]="testForm" (submit)="submit()">
<mat-form-field class="permission-module">
  <mat-select (selectionChange)="selectionParentChange()"
    multiple
    ngDefaultControl
    formControlName="parentModule"
    placeholder="Select parent module"
  >
    <div class="mat-option">
      <mat-checkbox
        [(ngModel)]="selectAllParent"
        [ngModelOptions]="{standalone: true}"
        (change)="toggleAllSelection($event.checked)"
        >Select All</mat-checkbox
      >
    </div>
    <mat-option
      *ngFor="let module of parentModuleList"
      [value]="module.parenModuleId"
    >
      {{module.parentModuleName}}
    </mat-option>
  </mat-select>
</mat-form-field>

<br />
<mat-form-field class="permission-module">
  <mat-select (selectionChange)="selectionChildChange()"
    multiple
    ngDefaultControl
    formControlName="childModule"
    placeholder="Select child modules"
  >
    <div class="mat-option">
      <mat-checkbox [(ngModel)]="allSelected"
        [ngModelOptions]="{standalone: true}"
        (change)="toggleAllChild($event.checked)"
        >Select All</mat-checkbox
      >
    </div>
    <ng-container *ngFor="let child of childModuleList">
        <mat-option *ngIf="testForm.get('parentModule').value && 
            testForm.get('parentModule').value.includes(child.parenModuleId)"
          [value]="child.childModuleId"
        >
          {{child.childModuleName}}
        </mat-option>
    </ng-container>
  </mat-select>
</mat-form-field>
<br/>
<button mat-raised-button color="primary">Submit</button>
</form>

辅助人员的职能如下:

代码语言:javascript
复制
  toggleAllSelection(checked: boolean) {
    this.testForm
      .get('parentModule')
      .setValue(
        checked ? this.parentModuleList.map((x) => x.parenModuleId) : null
      );
  }

  toggleAllChild(checked: boolean) {
    const parent = this.testForm.get('parentModule').value;
    const value = checked
      ? this.childModuleList
          .filter((x) => parent.includes(x.parenModuleId))
          .map((x) => x.childModuleId)
      : null;
    this.testForm.get('childModule').setValue(value);
  }

  selectionParentChange() {
    this.selectAllParent =
      this.testForm.get('parentModule').value.length ==
      this.parentModuleList.length;
  }

  selectionChildChange() {
    const parent = this.testForm.get('parentModule').value;
    const value = this.childModuleList.filter(
      (x) => parent.includes(x.parenModuleId)
    );
    this.allSelected =
      value.length == this.testForm.get('childModule').value.length;
  }

The stackblitz

Update我们需要检查,当我们选择了一个childrenModule并取消选择一个ChildrenParent时,是否删除这个值。因此,我们的函数selectionParentChange()变成了

代码语言:javascript
复制
  selectionParentChange() {
    this.selectAllParent = ...

      //Here: we need check if there some selected in childModule that it's not
      //in parent
      const parent = this.testForm.get('parentModule').value;
      const child=this.testForm.get('childModule').value;
      const value=child.filter(x=>{
           const child=this.childModuleList.find(c=>c.childModuleId==x)
           return child && parent.includes(child.parenModuleId)
      })
      if (child!=value)
        this.testForm.get('childModule').setValue(value)
  }

(*)您可以做一些更改相关的函数

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70301389

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档