标签:
@ngrx/store builds on the concepts made popular by Redux and supercharges it with the backing of RxJS. The result is a tool and philosophy that will transform the way you approach state management in your Angular 2 applications. This lesson takes an existing Angular 2 app and refactors it to utilize @ngrx/store, touching on all of the major concepts along the way!
Link: https://github.com/btroncone/ngrx-store-in-ten
The approach I took is a little bit different from the one shown in Github.
People reducer:
For perople reducer, mainly three things:
export const people = (state = defaultPeople, {type, payload}) => { switch(type){ case TOGGLE_STATE: return state.map( (person) => { if(person.name === payload.name){ let state = person.state ? !person.state : true; return Object.assign({}, person, {state}); } return person; }); case ADD_PERSON: return [ ...state, {name: payload, time: new Date()} ]; case DELETE_PERSON: var index = state.indexOf(payload); console.log(index); return [ ...state.slice(0, index), ...state.slice(index+1), ]; default: return state; } };
Then on the interface, add input and buttons:
<ul> <li [style.textDecoration]="person.state ? ‘line-through‘: ‘none‘" (click)="person$.next(person)" *ngFor="#person of people | async"> {{person.name}} is in {{person.time | date : ‘jms‘}} <button (click)="deletePerson$.next(person)">Remove</button> <button (click)="toggleState(person)">Toggle</button> </li> </ul> <br> <input type="text" #personInp><button (click)="addPerson$.next(personInp.value); personInp.value=‘‘">Add</button>
Add Person:
addPerson$ = new Subject() .map( (person) => ({type: ADD_PERSON, payload: person}));
Here we create an Action: {type: ADD_PERSON, payload: person}.
Dispatch the action:
Observable.merge(
... this.addPerson$,
... ) .subscribe(store.dispatch.bind(store))
Toggle Person:
For add person, we use Subject() to emit the event. For toggle person, we just use normal function to dispatch the action:
toggleState(person){ this.store.dispatch({type: TOGGLE_STATE, payload: person}) }
Filter:
Filter reducer add function which will be passed into the Array.filter() function:
export const filter = (state = person => person, {type, payload}: {type: ""}) => { switch(type){ case SHOW_ALL: return person => person; case SHOW_AVAILABLE: return person => !person.state; case SHOW_BUSY: return person => person.state; default: return state; } }
Tamplete:
<button (click)="all$.next()">Show All</button> <button (click)="available$.next()">Show Available</button> <button (click)="busy$.next()">Show Busy</button>
Use Subject:
all$ = new Subject()
.mapTo({type: SHOW_ALL});
available$ = new Subject()
.mapTo({type: SHOW_AVAILABLE});
busy$ = new Subject()
.mapTo({type: SHOW_BUSY});
Dispatch:
Observable.merge( this.person$, this.addPerson$, this.deletePerson$, this.available$, this.all$, this.busy$ ) .subscribe(store.dispatch.bind(store))
Update store:
this.people = Observable.combineLatest( this.people, this.filter, ( people, filter) => { return people.filter(filter); } );
-------------------------
标签:
原文地址:http://www.cnblogs.com/Answer1215/p/5449980.html