Template.instance() 和上下文与 Blaze 块助手混淆

Template.instance() and context messed with with Blaze block helpers

我正在使用一个简单的模板块助手来显示加载动画,隐藏其中的任何内容。这对提交表单和防止按钮被按两次非常有帮助。

<template name="waiting">
  {{#if isLoading}}
      {{> loader}}
  {{else}}
    {{> UI.contentBlock}}
  {{/if}}
</template>

我决定将它放在一个块助手中,因为我以前从未尝试过它并且我想让我的代码保持干燥 -- 我在几个地方使用这个模式。

我 运行 使用此块助手访问 Template.instance() 不是块助手而是它所在的模板的问题。我也 运行 遇到模板上下文的问题。以下是我的问题的详细信息:

我正在设置一个确认删除按钮,如下所示:

  {{#waiting isLoading=loadingDelete}}
    {{#if confirmDelete}}
      <button class="confirm">Are you sure?</button>
    {{else}}
      <button class="delete">Delete</button>
    {{/if}}
  {{/waiting}}

我还将 loadingDeleteconfirmDelete 反应变量放入模板实例中,这样我就不会污染 Session:

Template.editRecord.created = ->
  @loadingDelete = new ReactiveVar(false)
  @confirmDelete = new ReactiveVar(false)

Template.editRecord.helpers
  loadingDelete: () -> Template.instance().loadingDelete.get()
  confirmDelete: () -> Template.instance().confirmDelete.get()

然后我创建一些这样的事件:

'click .delete': (e,t) -> t.confirm.set(真)

'click .confirm': (e,t) -> t.loadingDelete.set(真) _id = @_id Meteor.call 'deleteRecord', _id, (err) -> t.loadingDelete.set(假) 如果错误 console.log 错了 别的 Router.go"home"

此实现的问题在于 Template.instance() 在此处引用 confirmDelete 帮助程序中的等待模板:

confirmDelete: () -> Template.instance().confirmDelete.get()

第二个问题是事件中的数据上下文是指等待模板的上下文,因此我需要使用_id = Template.parentData()_id而不是_id = @_id。但是我无法从这里访问 editRecord 模板实例或其任何变量,这令人沮丧。

我将模板更改为此,这解决了第一个问题。

  {{#if confirmDelete}}
    <button class="confirm">Are you sure?</button>
  {{else}}
    {{#waiting isLoading=loadingDelete}}
      <button class="delete">Delete</button>
    {{/waiting}}
  {{/if}}

但这很丑陋,不是我想要的。我希望只是用这个块助手替换我的 #if 块,但我最终写了更多的代码,同时试图用我的模板进行 DRY。这似乎不对。

我注意到 #if 块不会导致这些上下文和模板实例问题。有什么我想念的吗?

事实证明,Meteor 团队已经认识到这个错误并正在努力修复它。看到这个 PR.