美文网首页
Angular8 中使用 mobx

Angular8 中使用 mobx

作者: 野鸡没名 | 来源:发表于2019-12-04 15:39 被阅读0次

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

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

  • 现在要完成一个简单的功能:
    定义个跟组局,根组件的状态修改要反应到其他两个子组件中


    screenshot1.png
  • 实现思路:
    Angular 的内部大量用到 Rxjs,如果把 mobx 中 @observable 的改变转换成为 Rxjs 的 Observable 是不是把 mobx 和 Angular 结合起来了呢?

核心代码

// 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 的魔性

相关文章

网友评论

      本文标题:Angular8 中使用 mobx

      本文链接:https://www.haomeiwen.com/subject/qsllgctx.html