Rivalutare i widget nell'intestazione al cambio di rotta senza errori

Sto cercando di sovrascrivere questo template di widget:

      api.reopenWidget("header-contents", {
        template: hbs`

          {{#if this.site.desktopView}}
            {{#if attrs.sidebarEnabled}}
              {{sidebar-toggle attrs=attrs}}
            {{/if}}
          {{/if}}

          {{home-logo attrs=attrs}}

          {{#if attrs.topic}}
            {{header-topic-info attrs=attrs}}
          {{else if this.siteSettings.bootstrap_mode_enabled}}
            {{#if transformed.showBootstrapMode}}
              {{header-bootstrap-mode attrs=attrs}}
            {{/if}}
          {{/if}}

          <div class="panel clearfix" role="navigation">{{yield}}</div>
        `,
      });

Nonostante il template sia attualmente identico all’originale in discourse/app/assets/javascripts/discourse/app/widgets/header-contents.js at 4aa81e709ea49e30383a3a3acd33dfedaebfc240 · discourse/discourse · GitHub

Genera un errore:

Questo è inaspettato, soprattutto perché non sto effettivamente “cambiando nulla” (ancora)?

Sono in grado di riprodurre questo problema anche se questa è l’unica modifica.

In definitiva, il motivo per cui sto cercando di cambiare questo è per poter forzare una rivalutazione di questo template anche se non mi sto spostando dentro o fuori da un percorso di argomento.

In definitiva, voglio aggiungere una logica in modo che il widget sia forzato a essere aggiornato quando ci si sposta dentro e fuori dai percorsi delle categorie, poiché la presentazione del mio percorso di categoria deve essere diversa.

Quindi, una soluzione a questo potrebbe essere un altro modo per forzare l’aggiornamento dei contenuti dell’intestazione.

In ogni caso, questo non sembra comportarsi come dovrei aspettarmi?

Non vogliamo investire molto tempo qui: i widget non dureranno ancora a lungo. Che personalizzazione stai cercando di apportare? Possiamo aiutarti aggiungendo un’uscita per plugin da qualche parte (ora siamo in grado di aggiungere normali uscite per plugin all’interno del codice dei widget).

Puoi condividere di più del tuo file (ad esempio, da dove viene importato hbs)?

1 Mi Piace

Inoltre, quale versione di Discourse è questa? site-header.js:337 non fa attualmente riferimento a una variabile ‘header’

1 Mi Piace

Capito.

import { hbs } from "ember-cli-htmlbars";

Funzionalmente, sto cercando di scambiare il logo a seconda del percorso. In realtà, lo sto facendo allegando un’immagine al logo della home in alcuni percorsi e sovrapponendo il logo principale. Voglio che quella logica venga rivalutata quando ci si sposta tra i percorsi, il che attualmente sembra funzionare entrando e uscendo dai percorsi di Topic, immagino perché il widget header-contents a cui tutto è collegato ha una logica che valuta gli attrs.topic che ovviamente cambia quando ciò accade.

Il mio category-logo-widget è collegato in questo modo:

      api.decorateWidget("home-logo:after", (helper) => {
        const currentPath = helper.register
          .lookup("service:router")
          .get("_router.currentPath");

        if (
          helper.widget.currentUser &&
          !helper.widget.site.mobileView &&
          currentPath.indexOf("discovery") === -1
        ) {
          return helper.attach("category-logo-widget");
        }
      });

Il che funziona bene, ma non viene rivalutato tra alcune transizioni di percorso, quindi non soddisfa il requisito di essere completamente dinamico senza un ricaricamento della pagina.

ooooops, questo potrebbe essere il problema, avevo la sensazione che potesse essere così ma i miei test erano ovviamente troppo superficiali per escluderlo.

Vedo questo commit, dovrò aggiornare la mia istanza di sviluppo… PERF: Memoize element references for `dockCheck` (#21079) · discourse/discourse@db16700 · GitHub

Tornerò indietro in ogni caso, grazie per il tuo tempo!

Questo è probabilmente il problema. I widget ‘templates’ sono una cosa personalizzata di Discourse e vengono compilati in modo completamente diverso dagli Ember templates. Dovrai importare hbs in questo modo:

Sembra che abbiamo un evento dell’app site-header:force-refresh che potresti attivare in risposta a qualche altro evento dell’app o evento del router Ember:

(esempio di trigger qui)

3 Mi Piace

Fantastico, grazie David, correggerò l’installazione obsoleta e proverò anche i tuoi consigli qui. Accumulo multiplo, grazie per aver aiutato a fare chiarezza!

3 Mi Piace

Quindi probabilmente un po’ gratuito, ma ho finito per usare il tuo suggerimento, con:

      api.onPageChange(url =>  {
        const applicationController = container.lookup(
          "controller:application"
        );
        applicationController.appEvents.trigger(
          "site-header:force-refresh"
        );
      });

ha funzionato benissimo, anche se non è perfettamente sincronizzato con la transizione del percorso, ma va bene.

grazie ancora!

3 Mi Piace

btw, solo come nota a margine, mentre l’API dei widget è molto personalizzata e un po’ complicata (specialmente le cose hyperscript), devo ammettere che è estremamente potente per aggiungere nuovi comportamenti ai widget esistenti senza dover sovrascrivere molto codice.

ad esempio, ho usato molto questo schema:

api.reopenWidget('discourse-awesome-widget', {

  html(attrs, state) {
    let contents = this._super(...arguments);

    contents.unshift(h("div.my-cool-new-thing", "cool new thing"))

    return contents;
  }
});

this._super potrebbe essere molto codice!!!

E può diventare molto più intelligente di così, tanto che ho imparato ad apprezzarlo molto.

Spero che l’“override-ability” di qualunque cosa lo sostituirà sarà ugualmente flessibile e potente.

1 Mi Piace

La soluzione principale qui saranno gli hook per plugin. Come sempre, se senti di averne bisogno di uno che non esiste, sentiti libero di inviare una PR al core :rocket:

1 Mi Piace

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.