Angular自带的状态共享,90%的人姿势都错了。

3,219 阅读2分钟

前言

在使用诸如react,vue之类的框架时随着项目的不断变大和复杂化,已经不能通过组件通讯等来表达处理数据,你可能会引用redux ,mobx,vuex等优秀的开源的状态管理的库来管理全局的数据状态,但我也觉得很复杂。但是在angular里,是隐藏了一个状态管理的机制,这得益于脏检查,我后来才明白angular的伟大之处,老子什么鬼都帮你做好,埋头搓代码就好了。

脏检查机制

其实我并不是很懂其中的原理,但也没差。你可以理解成使用 setInterval 不断的轮询组件的状态来判断属性是否发生改变。这里思考一下,因为javascript变量赋值是值传递的,对象的引用其实是指针的赋值,假设我在component里引用外部store.ts导出的对象(Store),在component里改变Store的属性,那么其他引用store.ts的component的状态会不会发生改变?

试验一下

demo的地址

store.ts:
export let Store = {
  count:0,
  people:[]
}

三个组件的属性和方法一样 component.ts

import { Component, OnInit } from '@angular/core';
import { Store } from '../store'
@Component({
  selector: 'app-component1',
  templateUrl: './component1.component.html',
  styleUrls: ['./component1.component.css']
})
export class Component1Component implements OnInit {
  store = Store
  constructor() { }

  ngOnInit() {
  }
  add() {
    ++this.store.count
  }
  subtract() {
    --this.store.count
  }
  
}

component.html

<P>Store: {{ store | json }}</P>
<button (click)="add()">+</button>
count:{{store.count}}
<button (click)="subtract()">-</button>
<br/>
<button (click)="push()" >push</button>
<button (click)="pull()" >pull</button>

上面是我写的代码。整个应用的状态使用一个store.ts文件保存就行,对比redux和mobx等简直是完爆。如果配合双向绑定[(ngModel)]="store.count"使用的话,那就比react和vue的代码还要简单。不过要小心点,对于不了解javascript值传递和引用传递的同学来说会遇到不小的坑。component里的store的赋值必须是store.ts导出的变量,如果你是这样写的

    public store = Store.people

那么改变store就不会共享到其他组件。 资料可以参考http://bosn.me/js/js-call-by-sharing 这篇文章。

结语

我真的很像不懂为什么官网不介绍这种用法呢,非要用ngrx这么麻烦的库,看慕课网的视频也没介绍。入门Angular的两个月就发现这神技,真是老天保佑,代码减到1/4。哦对了,之前使用bootstrap也发现一个神级技巧,这就留到下片再讲。祝各位过个好年,不说了,我去看看我滴瓜蛙子旅游回来没。