我有两个 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()
从其他组件中产生?
你可以用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>
喏 one
和 two
作为输入,只是为了识别实例。
那么你的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);
}
}
在你的第一个标签页中,你可以在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.
}
这就是有一个共同的父体的好处,如果两个子体要交流,应该通过父体来进行,因为父体的任何数据变化作为输入,都会自动触发子体所需的变化。