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... 但问题来了,假如项目特别大,组件之间的通讯可能会变得十分复杂... 这个时候了我们 ...
随机推荐
- JavaScript 编码规范(中文/Airbnb公司版)
Airbnb 是一家位于美国旧金山的公司,本文是其内部的 JavaScript编码规范,写得比较全面,在 Github 上有 16,686 + Star,3,080 + fork,前端开发人员可参考. ...
- vue中Axios请求豆瓣API数据并展示到Swipe中
vue中Axios请求豆瓣API数据并展示到Swipe中 1.首先是安装Axios: 安装方法cnpm install axios --save 等待npm安装完毕: 2.在main.js中引入axi ...
- armeabi和armeabi-v7a(转)
在ANE中如果SDK调用了so库,则需要把so库放到ANE下Android-ARM/lib/armeabi (调试模式)或者 armeabi-v7a(发行模式)下. 可以贴个ADT代码说明问题: // ...
- Oracle11g登录名和密码不区分大小写
问题描述: oracle11g对账户密码实行大小写识别,烦的一比!想移除此限制 问题解决: oracle 11g以前的版本的用户名和密码是不区分大小写!oracle 11g 用户名和密码默认区分大小写 ...
- 虚拟机centos 7联网设置之NAT方式
第一步在设置虚拟机的连接模式为NAT,虚拟机是VMware12的版本 第二步在PC主机上设置网络共享 第三步将虚拟机网卡开启,默认关闭状态,开启网卡 ip link set ens32 up (ens ...
- 安装astrixx firefox插件
以上步骤适用于firefox 45.0.1. 将astrixx的firefox插件下载到本地,这个插件的下载地址很难找...全名是astrixx proxy switcher about:config ...
- 配置Django
第一步,安装Python,在这里下载,如果你安装在C:\Python27, 把C:\Python27;C:\Python27\Scripts;C:\Python27\Lib 加到你的Path 第二步: ...
- java中的数据加密3 非对称加密
非对称加密也加公钥加密,不对称算法使用一对密钥对,一个公钥,一个私钥,使用公钥加密的数据,只有私钥能解开(可用于加密):同时,使用私钥加密的数据,只有公钥能解开(签名).但是速度很慢(比私钥加密慢10 ...
- 【C】——实现tree命令
在大部分的linux系统中有一个很好用的命令——tree,就是显示目录的结构,但是发现在FreeBSD中没有这个命令,因此自己实现了一个简单的tree.代码如下:主要利用了递归的思想. #includ ...
- React Native - FlexBox弹性盒模型
FlexBox布局 1. 什么是FlexBox布局? 弹性盒模型(The Flexible Box Module),又叫FlexBox,意为"弹性布局",旨在通过弹性的方式来对 ...