テンプレートで「string === string」を持つ方法

私のプラグインで、テンプレート内に文字列が特定の値と一致するかどうかを評価する if 文を入れたいと考えています。

例えば、以下のようにしたいです:

{{#each groups as |group|}}
  {{#if group.name === "AwesomeName"}}
      <div>一致しました!</div>
  {{/if}}
{{/each}}

Discourse ではこれをどのように実現できますか?


単純な {{if}} では Ember/Handlebars 環境では動作しないことは理解しています。ヘルパーを登録する必要があるようです。例えば以下のような感じです:

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 テンプレートには基本的なブール論理しか備わっていません。真理値 (truthy values) をチェックすることは可能です。

それ以上の複雑な処理を行うには、テンプレートに関連付けられた Ember JS ファイル内でロジックを実行する必要があります。

例えば、templates/components/my-component.hbs にテンプレートがあるとします。その場合、計算処理を行うには components/my-component.js という 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 ファイルから計算プロパティが取得され、propertytrue を返した場合にのみ #if ブロック内のコンテンツが表示されます。

「いいね!」 4

ありがとうございます、これでだいぶ明確になりました。

まだ完全に動作させることができていません。部分的な理由は、この種の操作を行うために計算プロパティを使用する例が他に見つからないためです。

私の場合、プラグイン内でグループインデックステンプレートを変更しています。具体的には、plugin/assets/javascripts/discourse/groups/index.hbs というファイルです(ここではグループインデックスのコード全体を記述し、その上に変更を加えています)。

おっしゃる計算プロパティの JS は、私が作成する plugin/assets/javascripts/discourse/groups/index.js というファイルに入れる必要があるのでしょうか?それとも、単にイニシャライザーにそのコードを入れるだけでもよいのでしょうか?

これが私があなたのおっしゃることを実装しようとした最善の試みです。これがあなたが意図していたものでしょうか:

js:

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

hbs:

 {{#if property}}
    <div>Yep There is a Match!</div>
 {{/if}}

それとも、@discourseComputed には文字通り一般的な値である “string1” や “string2” を入力し、テンプレートを {{#if property group.name "Amazing_Name"}} のように変更すべきだとおっしゃるのでしょうか?(テンプレート内の各値を動的に扱うためには、その方法しかありません。)

どちらのアプローチもまだ完全に動作させることができていません。

ご協力ありがとうございます。

「いいね!」 2

うまく動作させることができましたか?具体的な例を詳しく教えていただけませんか(どのような内容を、どのファイルに、そしてそのファイルのどこに追加すればよいか、それが関連する場合は)。

「いいね!」 1

実は、私自身もこれをうまく動かすことができず、諦めてしまいました。通常は基本的なコーディング演習で済むものに、これほど時間を費やすのは無意味に思えました。私の場合、おそらく至る所で少しだけ構文が間違っていたのでしょうが、完全に動作する例を見つけることはできませんでした。if string === string のように文字列を比較する完全な動作例についても、もしご共有いただければ大変感謝いたします。

「いいね!」 2