根据输入操作可重用组件

时间:2019-09-19 06:25:11

标签: javascript angular

我创建了一个可重用的组件,并在组件内部使用了两次。但是我需要两个按钮,它们可以分别操作组件。

就我而言,component1的按钮不应同时更新组件的两个实例。

我认为我在设计上做错了什么,但是任何建议都会对我有所帮助。

Stackblitz

可重用组件:-

    import { Component, OnInit,Input } from '@angular/core';
import { AppService } from '../app.service';
@Component({
  selector: 'app-reusable',
  templateUrl: './reusable.component.html',
  styleUrls: ['./reusable.component.css']
})
export class ReusableComponent implements OnInit {
  @Input() items:any;
  constructor(
    private service:AppService
  ) { }

  ngOnInit() {
    this.service.addFruit.subscribe(()=>{
      this.items.unshift({fruit:'Blackberry'});
    });
  }


}

用法:-

<button type="button" (click)="Add()">Add Component1</button>
<app-reusable [items]="fruitList1"></app-reusable>
<hr/>
<button type="button" (click)="Add()">Add Component2</button>
<app-reusable [items]="fruitList2"></app-reusable>

我只想一次更新一个可重用组件实例。 实例1或2。

4 个答案:

答案 0 :(得分:1)

您必须让服务知道您正在调用哪个组件。

尝试在演示中所做的更改。

app.component.html

<button type="button" (click)="Add(1)">Add Component1</button>

<app-reusable [items]="fruitList1" [componentNumber]="1"></app-reusable>

app.component.ts:

Add(componentNumber:number){
   this.service.addFruit.next(componentNumber);
}

reusable.component.ts:

@Input() componentNumber: number;

 ngOnInit() {
    this.service.addFruit.subscribe((x) => {
      if (x == this.componentNumber)
        this.items.unshift({ fruit: 'Blackberry' });
    });
  }

Working Stackbiltz

答案 1 :(得分:1)

更简洁的方法是简单地传递组件实例并调用相关方法,因此在可重用组件中创建一个方法,例如

addFruit(){
    this.items.unshift({fruit:'Blackberry'});
  }

修改您的add方法以将组件作为实例并调用此方法

 Add(instance:ReusableComponent){
    instance.addFruit();
  }

然后添加哈希以分隔每个实例并在方法中传递实例

 <button type="button" (click)="Add(instance1)">Add Component1</button>
<app-reusable [items]="fruitList1" #instance1></app-reusable>

Working demo

答案 2 :(得分:1)

每个ReusableComponent实例都订阅了Subject addFruit。单击按钮将更新主题值,这将触发所有订阅。

为避免这种情况,您将需要在订阅中添加一个过滤器,该过滤器会在执行this.service.addFruit.next();时添加一些值,从而忽略其他组件的值。您可以使用RXJS过滤器运算符进行过滤。 https://rxjs-dev.firebaseapp.com/api/operators/filter

另一个想法是为服务中的每个组件创建订阅,并将其保存在服务中的某些地图/对象中。当组件从服务请求订阅时,它将添加一个映射条目,即subjectId:new Subject()。您将返回该新主题以供组件订阅。与其直接执行next(),不如调用服务方法addNewFruit(subjectId:string,newFruit:string):void。 地图将是:

{
     'firstId': Subject,
     'secondId': Subject,
}

这种情况下最简单的想法是使用ViewChild并从父组件中调用方法addFruit。

答案 3 :(得分:0)

代替在可重用组件中订阅APP服务,应单击按钮,然后修改提供给组件的输入。如果您一次更新fruitList1或fruitList2,则不会更新该组件的另一个实例。