简单的安装 @ngxs/schematics

$ ng add @ngxs/schematics
$ ng g ngxs-sk --spec // 会生成一个 src/store 文件
  1. 配置 src/store 下的config文件 (完成todo)。
  2. 在Core模块中导入NgxsStoreModule模块,没有创建Core就直接在AppModule中导入。

ng6,rxjs6.0.0,ngxs3.0.1

λ ng new ngxs  --style=styl --routing --skip-install
λ cd ngxs
λ yarn
λ yarn add @ngxs/store
λ yarn add @ngxs/logger-plugin @ngxs/devtools-plugin --dev
λ ng g c template1
λ ng g c template2
λ code .

在app下创建 app=>ngxs[actions, models, state] 3个文件夹

models

// model.ts

 //  存储数据模型
export interface Tutorial {
name: string;
url: string;
}

actions

// action.ts

import { Tutorial } from '../models/tutorial.model';

export class AddTutorial {

  // 需要一个唯一的标识
static readonly type = '[TUTORIAL] Add'; // 函数接收的参数
constructor(public payload: Tutorial) { }
} export class RemoveTutorial {
static readonly type = '[TUTORIAL] Remove'; constructor(public payload: string) { }
}

state

// state.ts

import { State, Action, StateContext, Selector } from '@ngxs/store';

// models
import { Tutorial } from '../models/tutorial.model'; // actions
import { AddTutorial, RemoveTutorial } from '../actions/tutorial.actions'; // state
export class TutorialStateModel {
tutorials: Array<Tutorial>;
} @State<TutorialStateModel>({
name: 'tutorials',
defaults: {
tutorials: []
}
})
export class TutorialState {
@Selector()
static getTutorials(state: TutorialStateModel) {
return state.tutorials;
} // 接收一个事件模型
@Action(AddTutorial)
// add(stateContext, arguments)
add({
getState, patchState }: StateContext<TutorialStateModel>,
{ payload }: AddTutorial) {
const state = getState();
patchState({
tutorials: [...state.tutorials, payload]
});
} // 接收一个事件模型
@Action(RemoveTutorial)
remove({
getState, patchState }: StateContext<TutorialStateModel>,
{ payload }: RemoveTutorial) {
patchState({
tutorials: getState().tutorials.filter(a => a.name !== payload)
});
}
}

app.module.ts

import { NgxsModule } from '@ngxs/store';
import { TutorialState } from './ngxs/state/tutorial.state';
import { NgxsReduxDevtoolsPluginModule } from '@ngxs/devtools-plugin';
import { NgxsLoggerPluginModule } from '@ngxs/logger-plugin'; @NgModule({
imports: [
NgxsModule.forRoot([
TutorialState
]),
NgxsReduxDevtoolsPluginModule.forRoot(),
NgxsLoggerPluginModule.forRoot()
]
})
export class AppModule { }

组件内使用数据

import { Component, OnInit } from '@angular/core';

import { Observable } from 'rxjs/observable';

import { Store, Select } from '@ngxs/store';
import { TutorialState } from '../ngxs/state/tutorial.state';
import { Tutorial } from '../ngxs/models/tutorial.model';
import { RemoveTutorial } from '../ngxs/actions/tutorial.actions'; @Component({
selector: 'app-template2',
templateUrl: './template2.component.html',
styleUrls: ['./template2.component.styl']
})
export class Template2Component implements OnInit { // tutorials$: Observable<Tutorial>; // Select 直接映射数据事件
@Select(TutorialState.getTutorials) tutorials$: Observable<Tutorial>; constructor(private store: Store) {
// this.tutorials$ = this.store.select(state => state.tutorials.tutorials);
} delTutorial(name) {
this.store.dispatch(new RemoveTutorial(name));
} ngOnInit() { }
}

模板渲染

<ul *ngIf="tutorials$">
<li *ngFor="let item of tutorials$ | async">
name: {{ item.name}}
<br> url: {{ item.url }}
</li>
</ul>

发出单个字符串

// state.ts
export class TitleModel {
title: string;
} @State<TitleModel>({
name: 'title',
defaults: {
title: 'hello Ajanuw'
}
})
export class TitleState {
@Selector()
static getTitle(state: TitleModel) {
return state.title;
}
} // app.module.ts
import { UsersState , TitleState} from './ngxs-store/state/users.state';
NgxsModule.forRoot([UsersState, TitleState]), // component.ts
import { User, Title } from '../ngxs-store/models/users.model';
@Select(TitleState.getTitle) title$: string; // component.html
<h2> {{ title$ | async }} </h2>

