NgRx/Store 4 + Angular 5使用教程

这篇文章将会示范如何使用NgRx/Store 4和Angular5。@ngrx/store是基于RxJS的状态管理库,其灵感来源于Redux。在NgRx中,状态是由一个包含action和reducer的函数的映射组成的。Reducer函数经由action的分发以及当前或初始的状态而被调用,最后由reducer返回一个不可变的状态。你可以在@ngrx/store中找到我们将在下面的例子中讨论到的相关的API。

Action: Action是状态的改变。它描述了某个事件的发生,但是没有指定应用的状态如何改变。

ActionReducerMapActionReducerMap注册了一系列的reducer,在应用中使用StoreModule对它进行配置。

ActionReducer: 它被用于创建reducer,例如logger。

MetaReducer: 在应用中使用StoreModule配置的MetaReducer构成了根的meta-reducer。

StoreModule: StoreModule@ngrx/storeAPI中的一个模块,它被用来在应用模块中配置reducer。

createFeatureSelector: 它为状态(state)创建一个feature selector。

createSelector: 它创建一个selector用于生成一个指定的状态。

Store: 它提供了Store.select()Store.dispatch()来与reducer协同工作。Store.select()用于选择一个selector,Store.dispatch()用于向reducer分发action的类型。

1. 使用到的技术

