模板中如何实现 “string === string”?

在我的插件中,我希望在模板中使用一个 if 语句,来判断某个字符串是否匹配特定值。

例如:

{{#each groups as |group|}}
  {{#if group.name === "AwesomeName"}}
      <div>存在匹配!</div>
  {{/if}}
{{/each}}

在 Discourse 中如何实现这一点?


我了解到,直接在模板中使用 {{if}} 在 Ember/Handlebars 中是行不通的。看起来我需要注册一个辅助函数(helper)。类似这样的代码:

plugin/assets/javascripts/discourse/helpers/eq/js/es6

import { registerHelper } from 'discourse-common/lib/helpers';

registerHelper('eq', function(arg1, arg2) {
     if (arg1 === arg2) {
         return true
    } else {
       return false
    }
})

plugin/assets/javascripts/templates/components/my-component.hbs

{{#each groups as |group|}}
  {{#eq group.name "AwesomeName"}}
      <div>存在匹配!</div>
 {{/eq}}
{{/each}}

但这不起作用(没有任何错误提示)。

我尝试了 这里 提供的解决方案,该方法试图使用 “makeBoundHelper”,但对我来说同样无效——我收到了关于 “makeBoundHelper” 不是函数的错误。

我只是希望能够实现一个判断字符串是否匹配特定值的 if 语句。该如何操作?

1 个赞

您想使用 Computed Properties - The Object Model - Ember Guides

不过,请查看 Discourse 的源代码以了解其特定的代码风格。

2 个赞

计算属性很有趣,但我没看出它们与我当前关注点之间的联系。

在我的示例中,关键属性是 group.name,我希望在模板中判断该属性是否等于 “AwesomeName”。我不确定计算属性如何能绕过在模板中使用某种特定 {{if}} 语句的需求,而我一直未能找到解决方法。

Handlebars 模板仅支持基本的布尔逻辑。您可以使用它来检查属性是否为 真值

若要执行更复杂的逻辑,您需要在与模板关联的 Ember JS 文件中实现该逻辑。

例如,如果您有一个位于 templates/components/my-component.hbs 的模板,则必须使用 components/my-component.js 文件来进行计算。

在该文件中,您可以这样写:

import discourseComputed from "discourse-common/utils/decorators";
import Component from "@ember/component";

export default Component.extend({
  @discourseComputed("string1", "string2")
  property(string1, string2) {
    return string1 === string2;
  }
});

property 只是一个函数名称,您可以根据需要更改为任何名称。

然后在模板中,您可以这样写:

{{#if property}}
  blah blah...
{{/if}}

这将从 JS 文件中获取计算属性,并且仅当 property 返回 true 时,才显示 #if 块中的内容。

4 个赞

谢谢,这帮助澄清了很多问题。

我还没有完全让它运行起来——部分原因是我找不到关于使用计算属性来执行此类操作的示例。

在我的情况下,在我的插件中,我正在组索引模板中进行修改。因此,在文件 plugin/assets/javascripts/discourse/groups/index.hbs 中(我把整个组索引代码放在那里,并在其基础上添加更改)。

你的意思是,计算属性的 JS 代码应该放在我创建的文件 plugin/assets/javascripts/discourse/groups/index.js 中吗?或者我可以直接将代码放在一个初始化器(initializer)中?

这是我尝试实现你所描述内容的最佳方案——这是你心目中的样子吗:

js:

export default Component.extend({
  @discourseComputed("group.name", "Amazing_Name")
  property(group.name, Amazing_Name) {
    return group.name === Amazing_Name
  }
})

hbs:

 {{#if property}}
    <div>是的,有匹配!</div>
 {{/if}}

还是你的意思是,我应该字面上在 @discourseComputed 中输入通用值如 “string1” 和 “string2”,然后将模板改为 {{#if property group.name "Amazing_Name"}}?(只有这样才能让模板中的每个值都是动态的。)

我还没有让这两种方法中的任何一种完全运行起来。

感谢你的帮助。

2 个赞

你成功实现了吗?我迫切需要一个详细的示例,说明具体该怎么做(添加什么内容、放在哪个文件中,以及如果相关的话,在该文件中的具体位置)。

1 个赞

我自己其实从未成功实现过这个功能,只能作罢。花这么多时间在一个通常属于基础编程练习的问题上,显得有些徒劳。就我的情况而言,问题很可能出在几处语法错误上,但我始终没有找到完整的可运行示例。如果能提供一个完整的可运行示例,展示如何实现 if string === string,我将不胜感激。

2 个赞