事件触发其他事件

使用状态上下文对象中包含dispatch的函数

// 代码片段

export class UserInfoState {
@Selector()
static userinfs(state: UserInfoModel) {
return state.userinfos;
}
@Action(AddUserInfo)
add(
{ getState, patchState, dispatch }: StateContext<UserInfoModel>,
{ userInfo }: AddUserInfo,
) {
const state = getState();
patchState({
userinfos: [...state.userinfos, userInfo],
});
dispatch(new UserInfoCount()); // 这里
} @Action(UserInfoCount)
count({ getState }: StateContext<UserInfoModel>) {
const state = getState();
console.log(state.userinfos.length);
}
}

异步事件

// promise

export class UserInfoState {
@Action(AddUserInfo)
async add(
{ getState, patchState }: StateContext<UserInfoModel>,
{ userInfo }: AddUserInfo,
) {
const userinfo = await this.checkRepeatName(userInfo); // 硬编码2s后得到结果
const state = getState();
patchState({
userinfos: [...state.userinfos, userinfo],
});
} // 添加用户信息时检查用户名是否已经存在,(具体实现不重要)
private checkRepeatName(userInfo: UserInfo): Promise<UserInfo> {
return new Promise(resolve => {
setTimeout(() => {
resolve(userInfo);
}, 2000);
});
}
}
// Observable

export class UserInfoState {
@Selector()
static userinfs(state: UserInfoModel) {
return state.userinfos;
}
@Action(AddUserInfo)
add(
{ getState, patchState }: StateContext<UserInfoModel>,
{ userInfo }: AddUserInfo,
) {
return this.checkRepeatName(userInfo).pipe(
tap((userinfo: UserInfo) => {
const state = getState();
patchState({
userinfos: [...state.userinfos, userinfo],
});
}),
);
} // 添加用户信息时检查用户名是否已经存在,(具体实现不重要)
private checkRepeatName(userInfo: UserInfo): Observable<UserInfo> {
return of(userInfo).pipe(delay(2000));
}
}

事件回掉

import { Component, OnInit } from "@angular/core";

import { Store, Select } from "@ngxs/store";
import { UserInfoState, UserInfoModel } from "./shared/store/user.state";
import { Observable } from "rxjs";
import { UserInfo } from "./shared/store/user.model";
import { AddUserInfo } from "./shared/store/user.action";
import { FormBuilder, FormGroup, Validators } from "@angular/forms"; const l = console.log;
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.styl"],
})
export class AppComponent implements OnInit {
@Select(UserInfoState.userinfs)
public userinfos$: Observable<UserInfo>; public userinfoFrom: FormGroup = this.fb.group({
name: [
"",
{
validators: [Validators.required],
},
],
age: [
"",
{
validators: [
Validators.required,
Validators.max(100),
Validators.min(18),
],
},
],
});
public get name() {
return this.userinfoFrom.get("name");
}
constructor(private store: Store, private fb: FormBuilder) {} ngOnInit(): void {} public addUserInfo(e: HTMLFormElement): void {
const userinfo: UserInfo = this.userinfoFrom.value;
this.store
.dispatch(new AddUserInfo(userinfo))
.subscribe((v: UserInfoModel) => { // 这里
e.reset();
});
}
}
<div>
<form
action=""
[formGroup]="userinfoFrom"
(ngSubmit)="addUserInfo(form)"
#form
>
<div>
<input type="text" placeholder="name" formControlName="name" /><span
*ngIf="
name.invalid && (name.dirty || name.touched) && !!name.errors.required
"
>name必填</span
>
</div>
<div><input type="number" placeholder="age" formControlName="age" /></div>
<div>
<button type="submit" [disabled]="!userinfoFrom.valid">Submit</button>
</div>
</form>
</div>
<ul>
<li *ngFor="let el of (userinfos$ | async)">{{ el.name }} - {{ el.age }}</li>
</ul>

