我在我开发的应用程序中有一项服务,它接收我点击的项目并将它们存储在一个状态中,在我点击它们时合并新项目。我可以通过调用一个返回Observable的函数来访问这个存储状态(让我们称之为getItems
)。
我还有一个方法,使用@ angular / router包导航到应用程序的不同部分,然后导航方法 - this.router.navigate(path);
。重要的是,存储在服务中的上述项目随后可用于新路由中的应用程序 - 它们就是这样。但是,我现在正在尝试实现一个功能,它在导航到路径之前/之前查看项目,因为应用程序的新功能可能需要根据商店中存在的项目进行额外的HTTP请求。问题是,当我这样做时(在Resolve方法中),服务返回一个空对象。导航完成后,我再次调用该服务,它将返回正确的项目。那么为什么服务会在resolve方法中简单地返回一个空对象?以下是我的代码示例(大大简化):
export const ROUTES = [
{
path: '',
component: ExampleComponent,
children: [
{
path: '/child', loadChildren: './child-component/child-component.module#ChildComponentModule', resolve: {
objSummary: ComponentResolverService
}
]
}
]
因此,当我向商店添加商品时(点击它们),我就在/
。然后,我点击一个链接/按钮,将我带到/child
。接下来是ComponentResolverService
:
@Injectable()
export class ComponentResolverService implements Resolve<ObjectType> {
constructor(private http: HttpClient, private itemStoreService: ItemStoreService) {}
public resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<ObjectType> {
// this method returns the result of an HTTP call. In that HTTP call, I need to get the items which have previously been stored
let request: Observable<ObjectType>;
this.itemStoreService.getItems().subscribe(items => {
console.log(items); // returned as empty object {}
request = this.http.post<ObjectType>(apiUrl, items);
});
return request;
}
}
如果我向ChildComponent中的itemStoreService.getItems()
发出请求,它会返回一个对象,其中包含我之前添加到商店的项目。它只是在解析器中它返回空。
最后,ItemStoreService
:
interface Item {
attribute1: string;
attribute2: string;
}
interface Store<T> {
[key: string]: T;
}
export class ItemStoreService {
private items: BehaviorSubject<Store<Item>> = new BehaviorSubject<Store<Item>>();
private itemData: Store<Item>;
public getItems(): Observable<Store<Item>> {
return this.items.map((x: Store<Item) => _.cloneDeep(x));
}
public addItem(itemName: string, item: Item): void {
this.itemData[itemName] = item;
this.items.next(this.itemData);
}
}
当单击某个项目时,在主要组件(在'/'中呈现)时调用addItem
方法。我没有包含此代码,因为它不是问题,但包括完整性的方法。
所以基本上:getItems()
返回一个带有正确项目的Observable,除了Resolver服务,它返回一个空对象,我需要它返回解析器服务中的项目,以便我可以发出HTTP请求在API上开发应用程序。
编辑:使用Chrome调试器获取更多信息:我添加了一个断点,点击链接并使用路由器:(return this.router.navigate(path);
)。此处,在Chrome调试器范围面板中,itemStoreService
在范围内,而BehaviorSubject变量的值包含存储的项目。所以这很好。但是,我在解析器服务中添加了一个断点,并在范围内找到了itemStoreService;此处items
的值为{}
。因此,在初始路由激活和路由解析之间的某处,数据将丢失,然后在呈现子组件时再次找到。我会继续添加更多的断点并进行检查,希望这能让我找到它丢失的地方。
答案 0 :(得分:0)
此问题的解决方案是在core / root app.module.ts文件中导入整个应用程序中应保持相同的任何服务。我在多个NgModule
声明中单独导入ItemStoreService,这意味着它是单独注入的。因此,在某些地方,items
变量被重新初始化为空对象;其中一个地方在我的路由从组件到组件(但在每个组件中定义相同)。
为了答案完整性,上面的代码可以保持完全相同,我只需要在app.module.ts中确保我导入了ItemStoreService:
@NgModule({
bootstrap: [ AppComponent ],
declarations: [ AppComponent ],
imports: [ ... ],
providers: [
ItemStoreService,
...
]
});
然后我必须确保没有在任何其他模块中导入ItemStoreService。
感谢this answer为我提供了初步解决方案。