下面是我们的例子中用到的技术:

  1. Angular 5.0.0
  2. Angular CLI 1.5.0
  3. NgRx/Store 4.1.1
  4. TypeScript 2.4.2
  5. Node.js 6.11.0
  6. NPM 3.10.10

    2. 安装Angular CLI和NgRX/Store

  7. 确保已安装的Node和NPM的最低版本为:Node 6.9.x和NPM 3.x.x
  8. 在命令行中输入以下命令:
    npm install -g @angular/cli
  9. 运行以下命令生成一个新的项目:
    ng new my-app
  10. 现在安装@ngrx/store。使用命令行进入my-app目录,然后运行如下命令:
    npm i @ngrx/store --save

    现在我们已经准备好使用NgRx/Store和Angular了。

    3. 创建State

    State是一个单独的不可变的数据结构。我们会像如下这样创建state:

    export interface AppState {
    articleState: ArticleState;
    }
    export interface ArticleState {
    articles: Article[];
    }

    4. 创建Action类

    NgRx的Action描述了状态的变化。对于每一个action,我们都需要创建一个继承自Action的类,同时定义其type和payload(payload是个可选参数)。

    ```

    export const JAVA = ‘Java‘;

    export const MY_ARTICLES = ‘Favorite_Articles‘;

export class JavaArticlesAction implements Action {

readonly type = JAVA;

}

export class FavoriteArticlesAction implements Action {

readonly type = MY_ARTICLES;

constructor(public payload: Article[]) {}

}

####5. 创建Reducer
Reducer描述了任何一个action所对应的应用的state将怎样变化。reducer创建如下:

export function reducer(state = initialState, action: fromActions.All): ArticleState {

switch(action.type) {

case fromActions.JAVA: {

return {articles: JAVA_ARTICLES};

}

case fromActions.ANGULAR: {

return {articles: ANGULAR_ARTICLES};

}
case fromActions.MY_ARTICLES: {
  return {articles: action.payload};
}
default: {
  return state;
}

}

}

####6. 使用createFeatureSelector和createSelector()
`createFeatureSelector()`被用于为任意指定的state创建一个feature selector。

export const getArticleState = createFeatureSelector

`createSelector()`使用feature selector来创建selector。

export const getArticles = createSelector(

getArticleState,

(state: ArticleState) => state.articles

);

####7. 使用ActionReducerMap
`ActionReducerMap`注册了reducer。我们需要在我们配置我们的reducer的地方创建一个 `ActionReducerMap`的常量。然后在应用模块中使用`StoreModule`来配置这个常量。

export const reducers: ActionReducerMap

####8.使用ActionReducer
`ActionReducer`用来创建类似logger的reducer,使用`MetaReducer`对它进行配置。

export function logger(reducer: ActionReducer

通过使用上面的代码,我们可以在控制台中获取每个action的状态和名称。
####9.使用`MetaReducer`
 `MetaReducer`由我们所创建的一系列`ActionReducer`所组成。在应用中使用`StoreModule`配置的`MetaReducer`构成了根meta-reducer。`@ngrx/store`默认使用 `combineReducers`在创建根meta-reducer。

export const metaReducers: MetaReducer

####10. 使用StoreModule
`StoreModule`是`@ngrx/store`API中的一个模块,它被用来在应用模块中配置reducer。

@NgModule({

imports: [

---

StoreModule.forRoot(reducers, {metaReducers})

]

---

})

####11. 使用`Store.select()`和`Store.dispatch()`
`Store.select()`和 `Store.dispatch()`与是reducer配合使用的。`Store.select()`用于选择一个selector,`Store.dispatch()`用于向reducer分发action的类型。
要使用`Store`, 在组件中创建一个`Observable`类型的属性。

articles: Observable

现在使用依赖注入来实例化`Store`,然后选择一个selector。

constructor(private store: Store

现在分发这个action以通过reducer改变state。

showJavaArticles(){

this.store.dispatch(new fromActions.JavaArticlesAction());

}

####12. 完整的例子
下面是我们的例子的项目结构:

my-app

|

|--src

| |

| |--app

| | |

| | |--actions

| | | |

| | | |--article.actions.ts

| | |

| | |--components

| | | |

| | | |--article.component.html

| | | |--article.component.ts

| | |

| | |--models

| | | |

| | | |--article.ts

| | |

| | |--reducers

| | | |

| | | |--app.states.ts

| | | |--article.reducer.ts

| | | |--reducers.ts

| | |

| | |--app.component.ts

| | |--app.module.ts

| |

| |--main.ts

| |--index.html

| |--styles.css

|

|--node_modules

|--package.json

以下是完整的代码:
**article.actions.ts**

import { Action } from ‘@ngrx/store‘;

import { Article } from ‘../models/article‘;

export const JAVA = ‘Java‘;

export const ANGULAR = ‘Angular‘;

export const MY_ARTICLES = ‘Favorite_Articles‘;

export class JavaArticlesAction implements Action {

readonly type = JAVA;

}

export class AngularArticlesAction implements Action {

readonly type = ANGULAR;

}

export class FavoriteArticlesAction implements Action {

readonly type = MY_ARTICLES;

constructor(public payload: Article[]) {}

}

export type All = JavaArticlesAction | AngularArticlesAction | FavoriteArticlesAction;

**article.ts**

export interface Article {

id: number;

title: string;

category: string;

}

export const JAVA_ARTICLES: Article[] = [

{id: 1, title: ‘Java Article 1‘, category: ‘Java‘},

{id: 2, title: ‘Java Article 2‘, category: ‘Java‘},]

export const ANGULAR_ARTICLES: Article[] = [

{id: 1, title: ‘Angular Article 1‘, category: ‘Angular‘},

{id: 2, title: ‘Angular Article 2‘, category: ‘Angular‘},]

export const FAVORITE_ARTICLES: Article[] = [

{id: 1, title: ‘Java Article 1‘, category: ‘Java‘},

{id: 2, title: ‘Angular Article 2‘, category: ‘Angular‘}]

**app.states.ts**

import { Article } from ‘../models/article‘;

export interface AppState {

articleState: ArticleState;

}

export interface ArticleState {

articles: Article[];

}

**article.reducer.ts**

import { createFeatureSelector, createSelector } from ‘@ngrx/store‘;

import * as fromActions from ‘../actions/article.actions‘;

import { JAVA_ARTICLES, ANGULAR_ARTICLES } from ‘../models/article‘;

import { ArticleState } from ‘./app.states‘;

export const initialState: ArticleState = { articles: []};

export function reducer(state = initialState, action: fromActions.All): ArticleState {

switch(action.type) {

case fromActions.JAVA: {

return {articles: JAVA_ARTICLES};

}

case fromActions.ANGULAR: {

return {articles: ANGULAR_ARTICLES};

}
case fromActions.MY_ARTICLES: {
  return {articles: action.payload};
}
default: {
  return state;
}

}

}

export const getArticleState = createFeatureSelector

export const getArticles = createSelector(

getArticleState,

(state: ArticleState) => state.articles

);

**reducer.ts**

import { ActionReducerMap, ActionReducer, MetaReducer } from ‘@ngrx/store‘;

import { AppState } from ‘./app.states‘;

import * as articleReducer from ‘./article.reducer‘;

import { environment } from ‘../../environments/environment‘;

export const reducers: ActionReducerMap

export function logger(reducer: ActionReducer

export const metaReducers: MetaReducer

**article.component.ts**

import { Store } from ‘@ngrx/store‘;

import { Component } from ‘@angular/core‘;

import { Observable } from ‘rxjs/Observable‘;

import * as articleReducer from ‘../reducers/article.reducer‘;

import * as fromActions from ‘../actions/article.actions‘;

import { ArticleState } from ‘../reducers/app.states‘;

import { Article, FAVORITE_ARTICLES } from ‘../models/article‘;

@Component({

selector: ‘app-article‘,

templateUrl: ‘article.component.html‘

})

export class ArticleComponent {

articles: Observable

constructor(private store: Store<ArticleState>) {
    this.articles = store.select(articleReducer.getArticles);
}
showJavaArticles(){
    this.store.dispatch(new fromActions.JavaArticlesAction());
}
showAngularArticles(){
    this.store.dispatch(new fromActions.AngularArticlesAction());
}
showFavoriteArticles(){
    this.store.dispatch(new fromActions.FavoriteArticlesAction(FAVORITE_ARTICLES));
}

}

**article.component.html**

Java Articles
Angular Articles
Favorite Articles

  • {{article.id}} - {{article.title}} - {{article.category}}
**app.component.ts**

import { Component } from ‘@angular/core‘;

@Component({

selector: ‘app-root‘,

template: <app-article></app-article>

})

export class AppComponent {

}

**app.module.ts**

import { NgModule } from ‘@angular/core‘;

import { BrowserModule } from ‘@angular/platform-browser‘;

import { StoreModule } from ‘@ngrx/store‘;

import { AppComponent } from ‘./app.component‘;

import { ArticleComponent } from ‘./components/article.component‘;

import { reducers, metaReducers } from ‘./reducers/reducers‘;

@NgModule({

imports: [

BrowserModule,

StoreModule.forRoot(reducers, {metaReducers})

],

declarations: [

AppComponent,

ArticleComponent

],

providers: [

],

bootstrap: [

AppComponent

]

})

export class AppModule { }

```

