注意:由于该问题归结为一次
@Injectable
服务的反复说明,因此请向下滚动至“更新”。
我有一个可以为企业服务的解析器:
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any {
this._logger.debug('Loading application data.');
return forkJoin([
this._userService.getMe(),
this._businessService.getAll()
]).pipe(
tap(([user, businesses]) => {
this._appState.user = user;
this._appState.businesses = businesses;
}),
finalize(() => this._logger.debug('Application data loaded.'))
);
}
有一个ApplicationState
,有两个BehaviorSubject
成员_business
和_businesses
:
constructor() {
this.businessChange = this._business.asObservable();
this.businessesChange = this._businesses.asObservable();
}
set business(business: BusinessModel) {
console.log(business);
this._business.next(business);
}
get business(): BusinessModel {
return this._business.getValue();
}
set businesses(value) {
this._businesses.next(value);
console.log(this.businesses);
}
get businesses(): Array<BusinessModel> {
return this._businesses.getValue();
}
如您所见,在解析器中设置了businesses
所述状态。 business
取决于路由,并根据该路由设置在(延迟加载)模块中:
ngOnInit() {
this._appState.businessesChange.subscribe(
(b) => {
console.log('businessesChange');
console.log(b);
}
);
this._subscriptions.add(
this._activatedRoute.params
.subscribe((params) => {
this._routeParams = params;
const businessId: number = parseInt(params['businessId'], 10);
const businesses = this._appState.businesses;
console.log(`businessId ${businessId}`);
console.log('available businesses');
console.log(businesses);
this._appState.business = businesses.find(b => b.id === businessId);
})
);
}
这是相关的日志输出:
2019-08-28T09:11:04.989Z DEBUG [..~df7ced28.js:428] Loading application data.
ngx-logger.js:251 2019-08-28T09:11:04.992Z DEBUG [main.js:398] Fetching /me
application.state.ts:56 Set businesses:
application.state.ts:58 (3) [{…}, {…}, {…}]
ngx-logger.js:251 2019-08-28T09:11:06.781Z DEBUG Application data loaded.
businesses.component.ts:43 businessesChange
businesses.component.ts:44 []
businesses.component.ts:47 businessId 4
businesses.component.ts:48 available businesses
businesses.component.ts:49 []
application.state.ts:46 Set business:
application.state.ts:47 undefined
ngx-logger.js:251 2019-08-28T09:11:08.386Z DEBUG Place is null. No action.
如您所见,businesses
被设置并包含三个元素。然后,我们从解析器看到应用程序数据已加载。。之后,我们看到_activatedRoute.params
订阅声明该路由显示businessId
的{{1}},但是随后。4
突然是一个空列表-初始值this._appState.businesses
的内容,即使我们稍早打印了该内容。
由于我也正在登录/调试BehaviorSubject
方法,因此我可以看到在将该值设置为三个元素的列表后,不会被更改。
我不知道这是怎么回事。可能是什么原因造成的?
我已经尝试过的:
好吧,我将问题归结为set
被多次宣告:
通过为ApplicationState
提供一个简单的ID(时间戳):
ApplicationState
并在constructor() {
this.businessChange = this._business.asObservable();
this.businessesChange = this._businesses.asObservable();
this.timestamp = moment().format('MM.SS SSS');
console.log(`${this.timestamp} ApplicationState created`);
}
和set
方法中更改日志输出,我得到了:
get
因此,08.09 095 ApplicationState created
ngx-logger.js:251 2019-08-28T09:51:16.098Z DEBUG Loading application data.
ngx-logger.js:251 2019-08-28T09:51:16.099Z DEBUG [main.js:398] Fetching /me
:4200/#/businesses/4/calendar:1 This site does not have a valid SSL certificate! Without SSL, your site's and visitors' data is vulnerable to theft and tampering. Get a valid SSL certificate before releasing your website to the public.
application.state.ts:60 08.09 095 Set businesses:
application.state.ts:62 (3) [{…}, {…}, {…}]
application.state.ts:38 08.14 145 ApplicationState created
ngx-logger.js:251 2019-08-28T09:51:16.161Z DEBUG Application data loaded.
businesses.component.ts:43 businessesChange
businesses.component.ts:44 []
businesses.component.ts:54 businessId 4
businesses.component.ts:55 available businesses
businesses.component.ts:56 []
application.state.ts:50 08.14 145 Set business:
application.state.ts:51 undefined
ngx-logger.js:251 2019-08-28T09:51:16.178Z DEBUG Place is null. No action.
calendar.component.ts:105
有一个08.09 095
(A)和一个08.14 145
(B)实例。
A设定了业务,但显然使用了B。
我检查过,ApplicationState
在我的ApplicationState
中仅被导入一次:
ApplicationModule
那为什么会这样呢?这不是辛格尔顿吗?是因为这经过了延迟加载的模块吗?
但最重要的是:为什么在过去的几周中一直如此?
我现在还添加了providers: [
// Services
ApplicationState,
ApiServices,
ApplicationResolver,
]
:
providedIn
但它的行为仍然相同。
答案 0 :(得分:0)
好吧,发生这种情况的答案为什么显然是由于延迟加载。似乎有一些事情要做依赖树的构建或类似的事情。
我不知道详细信息,我将接受任何有关此主题的更详细的分析器。
无论如何,我认为在 parent 模块中提供服务就足够了。因为有了感觉,不是吗?
事实证明,这确实必须在app.module.ts
中提供。我在提供application.module.ts
的地方有另一个名为ApplicationState
的模块(不应混淆)。 application.module.ts
是延迟加载的,但也有一些路由再次被延迟加载,例如businesses.module.ts
。所以我的层次结构看起来像这样:
app.module.ts
|_ application.module.ts // lazy, providers: [ApplicationState]
| |_ businesses.ts // lazy, uses ApplicationState too
|_ public-pages.module.ts // not lazy
我需要更改的是设置
providers: [ApplicationState]
在app.module.ts
中。
这不是理想的imo,但是由于延迟加载是这样工作的,因此我将不得不对其进行处理。
显然这是一个已知问题(https://github.com/angular/angular/issues/12869),但是堆栈上也有可能的解决方案溢出:https://stackoverflow.com/a/41293784/826983