Obtener acceso a componentes glimmer para cosas del padre

Estoy agregando un componente a before-topic-list-body. Necesito que obtenga datos de la categoría o del tema (y agregaré los datos que quiero a la serialización que tenga más sentido).

He pasado un par de horas en esto y he decidido que estoy perdido y existe una buena posibilidad de que este sea un problema de 2 a 5 minutos para que me des una pista que necesito.

Recuerdo vagamente haber pensado o escuchado algo sobre esto antes, pero estoy atascado.

2 Me gusta

:thinking: hmmm

¿quizás este tema tiene algo que pueda ayudar?

¡Gracias, @Lilly! No es una mala idea, pero temía que currentUser se aplicara a toda la página y no solo a donde se inserta el componente, y creo que tengo razón. Para ver qué estaba disponible de esa manera, busqué en los plugins oficiales y obtuve esta lista de servicios (si fuera inteligente, sabría cómo encontrarlos en el código fuente de Discourse, pero no lo soy):

  @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 Me gusta

Lo encontré. Aquí es de dónde obtenerlo de mi contexto:

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

¡Así que puedo usar esa parentView y _parentView para volver al tema! Esa es la magia que busco (que creo que también resolverá otro problema en otro proyecto). ¡Ahora todo lo que necesito hacer es poner las cosas en el controlador de temas, que espero que sean cosas que (al menos en su mayoría) sé cómo hacer!

1 me gusta

¿Esto imprimió un mensaje de deprecación en la consola? Debería haberlo hecho, porque eliminaremos el acceso a parentView de PluginOutlet inminentemente. De hecho, está tan desaconsejado que debería mostrar un banner de advertencia a los administradores en la interfaz de usuario :sweat_smile:

Si no vio ninguna advertencia, ¡háganoslo saber!

(parentView es parte del sistema de componentes clásico de Ember, del cual nos estamos alejando)

Si desea acceder a información de niveles superiores en el árbol, entonces debe pasarse como argumento a Plugin Outlet, o debe usar uno de los servicios disponibles (como currentUser o router).

2 Me gusta

Ah, ya veo lo que ha sucedido. Estás usando ._parentView, no .parentView. La versión con guion bajo te permite omitir el mensaje de deprecación. Pero aun así, dejará de funcionar en las próximas semanas.

Esta PR evita ese tipo de solución alternativa, por lo que .parentView y ._parentView generarán la deprecación:

2 Me gusta

Gracias, @david!

No. Ni siquiera después de que busqué durante un rato. Estoy en 27eea3250cbde2e8bca754f445bee403c059eba3

<RatingOne @scaleValue={{this.scaleValue}} @topic={{this.parentView._parentView.topic}} />
<td class="rating-one">
  <span class="rating-title">{{this.ratingName}}</span> 
  Este es el tema {{this.topic.id}}
  Esta es la categoría {{this.topic.category.title}} (id de categoría: {{this.topic.category_id}})
  {{log "calificando esto" this}}
  {{log "valor de escala" this.scaleValue}}
  {{log "valor de calificación" this.ratingValue}}
  {{log "categoría" 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. Entonces, ¿puedo usar router para llegar al tema o a la categoría? Lo que (creo que) necesito hacer es llevar esas ratingOptions al serializador del tema o categoría para poder agregar estas calificaciones de múltiples temas a la lista de temas para que estas cosas puedan ser calificadas sin entrar en los temas (presumiblemente la gente ya estará familiarizada con ellos, así que no necesitarán entrar en el tema para saber por qué votan).

Hmm. No parece que pueda.

2 Me gusta

Ok, eso debería estar arreglado por este commit. ¿Puedes confirmar que ahora ves la advertencia?

Idealmente, ese tipo de cosas estarían disponibles como argumentos en el plugin outlet.

Mencionaste ‘before-topic-list-body’ arriba. Eso tiene todos estos argumentos:

2 Me gusta
{{log "rating this parent" this.parentView._parentView.topic}}

genera un error feo.


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

parece no generar un error.

Realmente necesito above-topic-list-item, pero gracias a tu buen ejemplo, pude encontrar que debería tener el tema en outletArgs,

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

¡Ja! ¡Lo voy a hacer!

Entonces, ¿outletArgs significa que ahora está en el this de la cosa? (Eso es lo que parece, pensé que necesitaría buscar en args de alguna manera…).

Así que en mi conector hbs, puedo acceder a this.topic y luego puedo llamar a mi componente así:

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

Y luego en el hbs para el componente RatingOne (que algún día se renombrará simplemente rating ya que descubrí cómo pasarle cosas) puedo

  Este es el tema {{this.topic.id}} {{this.topic.title}}
  Este es el id de la categoría: {{this.topic.category_id}})

¡y obtener la información del tema!

Y ahora veo el tema, ahora puedo ir a agregar mis argumentos al serializador del tema, ¿verdad? (Podría ser mejor pasarlo solo a la categoría… o tal vez solo pasaré un valor “doTheThing” en el serializador y obtendré las cosas reales de SiteSettings, ya que creo que quieren esto a nivel del sitio y no de la categoría).

A menos que de alguna manera haya tropezado con algo más obsoleto, parece que lo has logrado. Gracias un millón. :cerveza: :cervezas: :vasos_chocando: :bolsa_dinero:

3 Me gusta

Esto está relacionado con “cómo hago que las cosas funcionen en Glimmer, así que lo mantengo aquí”.

Necesito llamar a este código después de que se renderice cada tema para reordenar los elementos <td>. Usé above-topic-item, que pone las calificaciones antes del título del tema. Este hack salvaje reordena los elementos <td> con la ayuda de algo de javascript.

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

//   // todo: esto necesita ser llamado al cargar la página
//   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);
//     }
//   }
// });

Creo que “solo” necesito llamar a algún afterRender o algo más en lugar de la cosa a nivel de documento que tengo. ¿Quizás el enrutador?

2 Me gusta

Tengo que preguntarme, Jay, si tu última pregunta fue la inspiración para esto: Upcoming topic-list changes - how to prepare themes and plugins :thinking: ;)\n\nY creo que la respuesta a tu última pregunta es, en última instancia, “¡consulta la nueva API! (https://meta.discourse.org/t/customizing-the-topic-list/350411?u=merefield) :rocket:

3 Me gusta

Gracioso. Y la persona que quería el trabajo que requería esto acaba de reaparecer. ¡Quizás ahora sea más sencillo!

2 Me gusta