为什么在大型 Angular 应用里我们需要使用 ngrx

举报
汪子熙 发表于 2022/08/28 09:59:32 2022/08/28
【摘要】 参考 ngrx 官网:https://ngrx.io/guide/effects#registering-root-effects Comparison with component-based side effects在基于服务的应用程序中,您的组件通过许多不同的服务与数据交互,这些服务通过属性和方法公开数据。 这些服务可能依赖于管理其他数据集的其他服务。 您的组件使用这些服务来执行任务,...

参考 ngrx 官网:https://ngrx.io/guide/effects#registering-root-effects

Comparison with component-based side effects

在基于服务的应用程序中,您的组件通过许多不同的服务与数据交互,这些服务通过属性和方法公开数据。 这些服务可能依赖于管理其他数据集的其他服务。 您的组件使用这些服务来执行任务,从而赋予您的组件许多职责——违反了设计的单一职责原理。

想象一下,您的应用程序管理电影。 这是一个获取并显示电影列表的组件。

@Component({
  template: `
    <li *ngFor="let movie of movies">
      {{ movie.name }}
    </li>
  `
})
export class MoviesPageComponent {
  movies: Movie[];
 
  constructor(private movieService: MoviesService) {}
 
  ngOnInit() {
    this.movieService.getAll().subscribe(movies => this.movies = movies);
  }
}

service 实现,负责读取 movies:

@Injectable({
  providedIn: 'root'
})
export class MoviesService {
  constructor (private http: HttpClient) {}

  getAll() {
    return this.http.get('/movies');
  }
}

这一个小小的 Component,就做了如下许多事情:

  • 管理电影的状态。
  • 使用该服务执行副作用,访问外部 API 以获取电影。
  • 更改组件内电影的状态。

引入 Store 和 Effect 的好处

与 Store 一起使用时,Effects 会减少 Component 的责任。 在更大的应用程序中,这变得更加重要,因为您有多个数据源,需要多个服务来获取这些数据,而服务可能依赖于其他服务。

Effects 处理外部数据和交互,允许您的服务实现达到 less stateful 的效果,并且只执行与外部交互相关的任务。 接下来,重构组件以将共享的电影数据放入 Store。 Effects 处理电影数据的获取。

重构后的 Component 实现:

@Component({
  template: `
    <div *ngFor="let movie of movies$ | async">
      {{ movie.name }}
    </div>
  `
})
export class MoviesPageComponent {
  movies$: Observable<Movie[]> = this.store.select(state => state.movies);
 
  constructor(private store: Store<{ movies: Movie[] }>) {}
 
  ngOnInit() {
    this.store.dispatch({ type: '[Movies Page] Load Movies' });
  }
}

电影仍然通过 MoviesService 获取,但现在组件不再关心如何获取和加载电影。 它只负责声明其加载电影的意图,并使用 selector 访问电影列表数据。

Effects 是获取电影的异步活动发生的地方。 您的组件变得更容易测试并且对它需要的数据负责。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。