Angular 9 + NGRX:子组件如何获取数据?
我来帮你梳理下这个Angular 9 + NGRX场景下的问题,分几个角度给你实用建议:
子组件获取数据的两种方案及适用场景
方案1:父组件加载数据后通过@Input传递(推荐纯展示型子组件)
这种方式符合**"智能页面组件负责数据逻辑, dumb子组件负责展示"**的最佳实践,能让子组件更通用、低耦合。
实现步骤:
- 首先在Store中添加
topPosts状态,并定义对应的selector(推荐用createSelector提升性能) - 修改父组件
PostsPageComponent,统一触发数据加载并获取topPosts流:
export class PostsPageComponent { posts$: Observable<Post[]> = this.store.select(selectPosts); // 用selector替代直接select state,更规范且易维护 topPosts$: Observable<Post[]> = this.store.select(selectTopPosts); constructor(private store: Store<AppState>) {} ngOnInit() { this.store.dispatch({ type: '[Posts Page] Load Posts' }); // 父组件统一触发热门帖子加载 this.store.dispatch({ type: '[Posts Page] Load Top Posts' }); } }
- 父组件模板中通过
@Input传递数据给子组件:
<div *ngFor="let post of posts$ | async"> {{ post.name }} </div> <top-posts [topPosts]="topPosts$ | async"></top-posts>
- 子组件
TopPostsComponent仅接收数据并展示:
@Component({ template: ` <div *ngFor="let post of topPosts"> {{ post.name }} </div> ` }) export class TopPostsComponent { // 接收父组件传递的热门帖子数据 @Input() topPosts: Post[]; }
适用场景:
子组件仅负责展示热门帖子,不需要独立控制加载逻辑,这种模式下子组件可以轻松复用到其他页面,无需依赖Store。
方案2:子组件直接注入Store自治(适合独立型子组件)
如果你的TopPostsComponent需要在多个页面独立使用,且每个场景下都需要它自己控制数据加载,那可以让子组件直接和Store交互。
实现步骤:
- 同样在Store中定义
topPosts状态和selector - 修改子组件
TopPostsComponent,自行注入Store并触发加载:
@Component({ template: ` <div *ngFor="let post of topPosts$ | async"> {{ post.name }} </div> ` }) export class TopPostsComponent { topPosts$: Observable<Post[]> = this.store.select(selectTopPosts); constructor(private store: Store<AppState>) {} ngOnInit() { // 子组件自行触发加载动作 this.store.dispatch({ type: '[Top Posts Component] Load Top Posts' }); } }
- 父组件模板无需做任何额外处理,直接使用子组件即可:
<div *ngFor="let post of posts$ | async"> {{ post.name }} </div> <top-posts></top-posts>
适用场景:
子组件需要独立完成数据加载+展示的闭环,比如这个组件在不同页面使用时,加载逻辑可能有细微差异(或完全独立),自治模式能减少父组件的逻辑负担。
关于动作命名的建议
动作命名的核心是清晰标识发起者,方便后续调试和维护:
- 如果是父组件页面触发的加载,用
[Posts Page] Load Top Posts完全合理,能明确这个动作是页面级逻辑触发的; - 如果是子组件自行触发的加载,改成
[Top Posts Component] Load Top Posts更直观,在Redux DevTools中能一眼看到动作的发起来源。
内容的提问来源于stack exchange,提问作者Miguel Moura
相关产品推荐
相关产品推荐

