楚天乐的全栈之路 - angular 9
type: channel
link: https://blog.shyclouds.net/tag/angular-9
items: angular 9打造用户系统 - 7使用ngrx router store管理路由
items: angular 9打造用户系统 - 6使用ngrx entity完成CRUD操作
items: angular 9打造用户系统 - 5使用ngrx entity
items: angular 9打造用户系统 - 4使用ngrx effect从http api加载数据
items: angular 9打造用户系统 - 3 使用ngrx action和devtools
items: angular 9打造用户系统 - 2使用ngrx store和reducer来加载用户列表
items: angular 9打造用户系统 - 1搭建一个用户管理界面

angular 9打造用户系统 - 7使用ngrx router store管理路由
type: item
date: 2020-05-15T13:40:02+08:00
description: 本篇要做什么 本系列最后一篇 本文将使用ngrx router store来绑定angular路由到ngrx，同事使用CustomRouteStateSerializer github代码：https://github.com/shyandsy/angular-9-ngrx-user-mamagement 原教程视频连接 https://www.youtube.com/watch?v=XHw4hYkGsHM&list=PLaMbwDs23r4KXoMucJEyUAvamQ-kFNBvC&index=9 安装文档文档位置 https://github.com/ngrx/platform/tree/master/docs/router-store 安装 npm install @ngrx/router-store --save 新建src\app\shared\utils.ts, customer-route-state-serializer。这段代码是上面文档提供的 import { StoreModule, ActionReducerMap } from "@ngrx/store"; import { Params, RouterStateSnapshot} from '@angular/router'; import { RouterStateSerializer, RouterReducerState, routerReducer, } from '@ngrx/router-store'; export interface RouterStateUrl { url: string; params: Params; queryParams: Params; } export interface State { router: RouterReducerState<RouterStateUrl>; } export class CustomSerializer implements RouterStateSerializer<RouterStateUrl> { serialize(routerState: RouterStateSnapshot): RouterStateUrl { let route = routerState.root; while (route.firstChild) { route = route.firstChild; } const { url, root: { queryParams }, } = routerState; const { params } = route; // Only return an object including the URL, params and query params // instead of the entire snapshot return { url, params, queryParams }; } } // In your root reducer export const reducers: ActionReducerMap<State> = { router: routerReducer, }; 步骤 修改src\app\app.module.ts import { StoreRouterConnectingModule, routerReducer, RouterStateSerializer} from '@ngrx/router-store'; import { CustomSerializer } from "./shared/utils" imports: [ BrowserModule, StoreModule.forRoot({}), // 在module中添加reducer StoreDevtoolsModule.instrument(), EffectsModule.forRoot([]), HttpClientModule, AppRoutingModule, ReactiveFormsModule, // 使用FormBuilder需要导入ReactiveFormsModule // 增加 StoreRouterConnectingModule.forRoot({stateKey: "router"}), ], // 加入provider providers: [{ provide: RouterStateSerializer, useClass: CustomSerializer }], 效果

angular 9打造用户系统 - 6使用ngrx entity完成CRUD操作
type: item
date: 2020-05-14T23:46:00+08:00
description: 本篇要做什么 本文将使用effect entity来实现CRUD操作,需要用到ReactiveForm github代码：https://github.com/shyandsy/angular-9-ngrx-user-mamagement 原教程视频连接 https://www.youtube.com/watch?v=XHw4hYkGsHM&list=PLaMbwDs23r4KXoMucJEyUAvamQ-kFNBvC&index=8 步骤 src/app/app.module.ts导入ReactiveFormsModule 不在给出全部代码，需要的话，参照前一篇文章。 // 导入ReactiveFormsModule import { ReactiveFormsModule } from '@angular/forms'; imports: [ BrowserModule, StoreModule.forRoot({}), StoreDevtoolsModule.instrument(), EffectsModule.forRoot([]), HttpClientModule, AppRoutingModule, ReactiveFormsModule, // 加入ReactiveFormsModule，使用FormBuilder需要导入ReactiveFormsModule ], 给出完整的src/app/users/user.service.ts,提供增删改查功能 import { Injectable } from "@angular/core"; import { HttpClient } from "@angular/common/http"; import { Observable } from "rxjs"; import { Response } from './../app.models'; import { User, } from "./user.model"; @Injectable({ providedIn: "root" }) export class UserService { private usersUrl = "http://localhost:8000/user"; constructor(private http: HttpClient) {} getUsers(): Observable<Response<User[]>> { console.log("user service: Get Users") return this.http.get<Response<User[]>>(this.usersUrl, //{headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}} ); } getUserById(payload: number): Observable<Response<User>> { console.log("user service: Get User By Id") return this.http.get<Response<User>>(`${this.usersUrl}/${payload}`, //{headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}} ); } createUser(payload: User): Observable<Response<User>> { console.log("user service: Create User") console.log(payload) return this.http.post<Response<User>>(this.usersUrl, payload, //{headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}} ); } updateUser(user: User): Observable<Response<User>> { console.log("user service: Update User") return this.http.patch<Response<User>>( `${this.usersUrl}/${user.id}`, user, //{headers: {'Content-Type': 'application/x-www-form-urlencoded; chars…

