我有三个组件bookcomponent,pagecomponent和linecomponent。 bookcomponent和linecomponent 有孙子/父母关系。我可以与服务共享数据,linecomponent可以订阅 但是问题是订阅是以linecomponent的ngOnInit()方法编写的。 linecomponent循环 在pagecomponent中使用* ngFor,因此我得到多个订阅(订阅乘以 页面中的行数)
@Input和@Output不可能,因为组件之间没有直接关系。
bookcomponent.ts
export class BookComponent implements OnInit {
constructor(private custStore: CustomerStoreService) { }
}
bookcomponent.html
<page *ngFor="let cust of this.custStore.custs$|async [billcust]=cust></page>
custstoreservice.ts
readonly custs$ = this._custs.asObservable();
pagecomponent.ts
selector: 'page',
template:`
<span>{{billcust.name}}</span>
<sub>{{billcust.mobile}}</sub>
<line-figure [cust]=billcust "></line-figure>`
export class PageComponent implements OnInit, AfterViewInit, OnChanges{
@Input()
billcust: Object
}
linecomponent.ts
selector: 'line-figure'
export class LineComponent implements OnInit, AfterViewInit, OnChanges {
@Input() cust: ICustomer;
ngOnInit() {
/*
this.lineStoreService.ledgersumm$.subscribe(
o=>{console.log(o)
this.metric = o
} //----->>> subscribe is multiplying with number of lines
)*/
if (this.cust.custid) {
this.lineStoreService.ledgersummary(this.cust.custid)
// third party service to populate data for each line number
.then(obj => {
this.metric = obj;
console.log(obj);
});
}
}
refresh(){
this.ngOnInit()
}
}
由于linedata是根据bookcomponent和pagecomponent的行号进行更新的,因此没有直接关系。带有数据,因此无法使用onchange钩子
更新
BookComponent
是主持人,它实例化custstoreservice
(它是cust数组的状态管理器)在构造函数中提供cust对象,从@Input
到PageComponent
(BookComponent
的直接子对象)。
PageComponent
在图像的标题细蓝框中显示cust.name
,并将cust
对象传递给它的子对象LineComponent
,然后为该客户设置metric
对象通过图片lineStoreService
中粉红色框中的LineComponent
。
到目前为止,一切都很好。现在,我希望LineComponent
跟踪cust.id
的数据更改。 LineComponent
中有一些更改metric
的按钮想要一种跟踪此更改的方法。
我可以通过单击metric
中的刷新按钮来更新LineComponent
,但这是手动的。想要一些自动方式。
我可以自由地更改方法,更关注任何示例引用的功能都将有所帮助。
linestoreservice.ts
export class LineStoreService implements OnDestroy{
constructor(private lineService: LineService) { }
private readonly _ledgersumm = new BehaviorSubject<ILedgSummary>(null);
readonly ledgersumm$ = this._ledgersumm.asObservable();
get ledgersummC(): ILedgSummary {
return this._ledgersumm.getValue();
}
set ledgersummC(val: ILedgSummary) {
this._ledgersumm.next(val);
}
async ledgersummary(cid){
this.ledgersummC = await this.lineService.ledgersummbydate(cid)
return this.ledgersummC
}
async add(data){
return await this.lineService.add(data).then(result=>{
if(result){
this.ledgersummary(data.custid)
}
return result
}).catch(function (error) {
console.error ("Oops: " + error);
})
}
}