Comment savoir si une page se charge dans un composant / widget de thème ?

J’ai l’impression qu’il me manque probablement quelque chose d’évident ici, mais je n’arrive pas à le trouver. J’ai un composant de thème qui charge quelques widgets, et j’utilise le code suivant pour les réafficher après que l’utilisateur a navigué vers une nouvelle page (emprunté aux bannières de catégorie) :

api.decorateWidget("my-widget:after", (helper) => {
    helper.widget.appEvents.on("page:changed", () => {
      helper.widget.scheduleRerender();
    })
});

Cependant, ce code attend que la nouvelle page soit chargée pour mettre à jour le widget. Ce que j’espère faire, c’est masquer le contenu de mon widget dès que quelqu’un clique sur un lien vers une autre page, tout comme la fonctionnalité native de Discourse qui masque les éléments et affiche un indicateur de chargement immédiatement au clic.

Je vois dans app\assets\javascripts\discourse\app\templates\discovery.hbs que le conteneur div observe une variable “loading”, mais je n’arrive pas à comprendre d’où elle vient et comment m’y connecter ou observer l’état de chargement dans mon widget.

Je suis reconnaissant pour toute réponse ou simplement pour une orientation dans la bonne direction générale. :slight_smile:

Merci,

Zach

1 « J'aime »

J’ai pensé remonter ce sujet — je suis prêt à payer pour un support premium afin d’obtenir une réponse si nécessaire.

Pouvez-vous brièvement décrire le comportement souhaité et sur quelles pages exactement ?

Vous pouvez essayer queueRerender() au lieu de scheduleRerender()

Merci pour vos réponses, les gars.

J’ai plusieurs widgets que j’ai créés pour certaines pages de catégories, et j’aimerais idéalement les masquer immédiatement dès que quelqu’un quitte une page. Voici une vidéo de démonstration de 45 secondes sur Loom montrant ce que je vise : Google Chrome - Latest Rental Cities/California topics - Afford Anything Forums - Google Chrome | Loom

@hawm Je ne pense pas que la réactualisation de la file d’attente soit ce dont j’ai besoin ici, car il ne s’agit pas vraiment de réactualiser mes widgets, mais plutôt de permettre à mes widgets de savoir si l’application Discourse globale charge une nouvelle page ou non.

En résumé, la condition doit se trouver dans le modèle, par exemple :

{{#if xyz}}
votre code
{{/if}}

Les modèles Ember sont dynamiques. Si la valeur change, le widget sera masqué.

Oui, bien sûr. :slight_smile: Je ne rencontre pas de difficultés avec la syntaxe if/then ; ce que je demande, c’est s’il existe un moyen de vérifier si Discourse est en train de charger une nouvelle page.

Je pense que pirater la route discovery en utilisant l’API modifyClass puis déclencher un événement personnalisé fonctionnerait.

https://api.emberjs.com/ember/3.12/classes/Route

La variable loading provient de la route discovery que j’ai mentionnée ci-dessus. Le widget attaché à plugin-outlet pourrait ne pas pouvoir y accéder car elle n’est pas passée en tant qu’argument ; cela dépend de la définition de plugin-outlet.

D’accord, merci beaucoup. Je vais faire quelques recherches et voir ce que je trouve, et je mettrai à jour cette page avec une solution pour la postérité si j’en trouve une :slight_smile:

1 « J'aime »

J’ai enfin réussi à trouver une solution. J’ai passé un temps fou sur ce sujet et, à mon avis, il mérite d’être intégré au cœur du projet, car honnêtement, on dirait que cela devrait déjà y exister.

J’ai ajouté le code ci-dessous à mon composant de thème : il ajoute une classe « loading » au body dès que le routage commence, puis la retire dès que le routage est terminé. Peut-être que cela semble simple ou évident pour ceux qui connaissent Ember, mais il m’a fallu un temps obscène (en essayant un million de choses et en parcourant tous les fils de discussion que j’ai pu trouver ici) pour le comprendre.

Avec ce code de base en place, je peux ajouter des spinners de chargement et autres à mes différents widgets, dont le CSS et la visibilité seront pilotés par la présence ou non de la classe CSS loading sur la balise body.

initialize() {
    withPluginApi("0.8.8", (api) => {
      const router = api._lookupContainer('router:main');
      router.reopen({
        addLoadingCSSClassToBody: function() {
          document.body.classList.add("loading");
        }.on('willTransition')
      });

      router.reopen({
        removeLoadingCSSClassFromBody: function() {
          document.body.classList.remove("loading");
        }.on('didTransition')
      });
    });
  },
};
1 « J'aime »

Le code que je partage ne provient pas d’un widget, mais d’un composant que nous avons publié pour téléchargement ici sur Meta.

Nous y utilisons le routeur, ainsi que @discourseComputed, pour vérifier si l’itinéraire a changé et rendre le contenu en conséquence.

Vous pouvez explorer plus en détail le code si vous souhaitez comprendre son fonctionnement.

4 « J'aime »