美文网首页
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