Ordine di precedenza dei componenti del tema

Ho notato che i componenti del tema sembrano essere eseguiti nell’ordine di installazione. Ad esempio, se installo A e poi B, gli script di A vengono inclusi nelle pagine generate prima di quelli di B.

Posso fare affidamento su questo comportamento? Esiste una vista che mostra questo ordine? Quando visualizzo i componenti installati, questi sembrano essere elencati in ordine alfabetico.

Preferirei un modo per eseguire esplicitamente le azioni prima di un determinato componente. Nel mio caso, voglio eseguire delle azioni prima del componente TOC (correlato a questo argomento). Dalla documentazione di Ember sembra che le funzioni programmate per una determinata coda vengano eseguite nell’ordine in cui sono state pianificate. Questo rende l’ordine di pianificazione essenziale nel mio caso.

2 Mi Piace

Non è qualcosa su cui puoi fare affidamento; al contrario, dovrebbero essere le API appropriate a gestirlo. Puoi utilizzare gli initializer di Ember per controllarlo fino a un certo punto. @eviltrout potrebbe avere alcune idee specifiche se puoi incollare il codice di esempio che stai cercando di pianificare.

7 Mi Piace

Questo è il codice che sto eseguendo:

<script type="text/discourse-plugin" version="0.8">
    const { run } = Ember;
    
    api.decorateCooked($elem => {
        run.scheduleOnce("actions", () => {
          // Deve essere eseguito prima delle azioni pianificate dal componente TOC.
        });
    })

Il componente TOC utilizza la stessa interfaccia per pianificare le proprie azioni.

Secondo la documentazione di Ember, l’interfaccia di pianificazione:

Aggiunge l’obiettivo/metodo passato e eventuali argomenti opzionali alla coda denominata da eseguire alla fine del RunLoop

Il termine “aggiunge” suggerisce un ordinamento FIFO delle azioni pianificate. Pertanto, l’ordine in cui viene chiamata schedule è fondamentale in questo caso.

Ho notato che nel mio tentativo di riordinare l’esecuzione di JavaScript reinstallando e disinstallando il componente TOC (questo sembra avere l’effetto collaterale fortuito di eseguire lo script JavaScript del TOC per ultimo), le regole CSS vengono ora applicate con questo ordine :slight_smile:

Ritengo che l’argomento dell’ordinamento per il posizionamento del codice dei componenti del tema sia piuttosto importante. Se l’ordinamento è ufficialmente “non definito”, i componenti non hanno alcuna possibilità di interagire.

Forse l’interazione tra i componenti non è un obiettivo. Ma penso che con un’euristica di ordinamento (ad esempio, dichiarare che un file di componente debba essere posizionato prima o dopo un file di un altro componente con lo stesso nome – questo verrebbe presumibilmente definito in about.json) questo problema non è così difficile da risolvere.

Per quanto mi riguarda, sto iniziando a pensare che forkare il componente TOC sia la strada giusta in base a ciò che sto cercando di fare.

Ogni volta che crei o installi un tema o un componente, Discourse gli assegna un ID. Se visiti la pagina di quel componente, dovresti vedere quell’ID nell’URL (il numero alla fine).

component id in the URL

Quando quel componente viene aggiunto al tuo tema, il suo ordine di esecuzione sembra basarsi sul suo ID, a un livello molto basilare (facendo un console.log senza alcun deferimento). Quindi, il 233 verrà eseguito prima del 234 e così via.

Questo funziona per la maggior parte dei casi perché le modifiche successive vengono solitamente aggiunte in nuovi componenti, quindi funziona semplicemente.

A lungo termine, potremmo far sì che l’ordine rispetti quello dell’elenco dei componenti che hai aggiunto al tema.

ma al momento non è previsto in nessuna roadmap.

Ciò di cui hai realmente bisogno è l’ordine degli inizializzatori. Non credo che tu possa farlo a meno che non sposti il tuo codice nel nuovo modo di creare il JavaScript del tema. Questo metodo ti consente di assegnare un nome e un ordine di esecuzione all’inizializzatore. Ad esempio, supponiamo di avere questo file

/javascripts/discourse/initializers/initialize-for-foo.js

e che appaia così:

import { withPluginApi } from "discourse/lib/plugin-api";

export default {
  name: "foo",
  initialize() {
    withPluginApi("0.8.7", api => {
      console.log("foo")
    });
  }
}

e che abbia un altro inizializzatore che appare così:

/javascripts/discourse/initializers/initialize-for-bar.js

import { withPluginApi } from "discourse/lib/plugin-api";

export default {
  name: "bar",
  initialize() {
    withPluginApi("0.8.7", api => {
      console.log("bar")
    });
  }
}

Se voglio assicurarmi che bar venga eseguito dopo foo, posso aggiungere un argomento after: ad esso, il che garantirà che venga eseguito dopo il nome dell’inizializzatore che passo lì. Quindi, per far sì che bar venga eseguito dopo foo, farei questo in

/javascripts/discourse/initializers/initialize-for-bar.js

import { withPluginApi } from "discourse/lib/plugin-api";

export default {
  name: "bar",
+ after: "foo",
  initialize() {
    withPluginApi("0.8.7", api => {
      console.log("bar");
    });
  }
};
6 Mi Piace

Grazie mille per i dettagliati suggerimenti! Considerando i miei problemi correlati con il componente TOC (ai quali hai anche risposto, grazie ancora), ho fatto un fork del TOC e spostato il codice dipendente all’interno di quel componente. Questo è legato agli ID delle intestazioni, in particolare alla necessità di controllarli dal post per gestire duplicati e collisioni con gli ID degli elementi principali.

Penso che, dato ciò che sto facendo con la documentazione, di cui alcune parti sono un po’ fuori dagli schemi, questo sia l’approccio giusto.

1 Mi Piace