Cmd.map è il modo giusto per dividere una Elm SPA in moduli?
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.elm
convertito il Html
e Cmd
emesso da ogni pagina usando Cmd.map
e 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:
- elm-spa-example usa Cmd.map (https://github.com/rtfeldman/elm-spa-example/blob/cb32acd73c3d346d0064e7923049867d8ce67193/src/Main.elm#L279)
- 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.map
senza ripensamenti.
Cmd.map è il modo "giusto" per dividere un'applicazione a pagina singola in moduli?
Risposte
Penso che a volte devi solo fare ciò che è giusto per te . Ho usato l' approccio Cmd.map
/ Sub.map
/ Html.map
per 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.Save
quando è nella Reporting
pagina, 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).
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:
- 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.
- 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.
- 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.
- Tutte le funzioni di aggiornamento mantengono una firma Msg -> Model -> (Model, Effect Msg) 2 pulita e concisa.
- 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.
- Un singolo NoOp o Ignored String 25 può essere utilizzato per l'intera applicazione.