.gjs ファイルでモバイル表示用の異なるコンテンツを表示する

カスタムテーマコンポーネントを非推奨通知後の新しい標準に更新しようとしていますが、この設定でモバイルユーザー向けに異なるものを表示する方法がわかりません。

テーマガイドにはこれに関する言及はなく、見つけた唯一の関連投稿は api.renderInOutlet not rendering? - #3 by NateDhaliwal で、this.site.mobileView を使用しているため、次のようなものが機能するはずだと想定していました。

import { apiInitializer } from "discourse/lib/api";

export default apiInitializer("1.8.0", (api) => {
  api.renderInOutlet(
    "composer-after-save-or-cancel",
    `<template>
      {{#if this.site.mobileView}}
      Mobile!
      {{else}}
      Normal!
      {{/if}}
    </template>`
  );
});

しかし、常に通常のコンテンツしか表示されません…明らかに基本的な何かを見落としています…

何かヒントがあれば教えてください!

おそらく site サービスを手動でインポートする必要があるでしょう。

import { apiInitializer } from "discourse/lib/api";

export default apiInitializer("1.8.0", (api) => {
  const site = api.container.lookup("service:site");
  api.renderInOutlet(
    "composer-after-save-or-cancel",
    <>
      {{#if site.mobileView}}
      モバイル!
      {{else}}
      通常!
      {{/if}}
    </>
  );
});
「いいね!」 3

@service site; も機能しますか?

いいえ。@service デコレーターは、コンポーネントやサービスなどの Ember クラスでのみ利用可能です。\u003ctemplate\u003e...\u003c/template\u003e が個別のコンポーネントとしてリファクタリングされた場合、デコレーターを使用できます。apiInitializer() は単なる関数であるため、サービスには通常の JS のようにアクセスする必要があります。

Ember object ownership (getOwner, service injections, etc.) を参照してください。

「いいね!」 1

お好みで、renderInOutlet 呼び出し内にクラス全体を配置することもできます。

import { apiInitializer } from "discourse/lib/api";
import Component from "@glimmer/component";
import { service } from "@ember/service";

export default apiInitializer((api) => {
  api.renderInOutlet(
    "composer-after-save-or-cancel",
    class extends Component {
      @service site;

      <template>
        {{#if this.site.mobileView}}
          Mobile!
        {{else}}
          Normal!
        {{/if}}
      </template>
    }
  );
});

しかし、.lookup() ソリューションも妥当です。結局のところ、@service は舞台裏で同じことを行っていますからね :ok_hand:

「いいね!」 6

ありがとうございます、これで動作します!

また、(少なくともこの種の)モダンなJSが、私が以前(2010年代初頭)働いていたエンタープライズJavaにますます似てきているのは面白いですね :smiley: