我确定这是一个简单的问题,我只是不知道在哪里查明它。 我有一个UserProfile服务,为userdata创建一个BehaviorSubject。 当我登录时,我使用此服务来广播用户数据。 登录后,我在Dashbord组件中订阅了这个userdata。但是userdata observable只在我第一次创建BehaviorSubject时返回第一个空对象。就好像使用.next()推送新数据的登录功能仅在仪表板订阅了BehaviourSubject之后运行。我尝试将我的仪表板的订阅放在ngAfterContentInit()中,以便.next()在订阅之前运行,但我仍然得到一个空白对象。如果我通过我的dashbord中的set_new_data()函数运行.next()来检查是否可观察到的工作,我得到.next()传递的数据;但我没有通过我的服务中的set_userdata()函数获取我的登录组件设置的数据。
我们不能使用服务分享这样的数据吗?离开登录组件后服务是否被销毁或正在发生什么?
我的USerProfile服务:
@Injectable()
export class UserProfileService {
public isLoggedIn: boolean = false;
public userdata: BehaviorSubject<any> = new BehaviorSubject<any>({});
constructor() {
}
public set_userdata(data) {
// this.userdata = data;
console.log(this.userdata);
if (this.userdata === undefined) {
console.log(data);
//this.userdata = new BehaviorSubject<any[]>(data);
console.log(this.userdata);
} else {
console.log(this.userdata);
this.userdata.next(data);
}
}
}
我的Dashbord组件:
@Component({
selector: 'dashboard',
styleUrls: ['./dashboard.scss'],
templateUrl: './dashboard.html'
})
export class Dashboard {
public isLoggedIn: boolean;
public curr_user: object;
constructor(private _appGlobals: AppGlobals, private _user: UserProfileService) {
this._appGlobals.isUserLoggedIn.subscribe(value => this.isLoggedIn = value);
// this.curr_user = _user.userdata;
}
ngAfterContentInit() {
console.log("this executes first");
this._user.userdata.subscribe(value => {
this.curr_user = value;
console.log(value);
});
}
set_new_data() {
let obj = {
name: "test",
age: 45
};
this._user.userdata.next(obj);
}
}
我的控制台输出,(显示空对象:{},预期用户数据)
答案 0 :(得分:1)
确保您只有一个服务实例,否则订阅者可能会订阅与您用于发布事件的实例不同的BehaviorSubject
。
在组件上提供服务可以导致创建与此组件的实例一样多的服务实例。
可能导致多个实例的另一个缺陷是延迟加载的模块,这些模块获得了自己的DI根范围 来自非延迟加载模块的提供程序被提升到应用程序根范围,即使多个非延迟加载的模块提供相同的服务,也只有一个实例。
由于DI范围在初始化后无法更新,因此无法将提供者从延迟加载的模块提升到应用程序根范围,因此新的&#34; root&#34;创建范围(作为应用程序根范围的子范围或另一个延迟加载的&#34; root&#34;范围),用于加载在一起的每组延迟加载模块。
使用forRoot
允许从延迟加载的模块向应用程序根范围添加提供程序。另见https://angular.io/guide/ngmodule-faq#what-is-the-forroot-method,
或者只是在AppModule
或任何其他已知不会直接加载延迟的模块中提供服务。
答案 1 :(得分:0)
如果从userdata
返回set_userdata(data)
作为Observable,然后订阅该函数而不是Subject
本身,则代码应该按预期工作。虽然我不确定最佳做法;
//UserProfileService
public set_userdata(data) { //--> Maybe make this get_userdata()
// this.userdata = data;
console.log(this.userdata);
if (this.userdata === undefined) {
console.log(data);
console.log(this.userdata);
} else {
console.log(this.userdata);
this.userdata.next(data);
}
return this.userdata.asObservable();
}
//Dashboard
ngAfterContentInit() { //--> this could be in ngOnInit
console.log("this executes first");
this._user.set_userdata().subscribe(value => {
this.curr_user = value;
console.log(value);
});
}