Angular 11-如何使用服务可观察到的数据
我的目标是将可观察到的从父组件传递给其子女,我无法使用“输入”和“输出”来做到这一点,因为包含子组件的组件本身就是用于用户接口的内部库的组成部分。
我有一个父亲组成部分:home.com.ponente.ts
在父级组件中,我调用oninit事件中的服务,然后将其响应存储在“主题”类型中以存储可观察的可观察到,以便我可以订阅儿童组件:
this.tabs = [
{id: 'reportsTab', label: 'Files', routerLink: '/reports/1'},
{id: 'processesTab', label: 'Tasks', routerLink: '/processes/1'},
];
ngOnInit(): void {
this.processesService.getInfo(id).subscribe(response => {
this.processesService.data.next(response);
});
}
这是proceses.service.ts服务:
export class ProcessesService {
data: Subject<RestResponse<ScheduleDataOutput[]>> = new Subject();
public getInfo(id: number): Observable<RestResponse<ScheduleDataOutput[]>> {
let serviceName = "/processes/info";
if (id) {
serviceName = serviceName + '?id=' + id;
}
return this.service.get<any>(serviceName)
.pipe(
tap(_ => this.log('fetched info')),
catchError(this.handleError<ScheduleDataOutput[]>('getInfo', []))
);
}
getData() {
return this.data.asObservable()
}
}
在home.component.html文件中,我们具有内部组件,它是使用经典选项卡的UI组件,每个选项卡都是子组件:
<app-menu-tab [tabs]="tabs"></app-menu-tab>
当,当我单击一个选项卡时, ,它具有一个加载子组件的路由器链接,我想通过在家庭成分中获得的响应(可观察到),订阅儿童组件中可观察到的响应,并随着该响应在子部件中绘制datagrid。
当我正确加载子分量组件中获得的响应的屏幕时,如果我正确加载了屏幕的屏幕,则问题是,当我单击选项卡时,datragrids未加载。
这是“报告站”选项卡组件的OnInit事件:
ngOnInit(): void {
// Here I access
this.reportsSubscription = this.processesService.getData().subscribe(response => {
// But within the subscription I do not access.
console.log("response: ", response)
});
}
问题是我无法在订阅中访问,在某个时候,可观察到的可观察到的情况是错误的,当我单击“ processEstab”选项卡的子组件时也会发生同样的情况。标签,我无法访问可观察到的订阅:
ngOnInit(): void {
// Here I access
this.tasksSubscription = this.processesService.getData().subscribe(response => {
// But within the subscription I do not access.
console.log("response: ", response)
});
}
问题是什么?如果我将可观察到的孩子的组件传递给了孩子,但是当我重新加载页面时,它只能工作并加载数据杂志,但是如果我单击“选项卡”,我会将失去在homecorment中获得的响应,并且数据杂志出现为空。
My goal is to pass an observable from a parent component to its children, I can't do it using "Input" and "Output" because the component that contains the child components is itself a component of an internal library for user interfaces.
I have a father component: home.componente.ts
In the parent component HomeComponent, I call a service from the OnInit event and store its response in a "Subject" type to store an observable so I can subscribe to child components:
this.tabs = [
{id: 'reportsTab', label: 'Files', routerLink: '/reports/1'},
{id: 'processesTab', label: 'Tasks', routerLink: '/processes/1'},
];
ngOnInit(): void {
this.processesService.getInfo(id).subscribe(response => {
this.processesService.data.next(response);
});
}
This is the processes.service.ts service:
export class ProcessesService {
data: Subject<RestResponse<ScheduleDataOutput[]>> = new Subject();
public getInfo(id: number): Observable<RestResponse<ScheduleDataOutput[]>> {
let serviceName = "/processes/info";
if (id) {
serviceName = serviceName + '?id=' + id;
}
return this.service.get<any>(serviceName)
.pipe(
tap(_ => this.log('fetched info')),
catchError(this.handleError<ScheduleDataOutput[]>('getInfo', []))
);
}
getData() {
return this.data.asObservable()
}
}
In the home.component.html file, we have the inner component, it's a UI component for to use the classic sistem of tabs, and each tab is a child component:
<app-menu-tab [tabs]="tabs"></app-menu-tab>
When, I click on a tab, it has a routerLink that loads the child components, to which I want to pass the response (observable) obtained in HomeComponent, subscribe to the observable in the child component and with that response paint a Datagrid in the child components.
When refreshing the screen if I correctly load the Datagrids of the childs components with the response obtained in the HomeComponent component, the problem is that when I click on the tabs the Datragrids are not loaded.
This is the OnInit event of the "reportsTab" tab component:
ngOnInit(): void {
// Here I access
this.reportsSubscription = this.processesService.getData().subscribe(response => {
// But within the subscription I do not access.
console.log("response: ", response)
});
}
The issue is that I cannot access within the subscription, at some point the observable was misconfigured, the same happens with the child component of the "processesTab" tab, when I click on the tab, I cannot access the subscription of the observable:
ngOnInit(): void {
// Here I access
this.tasksSubscription = this.processesService.getData().subscribe(response => {
// But within the subscription I do not access.
console.log("response: ", response)
});
}
What could be the problem? If I am passing the observable to the childs components, but it only works and loads the Datagrids, when I reload the page, but if I click on the tabs, I lose the response obtained in the HomeComponent and the Datagrids appear empty.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您需要使用
cistionubject
(或replaysubject
,如果您不需要初始值),而不是普通的主题
。capenionSubject
将发出新订户的最新值,而主题
不会做到这一点。为了使订户从主题中获取数据,需要在发出数据之前对其进行订阅。
简而言之,数据属性应该看起来像这样:
或者,如果初始值是多余的,则可以使用
replosaySubject
而选择:You need to use a
BehaviorSubject
(or aReplaySubject
if you don't need an initial value), not a plainSubject
.The
BehaviorSubject
will emit the latest value to new subscribers, whileSubject
won't do that.In order for a subscriber to get the data emitted from a subject, it needs to be subscribed to it prior to the data being emitted.
In short, the data property should look like this:
Or, if the initial value is superfluous, you could go with a
ReplaySubject
instead: