Angular8 中使用 mobx

2019-12-04  本文已影响0人  野鸡没名

前言: 最近在折腾一个 ionic4 项目,主要是围绕着 Angular 转圈圈,状态管理这块,Angular 官方的 @ngrx/store 用起来样板代码太多,索性换到了 mobx (react党😂),记录下折腾日记

代码已放到 github 上面https://github.com/caoxiemeihao/mobx5-angular8

核心代码

// src/store/mobx-rxjs.ts
import { computed } from 'mobx';
import { Observable, Subscriber } from 'rxjs';

/**
 * mobx 与 rxjs 之间的桥梁
 * @param expression 例如: () => this.store.xxxx
 */
export function fromMobx<T>(cb: () => any) {
  return new Observable((subscriber: Subscriber<T>) => {
    const _computed = computed(cb);
    const disposer = _computed.observe(changed => {
      subscriber.next(changed.newValue as T);
    });
    return () => {
      if (disposer) disposer();
    }
  });
}

新建一个 store 项目中可以有n个 store

// src/store/app-store.ts
import { Injectable } from '@angular/core';
import { observable, action, reaction } from 'mobx';

@Injectable({
  providedIn: 'root'
})
export class AppStore {
  constructor() {
    reaction(
      () => ({
        // 跟踪数据变动
        red: this.counterRed,
        green: this.counterGreen,
        blue: this.counterBlue
      }),
      ({ red, green, blue }) => {
        // 计算总惦记次数
        this.counter = red + green + blue;
      }
    );
  }

  @observable counter: number = 0;
  @observable counterRed: number = 0;
  @observable counterBlue: number = 0;
  @observable counterGreen: number = 0;

  @action.bound setCounter(color: 'red' | 'green' | 'blue') {
    if (color === 'red') {
      this.counterRed += 1;
    } else if (color === 'green') {
      this.counterGreen += 1;
    } else if (color === 'blue') {
      this.counterBlue += 1;
    }
  }
}

在组件中使用 将mobx转换成rxjs

// src/componets/counter/counter.ts
import { Component, DoCheck, ChangeDetectionStrategy } from "@angular/core";
import { Observable } from 'rxjs';
import { AppStore } from '@src/store/app-store';
import { fromMobx } from '@src/store/mobx-rxjs';
import { startWith } from 'rxjs/operators';

@Component({
  selector: 'app-counter',
  templateUrl: './counter.html',
  styleUrls: ['./counter.less'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class CounterComponent implements DoCheck  {
  couter$: Observable<number>;
  counter = 0;

  constructor(
    private store: AppStore
  ) {
    this.couter$ = fromMobx<number>(() => this.store.counter).pipe(startWith(0));
    this.counter = this.store.counter;
  }

  ngDoCheck() {
    console.log('[this.store.counter]', this.store.counter)
  }
}

模板代码

// src/components/counter/counter.html
<h2 class="alert alert-secondary rounded-0">
  Counter组件
</h2>
<h3>
  总点击次数 - Observable
  <span class="badge badge-dark">{{couter$ | async}}</span>
</h3>
<h3>
  总点击次数 - 原始类型
  <span class="badge badge-dark">{{couter || 0}}</span>
</h3>

上面只写了部分代码,源码可以去gtihub上面拉下来自己跑下 😊
感受下 Rxjs 的魔性

上一篇 下一篇

猜你喜欢

热点阅读