親のデータへのglimmer componentアクセスを取得

before-topic-list-body にコンポーネントを追加しています。このコンポーネントは、カテゴリまたはトピックからデータを取得する必要があります(どのシリアライザーがより適切かによって、必要なデータを追加します)。

数時間かけて調べましたが、お手上げ状態です。おそらく、ヒントをいただければ2〜5分で解決できる問題だと思います。

以前にこれについて考えたり聞いたりしたような気がしますが、行き詰まっています。

「いいね!」 2

:thinking: うーん

もしかしたら、このトピックに役立つものがあるかもしれません。

ありがとうございます、@Lilly!悪くないアイデアですが、currentUser はコンポーネントが挿入される場所だけでなく、ページ全体に適用されるものだと恐れていました。そして、それは正しいと思います。その方法で何が利用可能かを確認するために、公式プラグインをgrepしたところ、このサービスのリストが得られました(賢ければ、Discourseのソースでそれらを見つける方法を知っているでしょうが、私はそうではありません):

  @service adminPluginNavManager;
  @service appEvents;
  @service capabilities;
  @service chatApi;
  @service composer;
      @service currentUser;
  @service currentUser;
  @service dialog;
  @service dTemplatesModal;
  @service encryptWidgetStore;
  @service hCaptchaService;
  @service imageCaptionPopup;
  @service menu;
  @service messageBus;
  @service modal;
  @service moreTopicsPreferenceTracking;
  @service presence;
  @service quickSearch;
  @service router;
  @service search;
  @service searchPreferencesManager;
  @service session;
  @service site;
  @service siteSettings;
  @service store;
  @service taskActions;
  @service toasts;
  @service upgradeStore;
  @service userFieldValidations;
  @service whosOnline;
「いいね!」 2

見つけました。コンテキストから取得する場所は次のとおりです。

<RatingOne @scaleValue={{this.scaleValue}} @topic={{this.parentView._parentView.topic}} />

したがって、その parentView_parentView を使用してトピックまで戻ることができます。これが私が探していた魔法です(これは別のプロジェクトの別の問題も解決すると思います)。あとは、トピックコントローラーにその内容を配置するだけです。これはすべて、私が(少なくとも大部分は)知っているはずのことです!

「いいね!」 1

コンソールに非推奨メッセージが表示されましたか? PluginOutlet からの parentView へのアクセスは間もなく削除されるため、表示されるはずです。実際、あまりにも非推奨であるため、UI で管理者に警告バナーが表示されるはずです :sweat_smile:

警告が表示されなかった場合は、お知らせください!

parentView は Ember の従来のコンポーネントシステムの一部であり、私たちはそこから移行しています)

ツリーの上位の情報にアクセスしたい場合は、引数として Plugin Outlet に渡すか、利用可能なサービス(currentUserrouter など)のいずれかを使用する必要があります。

「いいね!」 2

ああ、何が起こったのかわかりました。あなたは .parentView ではなく ._parentView を使用しています。アンダースコア付きのバージョンを使用すると、非推奨メッセージを回避できます。しかし、それでも数週間以内に動作しなくなります。

このPRは、そのような回避策を防ぐため、.parentView._parentView の両方で非推奨の警告が発生するようになります。

「いいね!」 2

ありがとうございます、@david

いいえ。しばらく探しても、何も表示されませんでした。27eea3250cbde2e8bca754f445bee403c059eba3 を使用しています。

