.gjs 파일에서 모바일 뷰에 다른 콘텐츠 표시하기

비공고(deprecation notice) 이후 커스텀 테마 컴포넌트를 새로운 표준으로 업데이트하려는데, 이 설정에서 모바일 사용자에게 다른 콘텐츠를 표시하는 방법을 모르겠습니다.

테마 가이드에는 이에 대한 언급이 없고, 찾은 유일한 관련 게시물은 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>
  );
});

하지만 항상 일반(Normal) 콘텐츠만 표시됩니다… 분명 제가 놓치고 있는 기본적인 부분이 있는 것 같습니다…

힌트가 주시면 감사하겠습니다!

아, 아마도 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",
    <template>
      {{#if site.mobileView}}
      모바일!
      {{else}}
      일반!
      {{/if}}
    </template>
  );
});

@service site;도 동작하나요?

아니요. @service 데코레이터는 컴포넌트나 서비스와 같은 Ember 클래스에서만 사용할 수 있습니다. <template>...</template>이 별도의 컴포넌트로 리팩터링되었다면 데코레이터를 사용할 수 있습니다. apiInitializer()는 단순히 함수이므로, 서비스는 일반적인 JavaScript처럼 접근해야 합니다.

https://meta.discourse.org/t/ember-object-ownership-getowner-service-injections-etc/292080에서 확인할 수 있습니다.

원하시면 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:

감사합니다, 잘 작동합니다!

또한 (적어도 이 플레버의) 현대 JS가 점점 더 엔터프라이즈 자바를 닮아가는 것도 재미있네요. 제가 그 업계에서 일하던 시절(2010년대 초)을 떠올리게 합니다 :smiley: