如何通过 {{{ }}}(模板助手)将操作绑定到 ember 模板中的标记?

How to bind actions to markup in ember template by {{{ }}} (Template helper)?

我正在构建带有 onclick 操作的标记字符串,如下所示。

    helpInfoMarkup: computed('levelInfo.name', function() {
       return '<a class="help-text" {{action "switchContext"}}' + get(this, 'levelInfo.name') + '</a>';
    }

我的 .hbs 文件

<div>{{{helpInfoMarkup}}}</div>

然而,这不绑定到 ember 操作,只是作为标记的一部分出现并且不起作用?对此有什么想法吗?

这是行不通的,因为 glimmer 渲染引擎(ember 使用)不对字符串进行操作。 相反,您的 ember 模板在构建期间被编译为二进制格式,稍后在运行时 glimmer 将直接生成 DOM,而不是 HTML 字符串。

这意味着您永远不能将 glimmer 模板作为字符串传递。您 可以 将模板编译器与您的应用程序捆绑在一起(但您不应该这样做)以在浏览器中编译模板,但即使这样您也不能使用它来生成 HTML 字符串表示,因为在此步骤中您丢失了信息(例如动作绑定)。这是因为这些动作绑定从来都不是 HTML 的一部分,但 glimmer 在渲染期间直接将事件侦听器附加到 DOM 节点。通过使用 HTML 字符串和 {{{...}}} 你渲染普通 HTML,而不是微光模板,所以这不会工作。

您应该做的是将所有 HTML 移动到模板并使用一个组件来嵌入它。

唯一的其他可能性是利用 ember-render-modifiers 中的 did-insert 手动附加事件。所以你可以这样做:

<div {{did-insert this.attachSwitchContextAction}}>{{{helpInfoMarkup}}}</div>

然后在您的组件中:

@action
switchContext() {
}

@action
attachSwitchContextAction(elem) {
  elem.addEventListener('click', (...args) => this.switchContext(...args));
}

get helpInfoMarkup() {
  return '<a class="help-text" ' + get(this, 'levelInfo.name') + '</a>';
}

通过这种方式,您可以完全绕过 glimmer 模板引擎,然后退回到手动 DOM 操作。

您可以删除 helpInfoMarkup 计算的 属性 并将您的模板更新为

<div>
  <a class="help-text" {{on "click" this.switchContext}}>{{this.levelInfo.name}}</a>
</div>