<RatingOne @scaleValue={{this.scaleValue}} @topic={{this.parentView._parentView.topic}} />
<td class="rating-one">
  <span class="rating-title">{{this.ratingName}}</span>
  これはトピック {{this.topic.id}} です
  これはカテゴリ {{this.topic.category.title}} (カテゴリID: {{this.topic.category_id}}) です
  {{log "rating this" this}}
  {{log "scale value" this.scaleValue}}
  {{log "rating value" this.ratingValue}}
  {{log "category" this.topic.category_id}}
    <form>
        {{!-- {{this.ratingLow}} --}}
       {{#each this.ratingOptions as |option|}}
            <input type="radio" name="rating" value={{option.value}} checked={{if (eq option.value this.ratingValue) "checked"}}> <span class="rotated-label">{{option.label}}</span>
        {{/each}}
        {{!-- {{this.ratingHigh}} --}}
    </form>
</td>

ああ。わかりました。では、トピックやカテゴリにアクセスするためにrouterを使用できますか?私が(そう思う)やりたいことは、これらのratingOptionsをトピックまたはカテゴリシリアライザーに取得して、これらの複数のトピック評価をトピックリストに追加できるようにすることです。これにより、トピックに入ることなくこれらの評価を行うことができます(人々はすでにそれらに精通していると仮定されるため、トピックについて投票するためにトピックに入る必要はありません)。

うーん。それはできないようです。

「いいね!」 2

これで修正されるはずです。このコミット を確認してください。警告が表示されるか確認していただけますか?

理想的には、そのようなものはプラグインのアウトレットの引数として利用可能になるはずです。

上で「before-topic-list-body」について言及されていました。それにはこれらの引数がすべて含まれています。

「いいね!」 2
{{log "rating this parent" this.parentView._parentView.topic}}

は、醜いエラーを生成します。

<RatingOne @scaleValue={{this.scaleValue}} @passedRouter={{this.router}} @topic={{this.parentView}} />

は、エラーを生成しないようです。

私は本当に above-topic-list-item が必要ですが、あなたの素晴らしい例のおかげで、トピックが outletArgs にあることを発見しました。

https://github.com/discourse/discourse/blob/main/app/assets/javascripts/discourse/app/components/topic-list/topic-list-item.gjs#L284

ハッ!やります!

つまり、outletArgs は、それが this の中にあるということですか?(そのように見えます。args の中を調べる必要があると思っていました...)

だから、私のコネクタのhbsでは、this.topic にアクセスして、コンポーネントを次のように呼び出すことができます。

<RatingOne @name="one" @topic={{this.topic}}/>

そして、RatingOne コンポーネントのhbs(いつか rating に名前変更する予定です。なぜなら、値を渡す方法を見つけたからです)では、次のようにできます。

  This is topic {{this.topic.id}} {{this.topic.title}}
  This is category id: {{this.topic.category_id}})

そしてトピックの情報を取得できます!

そして今、トピックが見えるようになりました。トピックシリアライザーに引数を追加できますよね?(カテゴリに渡す方が良いかもしれませんが...あるいは、シリアライザーに「doTheThing」という値だけを渡して、実際の内容は SiteSettings から取得するかもしれません。これはサイトレベルで、カテゴリレベルではないからです。)

何か別のものが非推奨になっていない限り、あなたはそれをやったようです。本当にありがとうございます。 :beer: :beers: :clinking_glasses: :moneybag:

「いいね!」 3

これは「glimmerでどうやって物事を機能させるか」に関連しているので、ここに置いておきます。

トピックがレンダリングされた後にこのコードを呼び出して、<td> アイテムを並べ替える必要があります。above-topic-item を使用して、レーティングをトピックタイトルの前に配置しました。このワイルドなハックは、JavaScript の助けを借りて <td> アイテムを並べ替えます。

// document.addEventListener("DOMContentLoaded", function() {
//   const table = document.querySelector('table.topic-list.ember-view');
//   const rows = table.getElementsByTagName('tr');

//   // todo: これはページロード時に呼び出す必要がある
//   for (let row of rows) {
//     const cells = Array.from(row.getElementsByTagName('td'));
//     cells.sort((a, b) => {
//       const orderA = parseInt(window.getComputedStyle(a).order, 10);
//       const orderB = parseInt(window.getComputedStyle(b).order, 10);
//       return orderA - orderB;
//     });

//     for (let cell of cells) {
//       row.appendChild(cell);
//     }
//   }
// });

ドキュメントレベルのもの (document-level thing) の代わりに、afterRender か何かを呼び出すだけでよいと思います。ルーター (router) かもしれません。

「いいね!」 2

ジェイ、あなたの最後の質問がこれのインスピレーションになったのではないかと疑問に思わざるを得ません。 Upcoming topic-list changes - how to prepare themes and plugins :thinking: ;)\n\nそして、あなたの最後の質問への答えは、最終的には「新しいAPIをチェックアウトしてください!」ということだと思います。 Customizing the topic list :rocket:

「いいね!」 3

面白い。そして、この作業を必要としていた人物がちょうど現れた。これで、もっと簡単になるかもしれない!

「いいね!」 2