ngxs 状态管理器
简单的安装 @ngxs/schematics
$ ng add @ngxs/schematics
$ ng g ngxs-sk --spec // 会生成一个 src/store 文件
- 配置 src/store 下的config文件 (完成todo)。
- 在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 状态管理器的更多相关文章
- vue状态管理器(用户登录简单应用)
技术点:通过vue状态管理器,对已经登录的用户显示不同的页面: 一 vue之状态管理器应用 主要用来存储cookie信息 与vue-cookies一起使用 安装:npm install vue-co ...
- VueX状态管理器 的应用
VueX状态管理器 cnpm i vuex axios -S 1 创建Vuex 仓库 import Vue from 'vue' import Vuex from 'vuex' vue.use(Vue ...
- 对于React各种状态管理器的解读
首先我们要先知道什么是状态管理器,这玩意是干啥的? 当我们在多个页面中使用到了相同的属性时就可以用到状态管理器,将这些状态存到外部的一个单独的文件中,不管在什么时候想使用都可以很方便的获取. reac ...
- vue - 状态管理器 Vuex
状态管理 vuex是一个专门为vue.js设计的集中式状态管理架构.状态?我把它理解为在data中的属性需要共享给其他vue组件使用的部分,就叫做状态.简单的说就是data中需要共用的属性.
- vue项目--vuex状态管理器
本文取之官网和其他文章结合自己的理解用简单化的语言表达.用于自己的笔记记录,也希望能帮到其他小伙伴理解,学习更多的前端知识. Vuex 是什么? Vuex 是一个专为 Vue.js 应用程序开发的状态 ...
- Vue中的状态管理器 - Vuex
我们知道vue是组件式开发的,当你的项目越来越大后,每个组件背后的数据也会变得越来越难以理顺, 这个时候你就可以考虑使用vuex了. 备注: 官方建议小项目不要使用,引入vuex会带来新的概念和模式, ...
- Flutter: MobX和flutter_mobx状态管理器
MobX.dart网站上的 " 入门指南" mobxjs video 组织Stores 安装依赖 dependencies: mobx: flutter_mobx: dev_dep ...
- vuex状态管理,state,getters,mutations,actons的简单使用(一)
之前的文章中讲过,组件之间的通讯我们可以用$children.$parent.$refs.props.data... 但问题来了,假如项目特别大,组件之间的通讯可能会变得十分复杂... 这个时候了我们 ...
- 组件之间的通讯:vuex状态管理,state,getters,mutations,actons的简单使用(一)
之前的文章中讲过,组件之间的通讯我们可以用$children.$parent.$refs.props.data... 但问题来了,假如项目特别大,组件之间的通讯可能会变得十分复杂... 这个时候了我们 ...
随机推荐
- DockOne技术分享(二十):Docker三剑客之Swarm介绍
[编者的话]Swarm项目是Docker公司发布三剑客中的一员,用来提供容器集群服务,目的是更好的帮助用户管理多个Docker Engine,方便用户使用,像使用Docker Engine一样使用容器 ...
- 原创:vsphere概念深入系列三:vSphere命令行管理
假设无法近距离接触物理主机,只能远程命令行管理,. 以下命令行可以起到点作用. 首先需要安装vSphere CLI工具. 启动后界面: 1.查看datastore内容 所有命令行工具都可以加上-ser ...
- llvm Array Bounds Check Elimination
http://www.knosof.co.uk/vulnerabilities/arraybnd.html http://www.cs.utsa.edu/dmz/techrep/2010/CS-TR- ...
- Djnogo Web开发学习笔记(2)
安 装 截止目前,https://www.djangoproject.com/download/提供的最新的Django的下载版本为1.6.4. Install Django You’ve got ...
- jQuery动态添加删除与添加表行代码
具体实现代码如下: table的HTML如下: 代码如下 复制代码 <input type="button" value="添加一行" />< ...
- sringboot项目在tomcat上的部署
sringboot项目在tomcat上的部署原文链接: https://blog.csdn.net/zhaoyahui_666/article/details/78283559#comments 20 ...
- Android webview clearHistory 不符合逾期的解决办法
目前在业务开发中有这么一个需求,切换不同的 Fragment, 切换回 WebView 的Fragment时候,要求是打开的初始页面,然后我在 onHiddenChanged() 方法中加载默认地址, ...
- 【Linux高级驱动】rtc驱动开发
[1.分层思想] 1.1 rtc-dev.c //设备接口层,功能:给用户提供接口 subsys_initcall(rtc_init); , RTC_DEV_MAX, "rtc&qu ...
- java框架篇---hibernate之连接池
Hibernate支持第三方的连接池,官方推荐的连接池是C3P0,Proxool,以及DBCP.在配置连接池时需要注意的有三点: 一.Apche的DBCP在Hibernate2中受支持,但在Hiber ...
- android平台的三个编译命令——make,mm,mmm
在Android源码根目录下,执行以下三步即可编译android: 1. build/envsetup.sh #这个脚本用来设置android的编译环境; 2. lunch #选择编译目标 3 ...