angular 9打造用户系统 - 5使用ngrx entity
type: item
date: 2020-05-11T02:45:00+08:00
description: 本篇要做什么 本文将使用effect entity库来管理数据集，减少CRUD操作代码量，通过id来查找user github代码：https://github.com/shyandsy/angular-9-ngrx-user-mamagement 安装ngrx entity npm install @ngrx/entity 原教程视频连接 https://www.youtube.com/watch?v=igc5rBN50wk&list=PLaMbwDs23r4KXoMucJEyUAvamQ-kFNBvC&index=7 步骤 修改src\app\users\state\user.reducer.ts import * as userAction from './user.actions'; import {createFeatureSelector, createSelector, Store} from '@ngrx/store'; // 加入 import {EntityState, EntityAdapter, createEntityAdapter } from '@ngrx/entity'; import * as fromRoot from '../../state/app-state'; import { User } from '../user.model'; // 改用EntityState export interface UserState extends EntityState<User>{ selectedUserId: number | null; loading: boolean, loaded: boolean, error: string, } export interface AppState extends fromRoot.AppState{ users: UserState; } export const userAdapter: EntityAdapter<User> = createEntityAdapter<User>(); export const defaultUser: UserState = { ids: [], entities: {}, selectedUserId: null, loading: false, loaded: false, error: "" } export const initialState: UserState = userAdapter.getInitialState(defaultUser); export function userReducer(state = initialState, action: userAction.ACTION): UserState{ switch(action.type){ case userAction.UserActionTypes.LOAD_USERS:{ console.log("reducer: LOAD_USERS") return { ...state, loading: true, } } case userAction.UserActionTypes.LOAD_USERS_SUCESS:{ console.log("reducer: LOAD_USERS_SUCESS") return userAdapter.addAll(action.payload, { ...state, loading: false, loaded: true, }) } case userAction.UserActionTypes.LOAD_USERS_FAILED:{ console.log("reducer: LOAD_USERS_FAILED") return { ...state, entities: {}, loading: true, loaded: false, error: action.payload } } default: { return state; } } } const getUserFeatureState = createFeatureSelector<UserState>( "users" ) export const getUsers = createSelector( getUserFeatureState, userAdapter.getSelectors().selectAll ) export const getUsersLoading = createSelector( getUserFeatureState, (state: UserState) => s…

