无法在 Angular 中的订阅内设置服务数据
Cannot set service data inside subscribe in Angular
我想在订阅方法中设置共享服务数据我的页面结构是
我必须从 home component
和 header component
中的一个组件 app.component
访问数据集。
this.sharedService.setData({title: this.title, logo: this.logo});
app.component.ts
setData(): void {
this.http.get(this.baseUrl+'api/content').subscribe(result => {
this.title=result['response'].title;
this.logo=result['response'].logo;
this.sharedService.setData({title: this.title, logo: this.logo});
});
}
但在这种情况下,当我在任何其他组件中访问它时设置服务数据,获取 title
和 logo
的空白数据但是当我传递静态数据时(不是订阅方法 API调用)然后它的值被传递给其他组件。
服务:
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { environment } from '../../environments/environment';
import { BehaviorSubject } from 'rxjs';
export interface SharedData {
title: string;
logo: string;
}
@Injectable({
providedIn: 'root'
})
export class SharedService {
private sharedData$ = new BehaviorSubject<SharedData>({title: '', logo: ''});
sharedData = this.sharedData$.asObservable();
constructor() { }
setData(data: SharedData): void {
this.sharedData$.next(data);
}
}
任何解决方案谢谢
BehaviourSubject
必须用起始值初始化。
在您的代码中,您从 title
和 logo
的空字符串开始,因此,如果您在调用 setData
之前在任何组件中订阅它(这使得 get 调用),新订阅者将获得初始的“空”值。
您可以尝试将其替换为ReplaySubject(1)
。然后,如果 setData
在订阅时尚未被调用,您可以应用任何您需要的逻辑来进行该调用。
如果您想继续使用 BehaviourSubject
,您可以将初始值设置为 null
并在您的订阅者中进行相应操作。
** 编辑 **
在玩了一下另一个用户设置的 Stackblitz 之后(并且缺少您的 API 返回的正确响应对象),我认为问题与主题或订阅无关,但是可能位于您的这两行代码中:
this.title=result['response'].title;
this.logo=result['response'].logo;
您可以尝试在 app.component.ts
中进行以下更改:
setData(): void {
this.http.get(this.baseUrl+'api/content').subscribe(result => {
/* Original code
this.title=result['response'].title;
this.logo=result['response'].logo;
*/
/* New code */
this.title=result.title;
this.logo=result.logo;
this.sharedService.setData({title: this.title, logo: this.logo});
});
}
注意我只是删除了 result
对象的 ['response']
属性,因为我 几乎 肯定没有这样的 属性 在 API 返回到您的应用程序中。但是如果没有看到您 API 的 实际 响应,很难给出正确的答案。
除非响应是一个数组,但在这种情况下你很可能需要指向一个索引位置。同样,如果您可以将 API 的实际回复粘贴到此处,那将非常有帮助,以便我们更好地指导您。
我想在订阅方法中设置共享服务数据我的页面结构是
我必须从 home component
和 header component
中的一个组件 app.component
访问数据集。
this.sharedService.setData({title: this.title, logo: this.logo});
app.component.ts
setData(): void {
this.http.get(this.baseUrl+'api/content').subscribe(result => {
this.title=result['response'].title;
this.logo=result['response'].logo;
this.sharedService.setData({title: this.title, logo: this.logo});
});
}
但在这种情况下,当我在任何其他组件中访问它时设置服务数据,获取 title
和 logo
的空白数据但是当我传递静态数据时(不是订阅方法 API调用)然后它的值被传递给其他组件。
服务:
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { environment } from '../../environments/environment';
import { BehaviorSubject } from 'rxjs';
export interface SharedData {
title: string;
logo: string;
}
@Injectable({
providedIn: 'root'
})
export class SharedService {
private sharedData$ = new BehaviorSubject<SharedData>({title: '', logo: ''});
sharedData = this.sharedData$.asObservable();
constructor() { }
setData(data: SharedData): void {
this.sharedData$.next(data);
}
}
任何解决方案谢谢
BehaviourSubject
必须用起始值初始化。
在您的代码中,您从 title
和 logo
的空字符串开始,因此,如果您在调用 setData
之前在任何组件中订阅它(这使得 get 调用),新订阅者将获得初始的“空”值。
您可以尝试将其替换为ReplaySubject(1)
。然后,如果 setData
在订阅时尚未被调用,您可以应用任何您需要的逻辑来进行该调用。
如果您想继续使用 BehaviourSubject
,您可以将初始值设置为 null
并在您的订阅者中进行相应操作。
** 编辑 **
在玩了一下另一个用户设置的 Stackblitz 之后(并且缺少您的 API 返回的正确响应对象),我认为问题与主题或订阅无关,但是可能位于您的这两行代码中:
this.title=result['response'].title;
this.logo=result['response'].logo;
您可以尝试在 app.component.ts
中进行以下更改:
setData(): void {
this.http.get(this.baseUrl+'api/content').subscribe(result => {
/* Original code
this.title=result['response'].title;
this.logo=result['response'].logo;
*/
/* New code */
this.title=result.title;
this.logo=result.logo;
this.sharedService.setData({title: this.title, logo: this.logo});
});
}
注意我只是删除了 result
对象的 ['response']
属性,因为我 几乎 肯定没有这样的 属性 在 API 返回到您的应用程序中。但是如果没有看到您 API 的 实际 响应,很难给出正确的答案。
除非响应是一个数组,但在这种情况下你很可能需要指向一个索引位置。同样,如果您可以将 API 的实际回复粘贴到此处,那将非常有帮助,以便我们更好地指导您。