테마에서 Ember.PromiseProxyMixin 사용

최근 Discourse 코어에 Ember.PromiseProxyMixin이 ember 모듈에 추가되었습니다.

이것은 Ember 컴포넌트 내에서 비동기 요청을 보내고 Promise를 쉽게 다룰 수 있게 해주는 매우 유용한 Ember mixin입니다. 이를 React의 React Suspense와 비슷하게 생각할 수 있지만, Ember용입니다. Discourse의 테마 및 플러그인 개발에 엄청난 잠재력을 가지고 있습니다.

Ember.PromiseProxyMixin 공식 Ember 문서는 여기에서 확인할 수 있습니다.

그리고 여기에서 Discourse와 무관한 Ember.PromiseProxyMixin 사용법에 대한 자세한 예시를 볼 수 있습니다.

이 mixin을 Discourse 테마 내에서 어떻게 사용할 수 있는지 간단한 예를 들어보겠습니다. 예를 들어 topic-list-item 컴포넌트에서 게시자가 스태프 멤버일 경우 게시자의 아바타를 스타일링하고 싶다고 가정해 보겠습니다. 이 경우 아바타에는 다른 테두리가 적용되어야 합니다.

어딘가의 topic-list-item.js(.es6) 파일에서 다음을 수행해야 합니다:

  • EmberObject와 PromiseProxyMixin을 가져오고, PromiseProxyMixin으로 EmberObject를 확장합니다.
import EmberObject from "@ember/object";
import PromiseProxyMixin from "@ember/object/promise-proxy-mixin";

const PromiseObject = EmberObject.extend(PromiseProxyMixin);

// 같은 사용자에 대한 중복 요청을 방지하기 위해 사용자 정의 메모이제이션 함수를 사용할 수 있습니다
const getUser = memoize(username => ajax(`/u/${username}`).then(data => data));
  • 그런 다음 다음 계산 프로퍼티를 만들어야 합니다.
  // 계산된 Promise
  @discourseComputed("topic")
  posterPromise(topic) {
    const { user } = topic.posters[0];
    return getUser(user.username);
  },

 // 이 계산 프로퍼티는 promise를 `PromiseObject`로 감쌉니다
  @discourseComputed("posterPromise")
  posterProxy() {
    const promise = this.get("posterPromise");
    return promise && PromiseObject.create({ promise });
  },

  posterData: reads("posterProxy.content.user"),

  @discourseComputed("posterData")
  isStaff() {
    const posterData = this.get("posterData");
    if (!posterData) return false;
    const { groups = [] } = posterData;
    // 사용자가 스태프 멤버인지 확인하려면
    // 사용자가 스태프 그룹에 속하는지 확인해야 합니다
    return groups.some(({ name }) => name === "staff");
  }

그리고 템플릿 topic-list-item.hb(r|s)에서는 다음과 같은 코드가 있을 것입니다:

  {{#if posterProxy.isFulfilled}}
    {{#if isStaff}}
      // 커스터마이징을 수행하세요
    {{/if}}
  {{/if}}

isPending을 사용하여 로더를 표시하는 데 활용할 수도 있습니다.

이렇게 유용하지는 않은 예시이지만, mixin이 어떻게 작동하는지 파악하는 데 도움이 되기를 바라며, 여러분의 테마/플러그인 개발에서 활용할 수 있는 방법을 찾는 데 도움이 되기를 바랍니다.

:wave:

4개의 좋아요

안녕하세요 @zcuric,

정말 잘 정리된 글과 초기 PR을 올려주셔서 감사합니다. 확실히 여기에는 탐색할 것들이 많네요. 플러그인/테마뿐 아니라 Discourse 코드베이스에서도 마찬가지입니다. 이 패턴을 어떻게 적용할지, 그리고 미래에 더 단순하게 만들 수 있을지 지켜보겠습니다. :+1:

5개의 좋아요