angular 9打造用户系统 - 4使用ngrx effect从http api加载数据
type: item
date: 2020-05-09T08:37:00+08:00
description: 本篇要做什么 本文将使用effect从http api加载数据来显示，user-list.component改用action对象发布事件 github代码：https://github.com/shyandsy/angular-9-ngrx-user-mamagement 原教程视频连接 https://www.youtube.com/watch?v=1dQVJ1DaFWU&list=PLaMbwDs23r4KXoMucJEyUAvamQ-kFNBvC&index=6 步骤 新建src\app\app.models.ts 通用的抽象response接口 export interface Response<T> { code: number, msg: string, data: T } 实现UserService, src\app\users\user.service.ts import { Injectable } from "@angular/core"; import { HttpClient } from "@angular/common/http"; import { Observable } from "rxjs"; import { Response } from './../app.models'; import { User, } from "./user.model"; @Injectable({ providedIn: "root" }) export class UserService { private customersUrl = "http://localhost:8000/user"; constructor(private http: HttpClient) {} // http接口返回 {code: 0, messgae: "...", data: [{id: 1, username: "...", ...}, ....]} // 直接映射到Response<User[]> getUsers(): Observable<Response<User[]>> { return this.http.get<Response<User[]>>(this.customersUrl); } } 添加src\app\users\state\user.effects.ts import { Injectable } from '@angular/core'; import { Actions, Effect, ofType, createEffect } from '@ngrx/effects'; import { Action } from '@ngrx/store'; import { Observable, of } from 'rxjs'; import { map, mergeMap, catchError } from 'rxjs/operators'; import { UserService } from '../user.service'; import * as userActions from '../state/user.actions'; import { Response } from './../../app.models'; import { User } from '../user.model'; @Injectable() export class UserEffect{ constructor( private actions$: Actions, private userService: UserService ){} @Effect() loadUsers$: Observable<Action> = createEffect(() => { return this.actions$.pipe( ofType<userActions.LoadUsers>( userActions.UserActionTypes.LOAD_USERS ), mergeMap((actions: userActions.LoadUsers) => this.userService.getUsers().pipe( map( // 解析Response<User[]>, 如果code是0（成功），提取data中的User[] (usersResponse: Response<User[]>) => { if(usersResponse.code == 0){ return new userActions.LoadUsersSuccess(usersResponse.data); }els…

angular 9打造用户系统 - 3 使用ngrx action和devtools
type: item
date: 2020-05-07T11:37:00+08:00
description: 本篇要做什么 本文将在上一篇基础上增加ngrx/store-devtools和actions github代码：https://github.com/shyandsy/angular-9-ngrx-user-mamagement 上一篇已经安装依赖 npm install @ngrx/store @ngrx/effects @ngrx/entity @ngrx/store-devtools @ngrx/router-store 原教程视频连接 https://www.youtube.com/watch?v=1dQVJ1DaFWU&list=PLaMbwDs23r4KXoMucJEyUAvamQ-kFNBvC&index=5 步骤 浏览器安装redux devtools插件，我使用chrome浏览器 修改src\app\app.module.ts import { BrowserModule } from '@angular/platform-browser'; import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { StoreModule } from '@ngrx/store'; //加入这行，引用StoreDevtoolsModule import { StoreDevtoolsModule } from '@ngrx/store-devtools'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { HomeComponent } from './home/home.component'; import { NavbarComponent } from './navbar/navbar.component'; @NgModule({ declarations: [ AppComponent, HomeComponent, NavbarComponent, ], imports: [ BrowserModule, StoreModule.forRoot({}), // 使用StoreDevtoolsModule StoreDevtoolsModule.instrument(), AppRoutingModule, ], providers: [], bootstrap: [AppComponent], }) export class AppModule { } 现在我们刷新浏览器，打开chrome console的redux面板，可以看到所有的状态变动，方便调试 创建actions，src\app\users\state\user.actions.ts import { Action } from '@ngrx/store'; import { User } from '../user.model'; export enum UserActionTypes { LOAD_USERS = "[User] Load Users", LOAD_USERS_SUCESS = "[User] Load Users Success", LOAD_USERS_FAILED = "[User] Load Users Failed", } export class LoadUsers implements Action{ readonly type = UserActionTypes.LOAD_USERS; } export class LoadUsersSuccess implements Action{ readonly type = UserActionTypes.LOAD_USERS_SUCESS; constructor(public payload: User[]) {} } export class LoadUsersFailed implements Action{ readonly type = UserActionTypes.LOAD_USERS_FAILED; constructor(public payload: string) {} } export type ACTION = LoadUsers | LoadUsersSuccess | LoadUsersFailed; 创建src\app\state\app-state.ts export interface AppState{ } 重写我们的reducer，不提供初始数据 import * a…

