调用 Meteor.call() 并在 `before: insert` 挂钩中等待

Call Meteor.call() and wait inside `before: insert` hook

场景:

我正在尝试为使用 autoform 的客户插入一个 Appointment,仅当日期不冲突时。下面是获取简要想法的代码。

{{#autoForm id='insertAppointmentForm' collection=appointment type="insert" 
              doc=this validation="browser"}}
    <fieldset>
      <!-- All fields here -->
    </fieldset>
    <button type="submit" class="btnn"> Create </button>
{{/autoForm}} 

我正在将钩子添加到上面的自动表单 insert 代码如下,

var hooksObject = {
  before: {
    insert: function(doc) {
      console.log(doc);
      Meteor.call('checkAppointmentClash', doc, function(error, response){
          if(error){ } else { }
      });
      return doc; // I want to wait here 
    }
  },
  onSuccess: function(formType, result) {},
  onError: function(formType, error) {}
};

AutoForm.addHooks(['insertAppointmentForm'], hooksObject, true);

问题:

这里的问题是,即使 errorMeteor.call() 返回并将 document 插入数据库,表单也会被提交。我知道 Meteor.call() 是异步调用,但如何等待结果呢?只有这样我才想在没有错误的情况下继续提交。

挂钩可以异步工作。来自 documentation:

These functions can perform asynchronous tasks if necessary. If asynchronicity is not needed, simply return the document or modifier, or return false to cancel submission. If you don't return anything, then you must call this.result() eventually and pass it either the document or modifier, or false to cancel submission.

因此代码可能如下所示:

insert: function(doc) {
  // note using () => {} to bind `this` context
  Meteor.call('checkAppointmentClash', doc, (error, response) => {
    if(error) {
      this.result(false);
    } else {
      this.result(doc);
    }
  });
  // return nothing
}

尽管如此,我还是建议您重新考虑您的流程。在钩子中检查 "clash" 是错误的。您应该在 "user entered data" 步骤和 disable/enable "Submit" 按钮上相应地执行此操作。