简体   繁体   English

材质标签中的Angular 6下拉菜单错误

[英]Angular 6 Dropdown inside Material Tabs Error

I have an input drop-down component which is used in multiple places in the same app but in different tabs. 我有一个输入下拉组件,可在同一应用程序的多个位置但在不同的选项卡中使用。

The issue I am facing is when I select a value from the drop-down in Tab 1 and an API call is done with the value, the same component in Tab 2 also does that with the selected value in Tab1. 我面临的问题是,当我从选项卡1的下拉列表中选择一个值并且用该值完成API调用时,选项卡2中的同一组件也使用选项卡1中的所选值来完成该操作。

How do I fix this as I am subscribing to the same service in the different tabs? 在不同标签中订阅相同服务时,该如何解决?

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

This is in my component: 这是在我的组件中:

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

This is my service: 这是我的服务:

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

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

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

I want individual calls on these tabs. 我想在这些标签上单独打电话。 Should I create three instances of same component with different names to achieve this? 我是否应该使用不同的名称创建相同组件的三个实例以实现此目的?

Think about the architecture of your program? 考虑一下程序的体系结构吗? Should DropDownComponent really be updating a service after a model change or is more like a more specific input control and any binding or application logic should occur outside of it? DropDownComponent应该在模型更改后真正更新服务,还是更像是更具体的输入控件,并且任何绑定或应用程序逻辑都应该发生在它之外?

It seems to me that the second case is more appropriate, especially if you feel the need to reuse it. 在我看来,第二种情况更合适,尤其是在您需要重用它的情况下。 You can easily modify the DropDownComponent to have an Input and Output and have the outer component bind to it. 您可以轻松地修改DropDownComponent使其具有输入和输出,并使外部组件绑定到该输入和输出。 Or you can go the extra mile and have your component extend NgModelAccessor, so you can use it properly in forms. 或者,您可以加倍努力,让您的组件扩展NgModelAccessor,以便可以在表单中正确使用它。

I'll give an example of the simpler approach below. 我将在下面举例说明更简单的方法。

  • DropDownComponent is to changed to be completely standalone. DropDownComponent将更改为完全独立的。 It has an input and output that other components will bind to. 它具有其他组件将绑定到的输入和输出。
  • AppComponent has a model and the properties of the model are bound to instances of dropdown in the view. AppComponent有一个模型,模型的属性绑定到视图中下拉列表的实例。 For no particular reason I also bound to the change event just to show you what happens. 出于特殊原因,我也绑定了change事件,只是为了向您展示发生了什么。 It really isn't necessary as doing the banana-in-a-box syntax will cause the Output to be bound to by convention - the Output having the same name as the input with Change appended to the end. 确实没有必要,因为执行框内香蕉式语法会使输出受约定约束-输出与输入名称相同,并在末尾附加Change。

DropDownComponent.ts DropDownComponent.ts

export class DropdownComponent  {
  colors = colors;

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

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

AppComponent.ts AppComponent.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}.`)
  }
}

AppComponent.html AppComponent.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>

You just need to use output to communicate to outer component. 您只需要使用输出与外部组件进行通信即可。 Thats it 而已

https://stackblitz.com/edit/angular-1oucud https://stackblitz.com/edit/angular-1oucud

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM