@ngrx入坑angular的schema,爽的一逼!

楊明明發表於2018-06-29

安裝schematics工具

yarn add @ngrx/schematics --dev
yarn add ngrx-store-freeze --dev
複製程式碼

安裝包

yarn add @ngrx/{store,effects,entity,store-devtools}
複製程式碼

使用schematics

ng config cli.defaultCollection @ngrx/schematics
複製程式碼

初始化state

ng generate @ngrx/schematics:store State --root --module app.module.ts
複製程式碼

初始化effect

ng generate @ngrx/schematics:effect App --root --module app.module.ts
複製程式碼

初始化action

ng generate action User --group
複製程式碼

新建元件

ng generate container UsersPage --state reducers/index.ts --stateInterface MyState
複製程式碼

新建effect

ng generate module User --flat false
ng generate effect user/User -m user/user.module.ts --group
複製程式碼

新建entity

ng generate entity User -m app.module.ts
複製程式碼

新建feature

ng generate feature User --group
複製程式碼

新建reducer

ng generate reducer User --group
複製程式碼

實戰

// 新建專案ngrx-test
ng new ngrx-test
// 配置環境
yarn add @ngrx/schematics --dev
yarn add ngrx-store-freeze --dev
yarn add @ngrx/{store,effects,entity,store-devtools}
ng config cli.defaultCollection @ngrx/schematics
// 初始化store
ng generate @ngrx/schematics:store State --root --module app.module.ts
// 初始化effect
ng generate @ngrx/schematics:effect App --root --module app.module.ts --group
// 新建Iwe7StoreModule並載入到AppModule
ng generate module Iwe7Store --flat false -m app.module.ts
// 新建模型Iwe7Member並掛在到Iwe7StoreModule
ng generate entity Iwe7Member -m iwe7-store/iwe7-store.module.ts --group
// 新建元件並掛在到Iwe7StoreModule並匯出元件,指定reducer和interface
ng generate container iwe7-store/iwe7-member -m iwe7-store.module.ts --state ../reducers/index.ts --stateInterface State --export
// 啟動應用
yarn start
複製程式碼

到此專案雛形已現!angular的schema技術真是牛的一逼,相信很快其他框架也會競相模仿!~~

簡單擼串

import { Component, OnInit } from '@angular/core';
import { Store } from '@ngrx/store';
import * as fromStore from '../../reducers';
import * as iwe7MemberActions from './../../actions/iwe7-member.actions';
import { Iwe7Member } from '../../models/iwe7-member.model';
import { pluck } from 'rxjs/operators';
let memberId: number = 0;
@Component({
  selector: 'app-iwe7-member',
  templateUrl: './iwe7-member.component.html',
  styleUrls: ['./iwe7-member.component.css']
})
export class Iwe7MemberComponent implements OnInit {
  list: any = this.store.pipe(pluck('iwe7Member'), pluck('entities'));
  ids: any = this.store.pipe(pluck('iwe7Member'), pluck('ids'));
  constructor(private store: Store<fromStore.State>) { }

  ngOnInit() { }

  add() {
    memberId = memberId + 1;
    const newMember: Iwe7Member = { id: memberId + '' };
    this.store.dispatch(new iwe7MemberActions.AddIwe7Member({
      iwe7Member: newMember
    }));
  }
}
複製程式碼
<p>
  iwe7-member entity works!
</p>


<ul>
  <li *ngFor="let id of ids|async">
    {{(list|async)[id] | json}}
  </li>
</ul>

<button (click)="add()">新增</button>
複製程式碼

點選按鈕新增即可實現資料的新增!

正規化

import {
  ActionReducer,
  ActionReducerMap,
  createFeatureSelector,
  createSelector,
  MetaReducer
} from '@ngrx/store';
import { environment } from '../../environments/environment';
import * as iwe7MemberReducer from './iwe7-member.reducer';
import { storeFreeze } from 'ngrx-store-freeze';
export interface State {
  member: iwe7MemberReducer.State;
}

