Angular 真的需要状态管理么?

Posted 前端外刊评论

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Angular 真的需要状态管理么?相关的知识,希望对你有一定的参考价值。

前端在过去很多年压根就没有听说过状态管理这东西,即使在 Angular.js 火热的那几年也很少有人谈前端的状态管理,直到 React 的出现,各种状态管理框架 Flux,Redux,Mobx, ... 层出不穷,让人眼花缭乱。如果你是一个 Angular 的开发者,貌似没有状态管理框架也可以正常的组件化开发,并没有发现缺什么东西。那么在 Angular 中如何优雅的管理前端状态呢?

首先前端组件化开发已经变成了标准,对于他的好处和概念网上有很多文章介绍,目前三大框架都是遵循组件化开发的思想,而且组件之间的通信基本都是单项数据流,就是说父组件通过属性绑定把数据传递给子组件,子组件想要修改传入的数据必须通过事件回调和父组件通信,React 中如果组件的层级比较深,同时父组件与很远的一个子组件之间需要共享数据,那就意味着数据会从父组件一层层往下传递,如果底层的组件需要修改数据,必须通过事件层层返回,这对于开发来说基本是灾难,代码变得难以维护,记得听说过一句很有哲学的话:任何解决不了的问题都可以引入一个第三方去解决,没错, 引入一个第三方存放维护这些状态,组件直接读取第三方把需要的状态展示在视图上,那么怎么样合理的设计这个第三方呢,那么 Flux,Redux,Mobx 这些状态管理类库基本都是所谓的第三方。

那么在 Angular 中为啥不是必须要状态管理框架呢?

首先在 Angular 中有个 Service的概念,虽然 Angular 对于 Service 基本上什么都没有做,连一个基类 BaseService 都没有提供,但是以下2个特性决定了在 Angular 中会很轻松的通过 Service 实现一个上述的第三方。

  1. Angular 中定义了一个 Service 后可以通过依赖注入很轻松的把这个服务注入到组件中,这样组件就可以调用 Service 提供的各种方法;

  2. 我们可以把组件需要的状态数据存储在 Service 中,然后把注入的 Service 设成 public,这样在模版中可以直接通过表达式绑定 Service 中的数据 。

基于以上 2 个特性,基本上在使用 Angular 开发应用时一旦遇到组件之间共享数据,都可以使用 Service 轻松应对(当然做一个 SPA 单页应用,即使组件之间没有共享数据,也建议 使用 Service 作为数据层,统一维护业务逻辑),官方提供的英雄编辑器示例 MessageService,就是直接公开服务在组件模版上绑定的,代码如下,所以 Angular 不像 React 那样必须完全依赖状态管理框架才可以做组件之间的数据共享。:

 
   
   
 
  1. export class MessageService {

  2.  messages: string[] = [];

  3.  add(message: string) {

  4.    this.messages.push(message);

  5.  }

  6.  clear() {

  7.    this.messages = [];

  8.  }

  9. }

  10. @Component({

  11.  selector: 'app-messages',

  12.  template: `

  13. <div *ngIf="messageService.messages.length">

  14.  <h2>Messages</h2>

  15.  <button class="clear"

  16.          (click)="messageService.clear()">clear</button>

  17.  <div *ngFor='let message of messageService.messages'> {{message}} </div>

  18. </div>

  19. `

  20. })

  21. export class AppMessagesComponent implements OnInit {

  22.  constructor(public messageService: MessageService) { }

  23.  ngOnInit() {

  24.  }

  25. }

那么在 Angular 中使用 Service 做状态管理会遇到哪些问题呢,如果只是很简单的状态通过 Service 直接管理肯定没有任何问题,但是一旦 Service 存储的状态与每个组件需要展示的状态不一致就很难处理了。比如下图是我们经常遇到的场景,首先项目中会有很多自定义的视图,默认只展示 2 个视图,其余的视图在更多视图中。