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 实现一个上述的第三方。
Angular 中定义了一个
Service
后可以通过依赖注入很轻松的把这个服务注入到组件中,这样组件就可以调用Service
提供的各种方法;我们可以把组件需要的状态数据存储在
Service
中,然后把注入的Service
设成public
,这样在模版中可以直接通过表达式绑定Service
中的数据 。
基于以上 2 个特性,基本上在使用 Angular 开发应用时一旦遇到组件之间共享数据,都可以使用 Service
轻松应对(当然做一个 SPA 单页应用,即使组件之间没有共享数据,也建议 使用 Service 作为数据层,统一维护业务逻辑),官方提供的英雄编辑器示例 MessageService,就是直接公开服务在组件模版上绑定的,代码如下,所以 Angular
不像 React
那样必须完全依赖状态管理框架才可以做组件之间的数据共享。:
export class MessageService {
messages: string[] = [];
add(message: string) {
this.messages.push(message);
}
clear() {
this.messages = [];
}
}
@Component({
selector: 'app-messages',
template: `
<div *ngIf="messageService.messages.length">
<h2>Messages</h2>
<button class="clear"
(click)="messageService.clear()">clear</button>
<div *ngFor='let message of messageService.messages'> {{message}} </div>
</div>
`
})
export class AppMessagesComponent implements OnInit {
constructor(public messageService: MessageService) { }
ngOnInit() {
}
}
那么在 Angular
中使用 Service
做状态管理会遇到哪些问题呢,如果只是很简单的状态通过 Service
直接管理肯定没有任何问题,但是一旦 Service
存储的状态与每个组件需要展示的状态不一致就很难处理了。比如下图是我们经常遇到的场景,首先项目中会有很多自定义的视图,默认只展示 2 个视图,其余的视图在更多视图中。