export const reducers: ActionReducerMap<State> = {
  member: iwe7MemberReducer.reducer,
};

export function logger(reducer: ActionReducer<State>): ActionReducer<State> {
  return function (state: State, action: any): State {
    console.log('state', state);
    console.log('action', action);
    return reducer(state, action);
  };
}

export const metaReducers: MetaReducer<State>[] = !environment.production ? [] : [logger];

export const selectIwe7MemberState = createFeatureSelector<iwe7MemberReducer.State>('member');
export const selectIwe7MemberIds = createSelector(
  selectIwe7MemberState,
  iwe7MemberReducer.selectIds
);

export const selectIwe7MemberEntities = createSelector(
  selectIwe7MemberState,
  iwe7MemberReducer.selectEntities
);

export const selectAllIwe7Member = createSelector(
  selectIwe7MemberState,
  iwe7MemberReducer.selectAll
);

export const selectIwe7MemberTotal = createSelector(
  selectIwe7MemberState,
  iwe7MemberReducer.selectTotal
);
複製程式碼
<p>
  共計:{{total|async}}
</p>

<ul>
  <li *ngFor="let item of list|async">
    {{ item.realname }}
    <button (click)="removeUser(item)">刪除</button>
    <button (click)="updateUser(item)">更新</button>
  </li>
</ul>

<button (click)="addUser()">新增會員</button>
複製程式碼
import { selectAllIwe7Member, selectIwe7MemberTotal, selectIwe7MemberIds, selectIwe7MemberEntities } from './../../reducers/index';
import { Component, OnInit } from '@angular/core';
import { Store } from '@ngrx/store';
import * as fromStore from '../../reducers';
import * as iwe7MemberActions from './../../actions/iwe7-member.actions';
import { Iwe7Member } from '../../models/iwe7-member.model';
import { Observable } from 'rxjs';
let memberId: number = 0;
@Component({
  selector: 'app-iwe7-member',
  templateUrl: './iwe7-member.component.html',
  styleUrls: ['./iwe7-member.component.css']
})
export class Iwe7MemberComponent implements OnInit {
  list: Observable<Iwe7Member[]>;
  total: Observable<number>;
  ids: Observable<string[] | number[]>;
  entities: Observable<{ [key: string]: Iwe7Member }>;
  constructor(private store: Store<fromStore.State>) {
    this.list = this.store.select(selectAllIwe7Member);
    this.total = this.store.select(selectIwe7MemberTotal);
    this.ids = this.store.select(selectIwe7MemberIds);
    this.entities = this.store.select(selectIwe7MemberEntities);
  }

  ngOnInit() { }

  addUser() {
    memberId = memberId + 1;
    const newMember: Iwe7Member = { id: memberId + '', realname: 'realname-' + memberId };
    this.store.dispatch(new iwe7MemberActions.AddIwe7Member({
      iwe7Member: newMember
    }));
  }

  removeUser(user: Iwe7Member) {
    this.store.dispatch(new iwe7MemberActions.DeleteIwe7Member(user));
  }

  updateUser(user: Iwe7Member) {
    const realname = 'update ' + user.id + ' realname';
    const iwe7Member = {
      id: user.id,
      changes: {
        realname
      }
    };
    this.store.dispatch(
      new iwe7MemberActions.UpdateIwe7Member({
        iwe7Member
      })
    );
  }
}
複製程式碼

開發速度及體驗都是槓槓滴!!

增加

ng g m iwe7-store/iwe7-fans --spec=false -m iwe7-store/iwe7-store.module --export=true
ng g c iwe7-store/iwe7-fans --spec=false --export=true -m iwe7-store/iwe7-fans/iwe7-fans.module.ts
ng generate entity Iwe7Fans -m iwe7-store/iwe7-fans/iwe7-fans.module.ts --group --spec=false
ng g s services/iwe7-fans --spec=false
ng generate effect Iwe7Fans -m iwe7-store/iwe7-fans/iwe7-fans.module.ts --group --spec=false
複製程式碼

相關文章