如何反应性地使用节点简单模式?

How to use node-simple-schema reactively?

鉴于关于此的示例不多,我将尽我所能遵循 docs,但验证不是被动的。

我声明了一个模式:

import { Tracker } from 'meteor/tracker';
import SimpleSchema from 'simpl-schema';

export const modelSchema = new SimpleSchema({
  foo: { 
    type: String,
    custom() {
      setTimeout(() => {
        this.addValidationErrors([{ name: 'foo', type: 'notUnique' }]);
      }, 100);  // simulate async
      return false;
    }
  }
}, {
  tracker: Tracker
});

然后我在我的组件中使用这个架构:

export default class InventoryItemForm extends TrackerReact(Component) {

  constructor(props) {
    super(props);

    this.validation = modelSchema.newContext();
    this.state = {
      isValid: this.validation.isValid()
    };
  }

  ...

  render() {
    ...
    const errors = this.validation._validationErrors;

    return (
      ...
    )
  }
}

因此,每当我尝试验证 foo 时,都会调用异步的自定义函数,并调用适当的 addValidationErrors 函数,但是当 [=14] 时组件永远不会重新呈现=] 应该是假的。

我错过了什么?

您的代码实际上有两个错误。首先 this.addValidationErrors 不能在自定义验证中异步使用,因为它没有引用正确的验证上下文。其次,TrackerReact只是在render函数内部注册了响应式数据源(比如.isValid),所以仅仅访问其中的_validationErrors是不够的。因此,要使其正常工作,您需要使用命名验证上下文,并在渲染函数(或它调用的其他函数)中调用 isValid,如下所示:

在验证中

custom() {
  setTimeout(() => {
    modelSchema.namedContext().addValidationErrors([
      { name: 'foo', type: 'notUnique' }
    ]);
  }, 100);
}

组件

export default class InventoryItemForm extends TrackerReact(Component) {
  constructor(props) {
    super(props);

    this.validation = modelSchema.namedContext();
  }

  render() {
    let errors = [];
    if (!this.validation.isValid()) {
      errors = this.validation._validationErrors;
    }

    return (
      ...
    )
  }
}

查看有关异步验证的更多信息here