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... 但问题来了,假如项目特别大,组件之间的通讯可能会变得十分复杂... 这个时候了我们 ...
随机推荐
- 在 Visual Studio 2010 中配置SharpPcap
最近需要在C#下写一个抓取ARP包的程序,网上找来找去,在C#下只能用SharpPcap来做了.SharpPcap是作者把winPcap用C#重新封装而来的,详细信息见如下的链接. SharpPcap ...
- oracle获取今年在内的前几年、后几年
前几年 select to_char(sysdate, 'yyyy') - level + 1 years from dual connect by level <= num num:即想获取几 ...
- eclipse-在编译项目时js特别慢的问题
eclipse在编译项目时,当项目中导入了很多第三方js库时,eclipse在验证js时会消耗大量的时间,而我们却完全不用考虑那些js是否有错误 步骤: 去除eclipse的JS验证: 1.将wind ...
- 【T05】套接字接口比XTI_TLI更好用
1.用于网络编程的API接口有两种: Berkeley套接字 XTL 2.套接字是加州大学伯克利分校为其Unix操作系统版本开发的,TLI是AT&T(贝尔实验室)为Unix系统V3.0开发的 ...
- 你应该更新的 Java 知识之常用程序库【转载】
在很多人眼中,Java 已经是一门垂垂老矣的语言,但并不妨碍 Java 世界依然在前进.如果你曾离开 Java,云游于其它世界,或是每日只在遗留代码中挣扎,或许是时候抬起头,看看老 Java 中的新东 ...
- [转]Visual Studio 2010 中安装Qt 5.1
截至目前(2013年7月12日)为止,Qt 的最高版本为Qt5.1,在该版本中已经将Qt Creator与Qt Lib集成在一个文件夹中,因此安装的时候较为方便,只需安装一个即可.因为Qt具有超强的可 ...
- Swift udp实现根据端口号监听广播数据(利用GCDAsyncUdpSocket实现)
有个小需求,app需要监听pc广播的数据: 代码实现思路: 使用三方库:CocoaAsyncSocket 1.开启udp监听: udpSocket.beginReceiving() 2.读取udp的数 ...
- mysql中TIMESTAMP设置默认时间为当前时间
在我们保存数据进入到数据库中时多半会使用像php之类的脚本来获取一个时间保存到mysql中,其实在mysql可以直接使用TIMESTAMP 数据类型来实现默认类型了,下面一起来看看. 很多时候,为 ...
- 译:3.RabbitMQ Java Client 之 Publish/Subscribe(发布和订阅)
在上篇 RabbitMQ 之Work Queues (工作队列)教程中,我们创建了一个工作队列,工作队列背后的假设是每个任务都交付给一个工作者. 在这一部分,我们将做一些完全不同的事情 - 我们将向多 ...
- zookeeper的可视化web界面
转载一篇我心中大神有关zookeeper WEB的文章 以前写过一篇zookeeper集群搭建的文章<烂泥:zookeeper集群搭建>,最近在使用activemq集群过程中碰到了一些有 ...