[Angular 2] ngrx/store

@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:

  • Add person
  • Remove person
  • Toggle person state
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);
            }
        );

 

-------------------------

 

 

 

你可能感兴趣的:([Angular 2] ngrx/store)