angular 9打造用户系统 - 2使用ngrx store和reducer来加载用户列表
type: item
date: 2020-05-06T01:41:00+08:00
description: angular 9打造用户系统-2 本片使用ngrx store和ngrx reducer加载用户列表 github代码：https://github.com/shyandsy/angular-9-ngrx-user-mamagement 原教程视频连接 https://www.youtube.com/watch?v=ChiAZJiX3v0&list=PLaMbwDs23r4KXoMucJEyUAvamQ-kFNBvC&index=4 步骤 安装ngrx依赖 npm install @ngrx/store @ngrx/effects @ngrx/entity @ngrx/store-devtools @ngrx/router-store 创建第一个action和reducer 创建src\app\users\user.model.ts import { Time } from '@angular/common' export interface User{ id?: number; username: string; cnname: string; enname: string; password?: string; role_id: number; email: string; telephone: string; mobile: string; fax: string; address: string; post: string; token: string; expired: Time; status: number; ip: string; } 创建src\app\users\user.service.ts, 稍后实现 创建src\app\users\state文件夹 创建src\app\users\state\user.actions.ts 创建src\app\users\state\user.reducer.ts 修改src\app.module.ts //加入 import { StoreModule } from '@ngrx/store'; imports: [ BrowserModule, // 加入这行 StoreModule.forRoot({}), // 在module中添加reducer AppRoutingModule, ], 修改src\app\users\users.module.ts //加入 import { StoreModule } from '@ngrx/store'; import { userReducer } from './state/user.reducer'; imports: [ CommonModule, RouterModule.forChild(userRoutes), // 加入，给user module添加UserReducer StoreModule.forFeature("users", userReducer), ], 编写userReducer, src\app\users\state\user.reducer.ts import { formatDate } from '@angular/common'; // 定义一个initialState let date = new Date(); const initialState = { users: [ { username: "shyclouds", cnname: "李连杰", enname: "Jack Li", password: "", role_id: 1, email: "shyclouds@shyclouds.com", telephone: "01022334441", mobile: "13122334455", fax: "01022334442", address: "北京市长安街128号", post: "10001", token: "xxxxx", expired: new Date(), status: 1, ip: "127.0.0.1", } ], loading: false, loaded: true, } // 定义userReducer export function userReducer(state = initialState, action){ switch(action.type){ case "LOAD_USERS":{ return { ...state, loading: true, loaded: false, } } default: { return state; } } } 修改src\app\users\user-list\user…

angular 9打造用户系统 - 1搭建一个用户管理界面
type: item
date: 2020-05-03T20:56:00+08:00
description: 做什么 本文使用angular搭建一个客户管理页面，包含添加客户，修改客户信息，客户列表。本文内容只涵盖展示页面，没有业务逻辑。业务逻辑将在下一篇中实现，最终效果在页面底部 github代码：https://github.com/shyandsy/angular-9-ngrx-user-mamagement 感谢教程原作者 https://www.youtube.com/watch?v=QlzX_gKixa4&list=PLaMbwDs23r4KXoMucJEyUAvamQ-kFNBvC&index=3 https://github.com/angulardeveloper-io/ngrx-store-app 步骤 创建项目,项目名user ng new user 加入bootstrap4的css,文件： User <app-root></app-root> 安装ngrx npm install @ngrx/store 修改src\app\app.module.ts import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; // 加入这行 import { StoreModule } from '@ngrx/store'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { HomeComponent } from './home/home.component'; import { NavbarComponent } from './navbar/navbar.component'; @NgModule({ declarations: [ AppComponent, HomeComponent, NavbarComponent ], imports: [ BrowserModule, // 加入这行 StorwModule.forRoot({}), AppRoutingModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { } 用vscode打开项目目录，创建所需要的model和component // 创建home module ng g c home // 创建navbar module ng g c navbar ng g m users // 创建user module ng g c users/user -m users // 创建user module --> user component ng g c users/user-add -m users // 创建user module --> user-add component ng g c users/user-edit -m users // 创建user module --> user-edit component ng g c users/user-list -m users // 创建user module --> user-list component 修改src\app\app-routing.module.ts import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { CommonModule } from '@angular/common'; // 1.加入这行 import { HomeComponent } from './home/home.component'; // 2.加入这行 const routes: Routes = [ { path: "", component: HomeComponent }, // 3.加入这行 { path: "users", loadChildren: "../app/users/users.module#UserModule" }, // 4.加入这行 ]; @NgModule({ imports: [ CommonModule, // 5.加入这行 RouterModule.forRoot(routes) ], exports: [RouterModule] }) export class AppRoutingModule { }…