Cmd.map è il modo giusto per dividere una Elm SPA in moduli?

Aug 23 2020

Sto creando un'applicazione a pagina singola in Elm e ho avuto difficoltà a decidere come dividere il mio codice in file.

Ho finito per dividerlo usando 1 modulo per pagina e ho Main.elmconvertito il Htmle Cmdemesso da ogni pagina usando Cmd.mape Html.map.

Il mio problema è che la documentazione sia per Cmd.map che per Html.map dice che :

Questo è molto raramente utile in un codice Elm ben strutturato, quindi leggi sicuramente la sezione sulla struttura nella guida prima di raggiungerlo!

Ho controllato le uniche 2 app di grandi dimensioni di cui sono a conoscenza:

  1. elm-spa-example usa Cmd.map (https://github.com/rtfeldman/elm-spa-example/blob/cb32acd73c3d346d0064e7923049867d8ce67193/src/Main.elm#L279)
  2. Non sono riuscito a capire come https://github.com/elm/elm-lang.org affronta la questione.

Inoltre, entrambe le risposte a questa domanda di stackoverflow suggeriscono di utilizzare Cmd.mapsenza ripensamenti.

Cmd.map è il modo "giusto" per dividere un'applicazione a pagina singola in moduli?

Risposte

3 JackLeow Aug 23 2020 at 11:12

Penso che a volte devi solo fare ciò che è giusto per te . Ho usato l' approccio Cmd.map/ Sub.map/ Html.mapper un'applicazione che ho scritto che aveva 3 "pagine": inizializzazione, modifica e reporting.

Volevo rendere ciascuna di queste pagine il proprio modulo in quanto erano relativamente complicate, ognuna aveva un discreto numero di messaggi che sono rilevanti solo per ciascuna pagina ed è più facile ragionare su ogni pagina in modo indipendente nel proprio contesto.

Lo svantaggio è che il compilatore non ti impedisce di ricevere il messaggio sbagliato per una determinata pagina, portando a un errore di runtime (ad esempio, se l'applicazione riceve un Editing.Savequando è nella Reportingpagina, qual è il comportamento corretto? implementazione, lo accedo alla console e vado avanti: questo è stato abbastanza buono per me (e comunque non è mai successo); Altre opzioni che ho considerato includono la visualizzazione di una brutta pagina di errore per indicare che è successo qualcosa di orribile - un BSOD se lo farai; O semplicemente reimpostare / reinizializzare l'intera applicazione).

2 olivieradam666 Aug 24 2020 at 14:03

Un'alternativa è usare il modello di effetto come ampiamente descritto in questo post del discorso .

Il fulcro di questo approccio è che:

Il pattern Effect esteso utilizzato in questa applicazione consiste nel definire un tipo di Effect custom che possa rappresentare tutti gli effetti che le funzioni di init e update vogliono produrre.

E i principali vantaggi:

  1. Tutti gli effetti sono definiti in un unico modulo Effect , che funge da API interna per l'intera applicazione che garantisce di elencare ogni possibile effetto.
  2. Gli effetti possono essere controllati e testati, non come i valori Cmd. Ciò consente di testare tutti gli effetti dell'applicazione, comprese le richieste HTTP simulate.
  3. Gli effetti possono rappresentare una modifica dei dati del modello di primo livello, come la Sessione 3 quando si accede a 3, o la pagina corrente quando è richiesta una modifica dell'URL da una funzione di aggiornamento della sottopagina.
  4. Tutte le funzioni di aggiornamento mantengono una firma Msg -> Model -> (Model, Effect Msg) 2 pulita e concisa.
  5. Poiché i valori degli effetti contengono le informazioni minime richieste, alcuni parametri come Browser.Navigation.key sono necessari solo nella funzione di esecuzione 3 degli effetti, che libera lo sviluppatore dal passarli alle funzioni in tutta l'applicazione.
  6. Un singolo NoOp o Ignored String 25 può essere utilizzato per l'intera applicazione.