观察数据从父级到子级的变化,反之亦然 [英] Observing data changes from parent to child or vice versa
问题描述
我有一个我订阅的服务,比如说一个组件.我在A组件中有一种方法,每隔5分钟订阅一次该服务.
I have a service that I subscribe in the, let's say A component. I have a method in the A component that subscribes to the service every 5 minutes.
A组件有一个子组件,比方说B组件.我使用@Input()并获取B组件中的数据.此外,B组件具有子C组件.C组件显示该消息.我需要获取每隔5分钟订阅该服务后发生的数据更改,并将它们放在B组件中,该B组件将调用C组件.
An A component has a child component let's say B component. I use @Input() and get the data in B component. Also, a B component has a child C component. C component displays the message. I need to get the data changes that happens after subscribing to the service every 5 minutes and get them in the B component which will invoke the C component.
我需要在A组件中进行服务调用,因为那里也需要完成一些逻辑.如果服务调用发生在B组件中,并且我想知道如何观察子组件中的数据更改.
I need the service call to happen in the A component since, there's some logic needs to be done there too. If the service call happens in B component and I'd like to know how to observe data changes in child.
-
我尝试使用计时器,管道和switchMap来避免使用间隔,并使服务订阅每5分钟发生一次,并从A和B组件中调用该服务.
I tried using timer, pipe and switchMap to avoid using an interval and make the service subscription happen every 5 minutes and call the service from both A and B components.
此外,我尝试使用ViewChild()并在A组件中调用了B组件的ngOnInit,但这给了我一个错误:
Also, I tried using ViewChild() and called the ngOnInit of B component in A component but that gives me an error :
无法在SafeSubscriber处读取undefined的属性ngOnInit()...
cannot read property ngOnInit() of undefined at SafeSubscriber...
,但仍会在订阅时调用.
but it would still invoke at subscription.
-
继续第二点,如果我将C的ngOnInit调用为B ...,我会得到一个跨源策略错误.
continuing the 2nd point, if I call the ngOnInit of C to B... I would get a cross origin policy error.
我尝试以与A类似的方式在B组件中订阅服务,并且尝试将数据更改输出到A.但是,这似乎也不起作用.如果这是一个更好的主意,那么真的很想知道如何观察孩子的数据变化.
I tried subscribing the service in B component in a similar manner as A. and I tried to output the data changes to A. But, that doesn't seem to work either. If this is a better idea, would really like to know how to observe data changes from child.
组件:
ngOnInit() {
this.method();
this.interval = setInterval(()=>this.method(), 300000);
}
method() {
// service subscription
}
ngOnDestroy(){
clearInterval(this.interval);
}
Acomponent.html:
Acomponent.html:
<Bcomponent [data]='data'></BComponent>
BComponent:
BComponent:
@Input() data: any;
ngOnInit() {
this.method();
}
method() {
// method to be executed
}
BComponent.html:
BComponent.html:
<Ccomponent [datafromBmethod]='datafromBmethod'></Ccomponent>
Ccomponent:
Ccomponent:
@input() datafromBmethod: any;
ngOnInit() {
// display message logic
}
推荐答案
Karan,事情不是您所要求的.不必每次都提供服务.假设您有一个带有DataData方法的服务DataService.如果要每隔x秒获取一次此数据,则可以使用switchMap将onInit设置为计时器.为了取消怀疑,我使用takeWhile,但变量为true时,ngOnDestroy中的结果为false
Karan, the thing are not as you asking. Yo need'nt susbcribe to a service each time. Imagine you has a service DataService with a method getData. If you want to get this data each x seconds you can susbcribe in onInit to a timer using switchMap. To unsusbcribe I use takeWhile a variable was true, that in ngOnDestroy becomes false
timer(0,1000).pipe(takeWhile(()=>this.alive),
switchMap(()=>{
return this.dataService.getData()
})).subscribe(res=>{
this.value=res;
})
变量"this.value"每1个secons更改一次.您可以使用输入将该变量传递给b,也可以使用输入将变量从b传递给c.
the variable "this.value" change each 1 secons. You can pass this variable to b using input, and pass the variable from b to c using input too.
注意:我使用运算符"of"返回一个可观察的对象,通常该服务变为
NOTE: I use the operator "of" to return an observable, in general the service becomes like
getData()
{
return this.httpClient.get(.....)
}
您还可以在服务中添加一个主题,在应用程序组件的计时器中发送一条消息并按可观察的方式订阅该主题
You can also has a Subject in your service, in timer of app-component send a message and subscribe to the subject as observable is c
您的组件A变得像
timer(0,1000).pipe(takeWhile(()=>this.alive),
switchMap(()=>{
return this.dataService.getData()
})).subscribe(res=>{
this.dataService.putMessage("I send "+res);
})
在组件c中,您拥有
this.dataService.dataObservable.subscribe(res=>{
this.message=res;
})
这篇关于观察数据从父级到子级的变化,反之亦然的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!