Skip to content

校验

AutoStore内置校验机制,当写入状态值时可以对写入值进行校验,并根据校验结果执行相应的行为。

AutoStore通过以下参数来为状态的写入提供校验。

  • onInvalid
  • validate
  • validators

基本用法

ts
import { AutoStore } from "autostore";
const store = new AutoStore(
    {
        order: {
            price: 100,
        },
    },
    {
        validate: (newValue, oldValue, path) => {
            if (path[1] === "price") {
                return newValue > 10;
            }
        },
    },
);

指南

校验函数

validate函数在写入状态前执行,函数类型如下:

ts
interface StateValidatorFunction<State extends Dict> {
    (this: AutoStore<State>,
    newValue: any,       // 新值
    oldValue: any,       // 旧值
    path: string[]       // 路径
) => boolean;
    getErrorMessage?: (error: Error) => string;
    onInvalid?: ValidationBehavior;
}
  • validate函数通过返回true/false来代表校验成功或失败。
  • validate函数也可以通过throw ValidateError('错误信息')来代表校验出错且提供出错信息。
ts
import { AutoStore, ValidateError } from "autostore";
const store = new AutoStore(
    {
        order: {
            price: 100,
        },
    },
    {
        validate: (newValue, oldValue, path) => {
            if (path[1] === "price") {
                if (newValue > 10) {
                    return true;
                } else {
                    throw new ValidateError("价格必须大于10");
                }
            }
        },
        id: "mystore",
    },
);

try {
    store.state.order.price = 1;
} catch (e) {
    console.log(e); // ValidateError
}

校验错误信息

  • 保存错误信息

默认情况下,当校验失败时,错误信息可以通过以下途径获取:

  • store.errors

    类型:Record<string,string>key为路径名称,value为错误信息字符串(即error.message)。 上例中校验失败时store.errors['order.price']==='价格必须大于10'

  • configManager.errors

    当启用配置管理器时,错误信息也会保存到配置管理器中。 上例中校验失败时AutoStoreConfigManager.errors['mystore.order.price']==='价格必须大于10' 关于配置管理器的更多信息见配置系统

  • 定制校验错误信息

默认情况下,校验错误信息取自error.message || error.stack。 因此,可以通过在validate函数中触发包含友好信息的错误来提供更加友好的错误信息。

校验失败行为

可以通过onInvalid参数来控制当校验失败时的行为。

onInvalid取值如下:

默认 说明
throw 会触发ValidateError错误
ignore 静默忽略,即不触发错误,也不写入
pass 继续写入,不抛出错误
throw-pass 继续写入,然后再触发ValidateError错误

onInvalid参数可以通过以下几种方式指定:

全局行为

全局onInvalid参数

ts
import { AutoStore, ValidateError } from "autostore";
const store = new AutoStore(
    {
        order: {
            price: 100,
        },
    },
    {
        validate: (newValue, oldValue, path) => {
            if (path[1] === "price") {
                if (newValue > 10) {
                    return true;
                } else {
                    throw new ValidateError("价格必须大于10");
                }
            }
        },
        onInvalid: "throw-pass",
    },
);

try {
    store.state.order.price = 1;
} catch (e) {
    console.log(e); // 会触发ValidateError
}
//  store.state.order.price === 1;

更新时指定

store.update时指定onInvalid

onInvalid参数也可以在store.update时覆盖全局onInvalid参数,如下:

ts
store.update((state) => {}, {
    onInvalid: "pass",
});

触发错误时指定

在触发错误时指定

ts
import { AutoStore, ValidateError } from "autostore";
const store = new AutoStore(
    {
        order: {
            price: 100,
        },
    },
    {
        validate: (newValue, oldValue, path) => {
            if (path[1] === "price") {
                if (newValue > 10) {
                    return true;
                } else {
                    const err = new Error("价格必须大于10");
                    err.onInvalid = "pass"; // 优先级最高
                    throw err;
                }
            }
        },
        onInvalid: "throw-pass",
    },
);

临时行为

通过withSchema赋值时临时指定

withSchema用于临时指定一些控制参数以指导更新操作。

ts
import { AutoStore, ValidateError } from "autostore";
const store = new AutoStore(
    {
        order: {
            price: 100,
        },
    },
    {
        validate: (newValue, oldValue, path) => {
            if (path[1] === "price") {
                return newValue > 10;
            }
        },
        onInvalid: "throw-pass", // 全局配置
    },
);
// 临时指定onInvalid
store.state.order.price = withSchema(1, { onInvalid: "pass" });

提示

  • 之所以在校验失败可能也要将错误的值写入到状态中,是因为在某些场景下需要保留错误值,但会显示错误。比如绑定表单时。
  • 错误信息总是可以通过store.errorsconfigManager.errors获取

指定路径校验

可以为指定的路径的状态值单独指定一个校验函数,其优先于onValidate参数。

ts
const store = new AutoStore({
    order:{
        price:100
    }
},{
    validators:{
        'order.price':(newValue,oldValue)=>{
            return newValue>0
        }
         // 允许使用通配符来匹配多个路径
        'order.*.price':(newValue,oldValue)=>{
             return newValue>0
        }
    }
})