ngxs 状态管理器的更多相关文章

  1. vue状态管理器(用户登录简单应用)

    技术点:通过vue状态管理器,对已经登录的用户显示不同的页面: 一  vue之状态管理器应用 主要用来存储cookie信息 与vue-cookies一起使用 安装:npm install vue-co ...

  2. VueX状态管理器 的应用

    VueX状态管理器 cnpm i vuex axios -S 1 创建Vuex 仓库 import Vue from 'vue' import Vuex from 'vuex' vue.use(Vue ...

  3. 对于React各种状态管理器的解读

    首先我们要先知道什么是状态管理器,这玩意是干啥的? 当我们在多个页面中使用到了相同的属性时就可以用到状态管理器,将这些状态存到外部的一个单独的文件中,不管在什么时候想使用都可以很方便的获取. reac ...

  4. vue - 状态管理器 Vuex

    状态管理 vuex是一个专门为vue.js设计的集中式状态管理架构.状态?我把它理解为在data中的属性需要共享给其他vue组件使用的部分,就叫做状态.简单的说就是data中需要共用的属性.

  5. vue项目--vuex状态管理器

    本文取之官网和其他文章结合自己的理解用简单化的语言表达.用于自己的笔记记录,也希望能帮到其他小伙伴理解,学习更多的前端知识. Vuex 是什么? Vuex 是一个专为 Vue.js 应用程序开发的状态 ...

  6. Vue中的状态管理器 - Vuex

    我们知道vue是组件式开发的,当你的项目越来越大后,每个组件背后的数据也会变得越来越难以理顺, 这个时候你就可以考虑使用vuex了. 备注: 官方建议小项目不要使用,引入vuex会带来新的概念和模式, ...

  7. Flutter: MobX和flutter_mobx状态管理器

    MobX.dart网站上的 " 入门指南" mobxjs video 组织Stores 安装依赖 dependencies: mobx: flutter_mobx: dev_dep ...

  8. vuex状态管理,state,getters,mutations,actons的简单使用(一)

    之前的文章中讲过,组件之间的通讯我们可以用$children.$parent.$refs.props.data... 但问题来了,假如项目特别大,组件之间的通讯可能会变得十分复杂... 这个时候了我们 ...

  9. 组件之间的通讯:vuex状态管理,state,getters,mutations,actons的简单使用(一)

    之前的文章中讲过,组件之间的通讯我们可以用$children.$parent.$refs.props.data... 但问题来了,假如项目特别大,组件之间的通讯可能会变得十分复杂... 这个时候了我们 ...

随机推荐

  1. SSE图像算法优化系列一:一段BGR2Y的SIMD代码解析。

    一个同事在github上淘到一个基于SIMD的RGB转Y(彩色转灰度或者转明度)的代码,我抽了点时间看了下,顺便学习了一些SIMD指令,这里把学习过程中的一些理解和认识共享给大家. github上相关 ...

  2. 【Java】MyBatis与Spring框架整合(一)

    本文将利用 Spring 对 MyBatis 进行整合,在对组件实现解耦的同时,还能使 MyBatis 框架的使用变得更加方便和简单. 整合思路 作为 Bean 容器,Spring 框架提供了 IoC ...

  3. Main.storyboard: WKWebView before iOS 11.0 (NSCoding support was broken in previous versions)

    在工程里用  故事板写了 wkwebview  如果运行在 ios11以下 就会报这个错误,如果要支持iOS 11 以下的用户,请重写View部分,使用代码调用WKWebView,而不用使用故事版来加 ...

  4. [Aaronyang] 写给自己的WPF4.5 笔记10[层次数据需求处理,TreeView绿色文章1/4]

     我的文章一定要做到对读者负责,否则就是失败的文章  ---------   www.ayjs.net    aaronyang技术分享 AY留言: 文章根据难易,我根据游戏的规则进行了分色,希望读者 ...

  5. HDU 3277 Marriage Match III(并查集+二分答案+最大流SAP)拆点,经典

    Marriage Match III Time Limit: 10000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  6. 关于MYSQL ERROR1045 报错的解决办法

    **问题描述 **ERROR 1045 (28000): Access denied for user ‘root’@’localhost’ (using password: YES)或者ERROR ...

  7. qeephp 记录下

    百度百科: https://baike.baidu.com/item/qeephp/8328612?fr=aladdin 官方地址: http://www.qeephp.cn/app/index.ph ...

  8. react学习笔记1之声明组件的两种方式

    //定义组件有两种方式,函数和类 function Welcome(props) { return <h1>Hello, {props.name}</h1>; } class ...

  9. 【Unity】讯飞语音识别SDK

    1.进入讯飞官网,注册帐号,进入控制台,创建新应用UnityXunfeiDemo,平台选Android.在当前应用这点下载SDK,添加AI能力(添加新服务),选择语音听写,即可下载安卓SDK(下称讯飞 ...

  10. Linux下rar 命令压缩和解压详解

    例1:添加文件或目录到压缩档案中,使用a命令.例如把文件files1添加到abc.rar中,使用a或m命令,a命令把file1文件添加到abc.rar档案中保持原有的file1文件不变,m命令移动fi ...