Komuniciranje otrok in staršev v Elmu: OutMsg vs Translator vs NoMap Patterns

Ko bo vaša aplikacija Elm začela rasti, jo boste želeli razdeliti na manjše koščke, da boste lahko spreminjali velikost. To sem zajel v drugem blogu bloga: Primer strukturiranega TodoMVC z Elm.

Delno je, če to skaliranje sčasoma vključuje potrebo po pošiljanju sporočila Msg iz modula nadrejenemu, denimo, ko morajo navigacijski gumbi v določenem pogledu poslati sporočilo usmerjevalniku najvišje ravni.

Čez nekaj časa sem začel opažati 3 različne vzorce za ravnanje s tem, in Elf TodoMVC sem obnovil na vseh tistih različnih pristopih v tem skladišču, da jih lahko primerjate drug ob drugem.

Vzorec OutMsg

Verjamem, da je bil Folkertdev prvi, ki sem ga videl pisati o komunikaciji med otrokom in staršem v Elmu, njegov blogpost pa ta pristop razlaga precej dobro.

Če povzamem, v bistvu vrnete dodatno vrednost v funkciji posodabljanja. Torej, namesto da to vrnete:

(Model, Cmd Msg)

To vrnete:

(Model, Cmd Msg, OutMsg)

Nato je za njihovo obdelavo odgovorna nadrejena funkcija posodabljanja. Tako otroku ni treba vedeti ničesar o svojem staršu, vendar mora starš vedeti o otrokovih izhodiščih.

S tem pristopom sem implementiral TodoMVC. Če pa želite preveriti obseg tega v resničnem svetu, je Richard Feldman na ta način izvedel elm-spa-primer.

Drug primer, ki uporablja ta pristop, je branjevec datumov.

Prevajalski vzorec

Prevajalski vzorec je zelo podoben OutMsg, toda namesto, da starš ve o otrokovih vrstah sporočil, je nadrejeni tisti, ki posreduje, katere sporočila bodo ustvarjena prek prevajalca. Alex Lew tukaj pojasni svoj pristop veliko bolje.

V bistvu imate prevajalca, ki je takšen zapis:

vnesite vzdevek TranslationDictionary msg =
  {onInternalMessage: InternalMsg -> msg
  , onPlayerWin: Int -> msg
  , onPlayerLose: msg
  }

Tudi s tem pristopom sem izvedel TodoMVC in verjamem, da je samodejno dokončanje elm tudi dober primer.

Posodobitev elm-starš-otrok je knjižnica, ki vam pomaga pri posodobitvi nadrejenega otroka, ki se zdi, da sledi temu vzorcu.

Vzorec NoMap

To sem opazil, da počnem. Osnovna ideja je izogniti se Cmd.map in Html.map, zato morajo vsi govoriti isti jezik, z drugimi besedami, vaše funkcije posodabljanja in pogleda bodo morale vrniti vrhnjo vrsto Msg.

S tem boste verjetno imeli sporočila, kot so MsgForLogin, MsgForRouter itd., Tako da bi v svojem pogledu naredili nekaj takega:

gumb [onClick (MsgForLogin SignUp)] []

Tako sem prvič obnovil TodoMVC, pravzaprav prvič, ko sem videl OutMsg, nisem razumel razloga za to, ker nisem preslikal mojih sporočil.

Oglejte si aplikacijo lightning-talk za večji primer s tem pristopom. Prav tako se zdi, da ta aplikacija sledi načinu Kris Jenkins strukturiranja aplikacij Elm, kar daje prednost temu pristopu, saj loči vrste Msgs v datoteki Types.elm.

Knjižnica elm-taco nekako uporablja kombinacijo vzorcev OutMsg in NoMap, tako da ima "taco" najvišje ravni, na katero lahko pošiljate sporočila.

Opažanja in primerjave

Medtem ko sem raziskal in popravljal te vzorce, sem opazil nekaj, kar je lahko prednosti ali slabosti glede na vaše potrebe:

  • V programu NoMap se funkcija za posodabljanje staršev ohranja približno tako, kot raste vaša aplikacija, medtem ko je pri funkcijah posodabljanja staršev OutMsg in Translate mogoče postati zelo veliko, saj morate obdelovati OutMsg vsakega otroka (primer)
  • V OutMsg in Prevajanju ugnezdenih modulov ni treba ničesar uvažati od zgornjih staršev, zaradi česar bodo bolj zaprti, lažje bi bilo izvleči in objaviti kakšen podmodul kot knjižnica, na primer
  • Da bi NoMap deloval, bi morala vaša sporočila živeti v ločeni datoteki od Posodobitve, sicer pa boste imeli zanko odvisnosti. To je dobro, ker vas sili, da stvari delite, hkrati pa slabo, če želite imeti za vsak modul eno datoteko (Home.elm, Login.elm, Router.elm)
  • V NoMap je lažje pošiljati sporočila kamor koli drugje, vendar je morda težje slediti vsem spremembam stanja, ki jih povzroča.
  • Kot je bilo izmerjeno v trenutku tega pisanja, za refaktorje TodoMVC ima pristop NoMap 546 LOC, OutMsg 561 in Translator 612, če je to pomembno za vas
  • V programu NoMap boste morali s primerom _ catch-all zanemariti sporočila iz drugih krajev, ki jih ne želite obravnavati, zato je pomoč prevajalnika manj, ne more povedati, kaj pogrešate (hvala za ukaz @mordrax da ven na elm ohlapno)
  • V OutMsg in Translatorju lahko preprosto pogledate vrste ali prevajalce, da ugotovite, katere komunikacije med starši in starši so potrebne, tako da vas bo prevajalnik vodil pri izvajanju, medtem ko je pri NoMap ta komunikacija bolj implicitna
  • Prevajalski pristop se zdi dobra ideja za podajanje lastnih sporočil zunanjim komponentam, kot je elm-autocomplete
  • Prevajalskemu vzorcu se mi je zdelo težko slediti s težje razumljivimi sporočili o napakah iz prevajalnika Elm, medtem ko ga je gradil
  • Če ne spremenite standarda (Model, Cmd Msg), lahko uporabite knjižnico s finim vrhom
  • Nekateri menijo, da Html.map ni dobra praksa, da bi se izognili ustvarjanju "komponent"
  • Z mešanjem teh pristopov lahko dobite veliko koristi, na primer, preprosto se lahko izognete Html.map za poglede, medtem ko še vedno uporabljate OutMsg za posodobitve ali pa NoMap uporabite samo za sporočila najvišje ravni, spodaj pa OutMsgs, med upodabljanjem zunanje prevedene komponente

Viri

Verjamem, da je komunikacija med otroki in starši pogosto bolj pomembna pri spreminjanju in izvajanju POV, zato sem našla veliko stvari, ki berejo to rdečo nit o aplikacijah Scaling Elm Apps:

Na zdravje!