强大的Angular状态管理库– tinystate

强大的Angular状态管理库– tinystate
插件名称 tinystate
发布时间 2020年6月3日
插件作者 SebastianM

一个微型但功能强大的Angular状态管理库。

安装:

# Yarn
$ yarn add @tinystate/core

# NPM
$ npm install @tinystate/core --save

在app / root模块中加载模块

import { TinyStateModule } from '@tinystate/core';

@NgModule({
  imports: [
    CommonModule,
    TinyStateModule.forRoot()
  ]
})
class AppModule {}

例子

import { Container } from '@tinystate/core';

export interface CounterState {
  count: number;
}

/**
 * 容器是一个非常简单的类,它保存您的状态和一些用于更新它的逻辑。
 * 状态的形状是通过接口描述的(在本例中为CounterState)。
 */
export class CounterContainer extends Container<CounterState> {
  getInitialState(): CounterState {
    return {
      count: 0
    };
  }

  increment(increment: number) {
    this.setState(state => ({ count: state.count + increment }));
  }

  decrement(decrement: number = 1) {
    this.setState(state => ({ count: state.count - decrement }));
  }
}

@Component({
  selector: 'my-component',
  template: `
    <h1>
      Counter: {{ counter$ | async }}
    </h1>
    <button (click)="increment()">Increment</button>
    <button (click)="decrement()">Decrement</button>
  `,
  providers: [
    CounterContainer
  ]
})
export class MyComponent {
  counter$: Observable<number> = this.counterContainer.select(state => state.count);

  constructor(private counterContainer: CounterContainer) {}

  increment() {
    this.counterContainer.increment(1);
  }

  decrement() {
    this.counterContainer.decrement();
  }
}

全局状态

面显示的CounterContainer示例为创建了一个实例,MyComponent并且也可以为的所有组件注入MyComponent

如果您具有应该在所有组件中注入的全局状态,请将该providedIn: 'root'选项添加到@InjectableContainer 的装饰器中:

@Injectable({
  providedIn: 'root'
})
class CounterContainer {}

通过上面显示的配置,您可以将CounterContainer容器注入应用程序的每个组件中。

测试容器

测试容器真的很容易。假设我们要为以下容器编写测试:

import { Container } from '@tinystate/core';

export interface CounterState {
  count: number;
}

export class CounterContainer extends Container<CounterState> {
  getInitialState(): CounterState {
    return {
      count: 0
    };
  }

  increment() {
    this.setState(state => ({ count: state.count + 1 }));
  }
}

这是使用茉莉花进行可能测试的示例:

import { CounterContainer } from './counter.container';
import { TestBed, inject } from '@angular/core/testing';

describe('CounterContainer', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [CounterContainer]
    });
  });

  it(
    'should have an initial count state of 0',
    inject([CounterContainer], (container: CounterContainer) => {
      let count: number | undefined;
      container.select(s => s.count).subscribe(s => (count = s));
      expect(count).toEqual(0);
    })
  );

  it(
    'should increment the count by one when calling increment',
    inject([CounterContainer], (container: CounterContainer) => {
      let count: number | undefined;
      container.select(s => s.count).subscribe(s => (count = s));
      container.increment();
      expect(count).toEqual(1);
    })
  );
});