Accedere ai componenti glimmer per le cose dal genitore

Sto aggiungendo un componente a before-topic-list-body. Ho bisogno che ottenga alcuni dati dalla categoria o dall’argomento (e aggiungerò i dati che voglio a qualsiasi serializzatore abbia più senso).

Ho passato un paio d’ore a questo e ho deciso che sono perso e c’è una buona probabilità che questo sia un problema da 2-5 minuti per darmi un suggerimento di cui ho bisogno.

Ricordo vagamente di aver pensato o sentito qualcosa a riguardo prima, ma sono bloccato.

2 Mi Piace

:thinking: hmmm

forse questo argomento contiene qualcosa che può aiutare?

Grazie, @Lilly! Non è una cattiva idea, ma temevo che currentUser si applicasse all’intera pagina e non solo a dove viene inserito il componente, e penso di aver ragione. Per vedere cosa era disponibile in quel modo, ho cercato nei plugin ufficiali e ho ottenuto questo elenco di servizi (se fossi intelligente saprei come trovarli nel codice sorgente di Discourse, ma non lo sono):

  @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 Mi Piace

L’ho trovato. Ecco da dove ottenerlo dal mio contesto:

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

Quindi sono in grado di usare quella parentView e _parentView per risalire all’argomento! Questa è la magia che sto cercando, (che penso risolverà anche un altro problema su un altro progetto). Ora tutto ciò che devo fare è inserire le cose nel controller dell’argomento, che spero siano tutte cose che so (almeno per la maggior parte) fare!

1 Mi Piace

Questo ha stampato un messaggio di deprecazione nella console? Dovrebbe averlo fatto, perché rimuoveremo l’accesso a parentView da PluginOutlet a breve. Infatti, è così sconsigliato che dovrebbe causare la visualizzazione di un banner di avviso agli amministratori nell’interfaccia utente :sweat_smile:

Se non hai visto avvisi, faccelo sapere!

(parentView fa parte del sistema di componenti classico di Ember, da cui ci stiamo allontanando)

Se desideri accedere alle informazioni dall’alto nell’albero, queste devono essere passate come argomento a Plugin Outlet, oppure devi utilizzare uno dei servizi disponibili (come currentUser o router).

2 Mi Piace

Ah, capisco cosa è successo. Stai usando ._parentView, non .parentView. La versione con underscore ti permette di aggirare il messaggio di deprecazione. Ma comunque, smetterà di funzionare entro le prossime settimane.

Questa PR impedisce questo tipo di soluzione alternativa, quindi sia .parentView che ._parentView solleveranno la deprecazione:

2 Mi Piace

Grazie, @david!

No. Nemmeno dopo aver cercato per un po’. Sono su 27eea3250cbde2e8bca754f445bee403c059eba3

<RatingOne @scaleValue={{this.scaleValue}} @topic={{this.parentView._parentView.topic}} />
<td class="rating-one">
  <span class="rating-title">{{this.ratingName}}</span>
  Questo è l'argomento {{this.topic.id}}
  Questa è la categoria {{this.topic.category.title}} (id categoria: {{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>

Ah. OK. Quindi posso usare router per accedere all’argomento o alla categoria? Quello che (penso di) dover fare è inserire quelle ratingOptions nel serializzatore dell’argomento o della categoria in modo da poter aggiungere queste valutazioni multiple all’elenco degli argomenti in modo che queste cose possano essere valutate senza entrare negli argomenti (presumibilmente le persone avranno già familiarità con loro, quindi non avranno bisogno di entrare nell’argomento per sapere per cosa stanno votando).

Hmm. Non sembra.

2 Mi Piace

Ok, questo dovrebbe essere risolto da questo commit. Puoi confermare che ora vedi l’avviso?

Idealmente, quel tipo di cose sarebbero disponibili come argomenti nell’outlet del plugin.

Hai menzionato ‘before-topic-list-body’ sopra. Quello ha tutti questi argomenti:

2 Mi Piace
{{log "rating this parent" this.parentView._parentView.topic}}

genera un errore brutto.

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

sembra non generare un errore.

Ho davvero bisogno di above-topic-list-item, ma grazie al tuo ottimo esempio, sono riuscito a scoprire che dovrebbe avere il topic in outletArgs,

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

Ah! Lo farò!

Quindi outletArgs significa che ora è nel this della cosa? (Questo è quello che sembra - pensavo che avrei dovuto cercare in args in qualche modo…)

Quindi nel mio hbs di connessione, posso accedere a this.topic e poi posso chiamare il mio componente in questo modo:

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

E poi nell’hbs per il componente RatingOne (un giorno sarà rinominato semplicemente rating dato che ho capito come passarci le cose) posso

  Questo è il topic {{this.topic.id}} {{this.topic.title}}
  Questo è l'id della categoria: {{this.topic.category_id}})

e ottenere le cose del topic!

E ora vedo il topic, ora posso andare ad aggiungere i miei argomenti al serializzatore del topic, giusto? (Potrebbe essere meglio passarlo solo alla categoria… o forse passerò solo un valore “doTheThing” nel serializzatore e otterrò le cose effettive da SiteSettings, dato che penso che vogliano questo a livello di sito e non di categoria).

A meno che non mi sia imbattuto in qualcos’altro di deprecato, sembra che tu l’abbia fatto. Grazie un milione. :beer: :beers: :clinking_glasses: :moneybag:

3 Mi Piace

Questo è correlato a "come faccio funzionare le cose in glimmer, quindi lo tengo qui.

Devo chiamare questo codice dopo che ogni argomento è stato renderizzato per riordinare gli elementi <td>. Ho usato above-topic-item, che mette le valutazioni prima del titolo dell’argomento. Questo hack selvaggio riordina gli elementi <td> con l’aiuto di un po’ di javascript.

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

//   // todo: questo deve essere chiamato al caricamento della pagina
//   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);
//     }
//   }
// });

Penso che debba solo chiamare una afterRender o qualcos’altro invece della cosa a livello di documento che ho. Forse il router?"

2 Mi Piace

Mi chiedo, Jay, se la tua ultima domanda sia stata l’ispirazione per questo: Upcoming topic-list changes - how to prepare themes and plugins :thinking: :wink:

E credo che la risposta alla tua ultima domanda sia in definitiva: “dai un’occhiata alla nuova API! Customizing the topic list :rocket:

3 Mi Piace

Divertente. E la persona che voleva il lavoro che lo richiedeva è appena riapparsa. Forse ora sarà più semplice!

2 Mi Piace