下载源代码

原文地址:NgRx/Store 4 + Angular 5 Tutorial

本文由本人原创翻译,转载请注明出处:https://www.jianshu.com/p/c2d61fc76128

原文地址:https://www.cnblogs.com/neromaycry/p/8542302.html

时间: 2024-10-03 20:40:46

NgRx/Store 4 + Angular 5使用教程的相关文章

[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

[Angular] Extract Implementation Details of ngrx from an Angular Application with the Facade Pattern

Extracting away the implementation details of ngrx from your components using the facade pattern creates some interesting possibilities in terms of iteratively migrating an application to ngrx. By decoupling your components from ngrx completely, this

[Angular2] @Ngrx/store and @Ngrx/effects learning note

Just sharing the learning experience related to @ngrx/store and @ngrx/effects. In my personal opinion, I fell there are tow different types of coding style by using @ngrx/store only @ngrx/store + @ngrx/effects So How we do with only ngrx/store? Contr

Angular 4入门教程系列 1 运行在Docker中的HelloWorld

Angular作为目前前端的一个重要选择,加之背后站着google,得到了越来越多的开发者的青睐.但是发现没有按照由浅入深地实例化的教程,虽然官网的教程已经不错,但是初始入门的细节没有提到,再加之网络等问题,决定把官网的教程替大家做一遍给大家留个笔记.同时可能会结合docker进行使用,当然没有安装docker也完全没有关系,同样执行就可以了. 事前准备 OS [root@angular docker]# uname -a Linux angular 3.10.0-514.el7.x86_64

Angular CLI 使用教程指南参考

Angular CLI 现在虽然可以正常使用但仍然处于测试阶段. Angular CLI 依赖 Node 4 和 NPM 3 或更高版本. 安装 要安装Angular CLI你需要先安装node和npm,然后运行以下命令来安装最新的Angular CLI: 注意:Angular CLI 需要Node 4.X 和 NPM 3.X 以上的版本支持. npm install -g angular-cli 在 Mac 或 Linux 平台上,你可能需要添加sudo前缀提权进行全局安装: sudo npm

Angular.js入门教程

简单介绍 AngularJS是为了克服HTML在构建应用上的不足而设计的.首先Html是一门很好的为静态文本展示设计的声明式语言,但要构建WEB应用的话它就显得乏力了. 通常,我们可以通过以下技术来解决决静态网页技术在构建动态应用上的不足: 1.类库 - 类库是一些函数的集合,它能帮助你写WEB应用.起主导作用的是你的代码,由你来决定何时使用类库.例如jQuery等 2.框架 - 框架是一种特殊的.已经实现了的WEB应用,你只需要对它填充具体的业务逻辑.这里框架是起主导作用的,由它来根据具体的应

手把手教你用ngrx管理Angular状态

本文将与你一起探讨如何用不可变数据储存的方式进行Angular应用的状态管理 :ngrx/store--Angular的响应式Redux.本文将会完成一个小型简单的Angular应用,最终代码可以在这里下载. Angular应用中的状态管理 近几年,大型复杂Angular/AngularJS项目的状态管理一直是个让人头疼的问题.在AngularJS(1.x版本)中,状态管理通常由服务,事件,$rootScope混合处理.在Angular中(2+版本),组件通信让状态管理变得清晰一些,但还是有点复

[Angular] NgRx/effect, why to use it?

See the current implementaion of code, we have a smart component, and inside the smart component we are using both 'serivce' and 'store'. In the large application, what we really want is one service to handle the application state instead of two or m

Angular vs React 最全面深入对比

如今,Angular和React这两个JavaScript框架可谓红的发紫,同时针对这两个框架的选择变成了当下最容易被问及或者被架构设计者考虑的问题,本文或许无法告诉你哪个框架更优秀,但尽量从更多的角度去比较两者,尽可能的为你在选择时提供更多的参考意见. 选择的方法 在选择之前,我们尝试带着一些问题去审视你将要选择的框架(或者是任何工具),尝试用这些问题的答案来帮助我们更加了解框架,也更加让选择变得更容易 框架本身的问题: 是否成熟?谁在背后支持呢? 具备的功能? 采用什么架构和模式? 生态系统