dojo 龙主要 logo

详细的存储概念

State 对象

在现代浏览器中,state 对象作为 CommandRequest 的一部分被传递。对该 state 对象的任何修改都会被转换为相应的补丁操作,并应用到存储中。

import { createCommandFactory } from '@dojo/framework/stores/process';
import { State } from './interfaces';
import { remove, replace } from '@dojo/framework/stores/state/operations';

const createCommand = createCommandFactory<State>();

const addUser = createCommand<User>(({ payload, state }) => {
	const currentUsers = state.users.list || [];
	state.users.list = [...currentUsers, payload];
});

请注意,尝试访问状态在 IE11 中不受支持,并将立即抛出错误。

StoreProvider

StoreProvider 接受三个属性

  • renderer:一个渲染函数,它将存储注入以访问状态并将进程传递给子小部件。
  • stateKey:注册表中状态的键。
  • paths(可选):一个函数,用于将提供程序连接到状态的部分。

失效

StoreProvider 有两种主要方法来触发失效并导致重新渲染。

  1. 推荐的方法是通过将 paths 属性传递给提供程序来注册 path,以确保仅在相关状态更改时才会发生失效。
  2. 当容器没有定义任何 path 时,它将成为一个万能方法,当存储中的任何数据更改时,它都会失效。

Process

生命周期

Process 具有一个执行生命周期,它定义了所定义行为的流程。

  1. 如果存在转换器,它将首先被执行以转换有效负载
  2. before 中间件按顺序同步执行
  3. 命令按定义的顺序执行
  4. 操作在每个命令(或在多个命令的情况下,在每个命令块)执行后从命令中应用
  5. 如果在命令期间抛出异常,则不再执行任何命令,并且当前的操作集不会被应用
  6. after 中间件按顺序同步执行

转换器

通过使用转换器,您可以在进程命令使用有效负载之前修改它。这是一种创建接受不同有效负载的额外进程执行器的方法。

interface PricePayload {
	price: number;
}

const createCommand = createCommandFactory<any, PricePayload>();

// `payload` is typed to `PricePayload`
const setNumericPriceCommand = createCommand(({ get, path, payload }) => {});
const setNumericPrice = createProcess('set-price', [setNumericPriceCommand]);

首先,创建一个转换器,将另一种类型的输入转换为 PricePayload

interface TransformerPayload {
	price: string;
}

// The transformer return type must match the original `PricePayload`
const transformer = (payload: TransformerPayload): PricePayload => {
	return {
		price: parseInt(payload.price, 10)
	};
};

现在只需使用此转换器创建进程即可。

const processExecutor = setNumericPrice(store);
const transformedProcessExecutor = setNumericPrice(store, transformer);

processExecutor({ price: 12.5 });
transformedProcessExecutor({ price: '12.50' });

进程中间件

中间件使用可选的 beforeafter 方法应用于进程周围。这允许在进程定义的行为周围执行通用、可共享的操作。

可以通过提供一个列表来定义多个中间件。中间件按列出的顺序同步调用。

之前

before 中间件块将传递一个 payload 和对 store 的引用。

middleware/beforeLogger.ts

const beforeOnly: ProcessCallback = () => ({
	before(payload, store) {
		console.log('before only called');
	}
});

之后

after 中间件块将传递一个 error(如果发生错误)和进程的 result

middleware/afterLogger.ts

const afterOnly: ProcessCallback = () => ({
	after(error, result) {
		console.log('after only called');
	}
});

result 实现 ProcessResult 接口,以提供有关应用于存储的更改的信息,并提供对该存储的访问权限。

  • executor - 允许对存储运行其他进程
  • store - 对存储的引用
  • operations - 应用的操作列表
  • undoOperations - 可以用来反转应用的操作的操作列表
  • apply - 来自存储的 apply 方法
  • payload - 提供的有效负载
  • id - 用于命名进程的 id

订阅存储更改

Store 具有一个 onChange(path, callback) 方法,它接受一个路径或路径数组,并在该状态更改时调用回调函数。

main.ts

const store = new Store<State>();
const { path } = store;

store.onChange(path('auth', 'token'), () => {
	console.log('new login');
});

store.onChange([path('users', 'current'), path('users', 'list')], () => {
	// Make sure the current user is in the user list
});

Store 还具有一个 invalidate 事件,该事件在存储更改时触发。

main.ts

store.on('invalidate', () => {
	// do something when the store's state has been updated.
});