首页 > 解决方案 > 材料选项卡错误中的 Angular 6 下拉菜单

问题描述

我有一个输入下拉组件,它在同一个应用程序的多个位置但在不同的选项卡中使用。

我面临的问题是,当我从选项卡 1 的下拉列表中选择一个值并使用该值完成 API 调用时,选项卡 2 中的相同组件也使用选项卡 1 中的选定值执行此操作。

当我在不同的选项卡中订阅相同的服务时,如何解决这个问题?

<ng-select 
  [items]="Groups"
  [virtualScroll]="true"
  bindLabel="bg_desc"
  bindValue="bg_desc"
  placeholder="Groups"
  [(ngModel)]="selectedGroup"
  [clearable]="false"
  (change)="selectGroups()">
  <ng-template 
    ng-notfound-tmp 
    let-searchTerm="searchTerm">
    <div class="ng-option disabled">
      No data found for "{{searchTerm}}"
    </div>
  </ng-template>
  <ng-template 
    ng-option-tmp 
    let-item="item" 
    let-search="searchTerm">
    <div 
      [ngOptionHighlight]="search" 
      class="text-uppercase">
      {{item.bg_desc}}
    </div>
  </ng-template>
</ng-select>

这是在我的组件中:

selectGroups() {
  this._data.changeGroup(this.selectedGroup);
}

这是我的服务:

changeGroup(bg: string) {
  this.changeGroupData.next(bg);
}

private changeGroupData = new BehaviorSubject<string>('');
currentChangeGroupData = this.changeGroupData.asObservable();

这是我的 stackbliz 示例:https ://stackblitz.com/edit/angular-1oucud

我希望在这些选项卡上单独调用。我应该创建三个具有不同名称的相同组件实例来实现这一点吗?

标签: javascripthtmlangularrxjsangular-material

解决方案


想想你的程序的架构?DropDownComponent 是否真的应该在模型更改后更新服务,或者更像是一个更具体的输入控件,并且任何绑定或应用程序逻辑都应该发生在它之外?

在我看来,第二种情况更合适,特别是如果您觉得需要重用它。您可以轻松地将 DropDownComponent 修改为具有 Input 和 Output 并将外部组件绑定到它。或者你可以加倍努力,让你的组件扩展 NgModelAccessor,这样你就可以在表单中正确使用它。

我将在下面给出一个更简单方法的示例。

  • DropDownComponent 将更改为完全独立的。它具有其他组件将绑定到的输入和输出。
  • AppComponent 有一个模型,模型的属性绑定到视图中的下拉实例。没有特别的原因,我也绑定到 change 事件只是为了向您展示会发生什么。这实际上是没有必要的,因为执行banana-in-a-box 语法会导致输出按照约定绑定 - 输出与输入具有相同的名称,并在末尾附加了更改。

下拉组件.ts

export class DropdownComponent  {
  colors = colors;

  @Input() selectedColor;
  @Output() selectedColorChange = new EventEmitter<string>();

  changeColor(e) {
    this.selectedColorChange.emit(this.selectedColor);
  }
}

应用组件.ts

declare type ColorType = { color: string, value: string };

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  colors: { first?: ColorType, second?: ColorType, third?: ColorType } = {};

  doSomething(colorKey: string) {
    console.log(`The color changed was ${colorKey} with a value of ${this.colors[colorKey].value}.`)
  }
}

应用组件.html

<mat-tab-group>
    <mat-tab label="First">
        <dropdown [(selectedColor)]="colors.first" (selectedColorChange)="doSomething('first')"></dropdown>
    <p>Selected Color is {{colors.first?.color}}</p>
    </mat-tab>
    <mat-tab label="Second">
        <dropdown [(selectedColor)]="colors.second" (selectedColorChange)="doSomething('second')"></dropdown>
    <p>Selected Color is {{colors.second?.color}}</p>
    </mat-tab>
    <mat-tab label="Third">
        <dropdown [(selectedColor)]="colors.third" (selectedColorChange)="doSomething('third')"></dropdown>
    <p>Selected Color is {{colors.third?.color}}</p>
    </mat-tab>
</mat-tab-group>

推荐阅读