zoukankan      html  css  js  c++  java
  • ngrx/store effects 使用总结2:列表展示

     第一个计数器案例:http://www.cnblogs.com/axel10/p/8589122.html

    完成了计数器案例后,现在开始比较能够完整的展示angular2+开发流程的案例:在线获取用户列表并展示,包含点击删除功能。希望在开始之前,你对typescript和rxjs有一定了解。

     

    再重复一遍开发流程:

    开始 -> 编写数据模型 -> 编写action -> 编写redurces并配置到相应module -> 编写services -> 编写effects并配置到相应module -> 创建组件 -> 组件绑定数据模型 -> 渲染

    第一步:编写数据模型(app/models/user.ts)

    export class User {
    
      id: number;
    
      name: string;
    
    }

    第二步:编写action(app/actions/num.ts)

    import {Action} from '@ngrx/store';
    import {User} from '../models/user';
    
    export enum ListActionType {
      Load = 'LOAD',
      LoadSuccess = 'LOAD_SUCCESS',
      RemoveUser = 'REMOVE_USER',
      RemoveUserSuccess = 'REMOVE_USER_SUCCESS',
      RemoveUserError = 'REMOVE_USER_ERROR'
    }
    
    export class Load implements Action {
      readonly type = ListActionType.Load;
    }
    
    export class LoadSuccess implements Action {
      readonly type = ListActionType.LoadSuccess;
    
      constructor(public payload: User[]) {
      }
    }
    
    export class RemoveUser implements Action {
      readonly type = ListActionType.RemoveUser;
    
      constructor(public payload: number) {
      }
    }
    
    export class RemoveUserSuccess implements Action {
      readonly type = ListActionType.RemoveUserSuccess;
    }
    
    export class RemoveUserError implements Action {
      readonly type = ListActionType.RemoveUserError;
    }

    第三步:编写redurcers(app/redurces/list.ts)

    import {Action} from '@ngrx/store';
    
    import {User} from '../models/user';
    
    import {ListActionType, LoadSuccess, RemoveUser} from '../actions/list';
    
     
    
    export interface State {
    
      loading: boolean;
    
      loaded: boolean;
    
      list: User[];
    
    }
    
     
    
    const initialState: State = {
    
      loading: false,
    
      loaded: false,
    
      list: []
    
    };
    
     
    
    export const list = (state = initialState, action: Action) => {
    
      switch (action.type) {
    
        case ListActionType.Load:
    
          console.log('load....');
    
          return {
    
            ...state,
    
            loading: true,
    
          };
    
        case ListActionType.LoadSuccess:
    
          console.log('load success');
    
          const myA = (<LoadSuccess>action).payload;
    
          console.log(myA);
    
          return {
    
            ...state,
    
            loaded: true,
    
            loading: false,
    
            list: myA
    
          };
    
        case ListActionType.RemoveUser:
    
          console.log('remove user');
    
          const userId = (<RemoveUser>action).payload;
    
          state.list = state.list.filter(function (item) {
    
            return item.id !== userId;
    
          });
    
          return {...state};
    
     
    
        default:
    
          return state;
    
      }
    
    };

    配置redurcer(app/app.module.ts)

     

     imports: [
    
        BrowserModule,
    
        RouterModule.forRoot(routes),
    
        StoreModule.forRoot({ modelNum, list}),      //配置redurcer
    
      ],

    第四步:编写services(app/services/ListService.ts)

    import {Injectable} from '@angular/core';
    
    import {HttpClient} from '@angular/common/http';
    
    import {Observable} from 'rxjs/Observable';
    
    import {User} from '../models/user';
    
     
    
     
    
    @Injectable()
    
    export class ListService {
    
      public getList(): Observable<any> {
    
        return this.http.get<{ users: User[] }>('/api/users.json');
    
      }
    
     
    
      public removeUser(): Observable<any> {
    
        return Observable.create(function (observer) {
    
          observer.next('true');
    
        });
    
      }
    
     
    
      constructor(private http: HttpClient) {
    
      }
    
    }

    第五步:编写effects:

    import {Injectable} from '@angular/core';
    
    import {Actions, Effect, ofType} from '@ngrx/effects';
    
    import {Observable} from 'rxjs/Observable';
    
    import {Action} from '@ngrx/store';
    
    import {ListActionType, Load, LoadSuccess, RemoveUser, RemoveUserError, RemoveUserSuccess} from '../actions/list';
    
    import {catchError, map, switchMap} from 'rxjs/operators';
    
    import {ListService} from '../services/ListService';
    
    import {of} from 'rxjs/observable/of';
    
     
    
     
    
    @Injectable()
    
    export class ListEffects {
    
     
    
      @Effect()
    
      loadList$: Observable<Action> = this.action$.pipe(   //rxjs写法。loadList$是effect名,在外部没有用到,可以随便起。
    
        ofType<Load>(ListActionType.Load),
    
        switchMap(action => {
    
          return this.listService.getList().pipe(map(
    
            users => {
    
              return new LoadSuccess(users);
    
            }
    
          ));
    
        })
    
      );
    
     
    
      @Effect()
    
      removeUser$: Observable<Action> = this.action$.pipe(
    
        ofType<RemoveUser>(ListActionType.RemoveUser),
    
        switchMap(_ => {
    
          return this.listService.removeUser().pipe(
    
            map(res => {
    
              console.log(res);
    
              if (res === 'true') {
    
                return new RemoveUserSuccess();
    
              } else {
    
                return new RemoveUserError();
    
              }
    
            }),
    
            catchError(err => of(new RemoveUserError()))
    
          );
    
        })
    
      );
    
     
    
     
    
      constructor(private action$: Actions, private listService: ListService) {
    
      }
    
     
    
    }
    
     

     

    记得在app.module.ts配置effects和HttpClient:

     

     imports: [
    
        BrowserModule,
    
        RouterModule.forRoot(routes),
    
        StoreModule.forRoot({modelNum, list}),
    
        EffectsModule.forRoot([ListEffects]),
    
        HttpClientModule
    
      ],

    第六步:创建组件

    ng g component list

    第七步:组件绑定数据模型(连带完成第八步)

    组件ts文件:

    import {Component, OnInit} from '@angular/core';
    
    import {Store} from '@ngrx/store';
    
    import * as list from '../actions/list';
    
    import {State} from '../reducers/list';
    
    import {User} from '../models/user';
    
     
    
    @Component({
    
      selector: 'app-list',
    
      templateUrl: './list.component.html',
    
      styleUrls: ['./list.component.scss']
    
    })
    
    export class ListComponent implements OnInit {
    
     
    
      public list: User[];
    
     
    
      constructor(private store: Store<any>) {
    
        this.store.select('list').subscribe(_list => {
    
          if (_list) {
    
            console.log(_list);
    
     
    
            console.log(_list.list);
    
     
    
            this.list = _list.list;
    
          }
    
        });
    
      }
    
     
    
      removeUser(id) {
    
        console.log(id);
    
        this.store.dispatch(new list.RemoveUser(id));
    
      }
    
     
    
      ngOnInit() {
    
        this.store.dispatch(new list.Load());
    
      }
    
    }

    组件html文件:

    <div>
    
    list
    
      请尝试点击上半部分的li。
    
      <ul>
    
        <li *ngFor="let item of list" (click)="removeUser(item.id)">{{item.name}}</li>
    
      </ul>
    
      <app-list-body></app-list-body>
    
      <br/>
    
      <a routerLink="/model">to counter demo</a>
    
    </div>

    最后配置路由:

    import {Routes} from '@angular/router';
    
    import {IndexComponent} from './index/index.component';
    
    import {ModelDemoComponent} from './model-demo/model-demo.component';
    
    import {ListComponent} from './list/list.component';
    
     
    
     
    
    export const routes: Routes = [
    
      {
    
        path: 'list',
    
        component: ListComponent
    
      },
    
      {
    
        path: 'model',
    
        component: ModelDemoComponent
    
      },
    
      {
    
        path: '**',
    
        redirectTo: 'list'
    
      }
    
    ];

     

    到此本案例结束。如果想要更加复杂的案例可以到ngrx的github获取。https://github.com/ngrx/platform

  • 相关阅读:
    Android-Java-构造方法内存图
    redis conf 详解
    redis windows 下安装及使用
    Python 学习笔记(一)
    python 配置
    win 7 下vim的使用
    window下安装Node.js NPM
    HashMap实现原理(转)
    mysql 常用功能
    MySql配置
  • 原文地址:https://www.cnblogs.com/axel10/p/8589139.html
Copyright © 2011-2022 走看看