在两个同级组件之间交换引用

问题描述 投票:0回答:1

我有两个 custom-component由一个共同的父代产生的,具有不同数据的两个标签页上的 "S"。mat-tab-group.

<mat-tab-group>
  <mat-tab label="TAB1">
    <ng-template matTabContent>
      <custom-component [data]="tab1data"></custom-component>
    </ng-template>
  </mat-tab>
  <mat-tab label="TAB2">
    <ng-template matTabContent>
      <custom-component [data]="tab2data"></custom-component>
    </ng-template>
  </mat-tab>
</mat-tab-group>

data 是一个设置器,用于设置内部的 _data 并将其包裹在 MatTableDataSource:

@Input()
set data(val: Data[]) {
    this._data = val;
    this.loadData();
}

loadData(): void {
    this.dataSource = new MatTableDataSource<Data>(this._data);
    this.dataSource.sort = this.sort;
}

我有一种情况,第一个标签页上的组件动作应该影响到另一个标签页上的数据。是否有任何方法可以传递组件的引用,以便我可以改变 _data 并称 loadData() 从其他组件中产生?

angular typescript angular-material angular-components
1个回答
1
投票

你可以用Rxjs的observables来实现这一点。

下面是stackblitz的例子,说明如何在两个组件之间进行通信。https:/stackblitz.comeditangular-ivy-myr2kh。

my-service.service.ts

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';

@Injectable()
export class MyServiceService {
  private dataChangeObservable = new Subject<any>();
    dataChangeStream = this.dataChangeObservable.asObservable();

  constructor() { }

  emitDataChange() {
    this.dataChangeObservable.next();
  }
}

ComponentOne.component.ts

onclickDiv() {
    this.myService.emitDataChange(); // Here you are triggering for change
}

ComponentTwo.component.ts

ngOnInit() {
    this.dataChangeSubscription$ = this.myService.dataChangeStream.subscribe(() => {
       this.count++; // Here you will get notified/listener of change
    })
 }

更新

如果你有相同的组件实例,那么你必须传递一些值来决定哪个实例应该被更新。

喜欢

https:/stackblitz.comeditangular-ivy-4pznor。

你的母版html

<app-componentone [name]="'one'"></app-componentone>
<app-componentone [name]="'two'"></app-componentone>

onetwo 作为输入,只是为了识别实例。

那么你的ts

import { Component, OnInit, Input } from '@angular/core';
import { MyServiceService } from '../my-service.service';

@Component({
   selector: 'app-componentone',
   templateUrl: './componentone.component.html',
   styleUrls: ['./componentone.component.css']
})
export class ComponentoneComponent implements OnInit {
  @Input() name; // it will have instance name
  count = 0;
  constructor(
     private myService: MyServiceService
  ) { }

  ngOnInit() {
    this.myService.dataChangeStream.subscribe((value) => { // here we will get to notify which instance should get updated
      if (this.name !== value) { // Here we checking for instance name for updating, if same component instance don't do anything else update
         this.count++;
      }
    })
  }

  onclickDiv() {
    // Here I am passing parameter, so if click is triggered from instance one, we have to update other instances, so passing parameter 'one' i.e. name, to avoid updating same component instance

    this.myService.emitDataChange(this.name);
  }
}

0
投票

在你的第一个标签页中,你可以在dataChange时向它的父组件发出一个输出。

在自定义组件中,有一个输出,如

@Output() public dataChange = new EventEmitter();

当数据发生变化时,发出这样的事件:-。

this.dataChange.emit('changed data');

在这个组件的选择器所在的父组件中,将选择器改为:-。

HTML :-

<custom-component [data]="tab1data" (dataChange)="modifyDataTab2($event)"></custom-component>

TS :-

modifyDataTab2(firstTabData) {
   this.tab2Data = firstTabData;
   // or you can make other changes.
} 

现在因为tab2已经有tab2Data作为输入,你的loadData()将自动被调用。

如果你想在tab2上修改tab1的数据,不需要再次修改tab组件,每个实例都会有自己的输出。

HTML:-

<custom-component [data]="tab2data" (dataChange)="modifyDataTab1($event)"></custom-component>

TS:-

modifyDataTab1(secondTabData) {
   this.tab1Data = secondTabData;
   // or you can make other changes.
} 

这就是有一个共同的父体的好处,如果两个子体要交流,应该通过父体来进行,因为父体的任何数据变化作为输入,都会自动触发子体所需的变化。

© www.soinside.com 2019 - 2024. All rights reserved.