Samskipti barna og foreldra í Elm: OutMsg vs Translator vs NoMap Mynstur

Þegar app Elm þinn byrjar að vaxa, þá viltu brjóta það í sundur í smærri hlutum til að geta verið stærri. Ég fjallaði um þetta í öðrum bloggpósti: Structured TodoMVC dæmi með Elm.

Hluti ef þessi stigstærð felur að lokum í sér þörfina á að senda Msg frá einingunni til foreldris þess, eins og þegar siglingahnappar á ákveðnu yfirliti þurfa að senda skilaboð til efstu leiðar router.

Eftir nokkurn tíma byrjaði ég að taka eftir 3 mismunandi mynstrum til að meðhöndla þetta, og ég endurgerði Elm TodoMVC við allar þessar ólíku aðferðir í þessari geymslu svo þú getir borið þau saman við hlið.

OutMsg mynstrið

Ég tel að Folkertdev hafi verið sá fyrsti sem ég sá til að skrifa um samskipti barns og foreldra í Elm, bloggpóstur hans skýrir þessa nálgun ágætlega.

En til að draga saman þá skilarðu í grundvallaratriðum aukagildi í uppfærsluaðgerðinni. Svo í stað þess að skila þessu:

(Gerð, Cmd Msg)

Þú skilar þessu:

(Gerð, Cmd Msg, OutMsg)

Síðan er foreldrauppfærslu ábyrg fyrir meðhöndlun þeirra. Þannig þarf barnið ekki að vita neitt um foreldrið sitt en foreldrið þarf að vita um OutMsgs barnsins.

Ég hef útfært TodoMVC með þessari aðferð. En ef þú vilt kanna raunverulegan mælikvarða á þessu, innleiddi Richard Feldman elm-spa-dæmið á þennan hátt.

Annað dæmi sem notar þessa aðferð er elm-datepicker.

Þýðingamynstrið

Þýðingamynstrið er mjög svipað og OutMsg en í stað þess að foreldrið viti um Msgs gerðir barns er það foreldrið sem lendir sem Msgs verður búið til með þýðanda. Alex Lew útskýrir nálgun sína miklu betur hér.

Í grundvallaratriðum ertu með þýðanda sem er plata eins og þessi:

tegund alias ÞýðingDiction msg =
  {onInternalMessage: InternalMsg -> msg
  , onPlayerWin: Int -> msg
  , onPlayerLose: msg
  }

Ég hef einnig innleitt TodoMVC með þessari aðferð og ég tel að elm-autocomplete sé líka gott dæmi.

Elm-foreldri-barn uppfærsla er bókasafn sem hjálpar þér við uppfærslu barns-foreldris sem virðist fylgja þessu mynstri.

NoMap mynstrið

Þetta er eitthvað sem ég tók eftir að ég var að gera. Grunnhugmyndin er að forðast að gera Cmd.map og Html.map, þannig að í staðinn þurfa allir að tala sama tungumál, með öðrum orðum, uppfærsla þín og skoða aðgerðir þurfa að skila efstu Msg gerð.

Með þessu muntu líklega hafa Msgs eins og MsgForLogin, MsgForRouter, o.s.frv., Þannig að þú myndir gera eitthvað í þínum augum:

hnappur [onClick (MsgForLogin SignUp)] []

Þetta er hvernig ég endurgerðaði TodoMVC, reyndar í fyrsta skipti sem ég sá OutMsg skildi ég ekki ástæðuna fyrir því vegna þess að ég var ekki að kortleggja Msgs minn.

Skoðaðu eldingar-tala-app til að fá stærra dæmi með þessari nálgun. Einnig virðist þetta forrit fylgja leið Kris Jenkins til að skipuleggja Elm forritin, sem er hlynnt þessari nálgun þegar hann skilur Msgs tegundirnar í Type.elm skrá.

Elm-taco bókasafnið notar í blöndu af OutMsg og NoMap mynstrum með því að hafa „taco“ á toppnum sem þú getur sent skilaboð til.

Athuganir og samanburður

Þegar ég var að rannsaka og endurgerða eftir þessum mynstrum, tók ég fram eitthvað sem getur verið kostur eða galli eftir þörfum þínum:

  • Á NoMap heldur uppfærsluaðgerð foreldris um það sama og forritið þitt stækkar en á OutMsg og Translate getur uppfærsluaðgerð foreldris orðið mjög stór, þar sem þú þarft að takast á við OutMsg hvers barns (dæmi)
  • Í OutMsg og Translate þarf hreiður einingin ekki að flytja neitt frá efri foreldrum, þannig að þau eru meira innbyggð, það væri auðveldara að vinna úr og gefa út einhvern undireining sem bókasafn.
  • Til að NoMap virki ætti Msgs þinn að búa í sérstakri skrá frá Update, annars ertu með ósjálfstæði. Þetta er gott mál sem neyðir þig til að skipta hlutum, en slæmt á sama tíma ef þú vilt hafa eina skrá fyrir hverja einingu (Home.elm, Login.elm, Router.elm)
  • Í NoMap er auðveldara að senda Msgs hvar sem er annars staðar, en það gæti verið erfiðara að fylgja öllum ástandsbreytingum af völdum þess.
  • Eins og það var mælt á þessari stundu, fyrir TodoMVC endurvirkni, hefur NoMap nálgunin 546 LOC, OutMsg 561 og Translator 612 ef þetta skiptir þig máli
  • Á NoMap þarftu að lokum að nota _ catch-all málið til að hunsa Msgs frá öðrum stöðum sem þú vilt ekki takast á við, svo það er minni hjálp frá þýðandanum, það getur ekki sagt hvað þér vantar (takk fyrir @mordrax fyrir að benda að út á öl slaka)
  • Í OutMsg og Translator geturðu bara skoðað gerðirnar eða þýðendurna til að uppgötva hvaða samskipti barna og foreldra eru nauðsynleg, svo þýðandinn getur leiðbeint þér um að útfæra þau, en á NoMap eru þessi samskipti óbeinari.
  • Þýðingaraðferðin virðist vera góð hugmynd til að gefa eigin Msgs til utanaðkomandi íhluta, eins og alm-autocomplete
  • Mér fannst þýðandamynstrið erfitt að fylgja eftir með erfiðara að skilja villuboð frá Elm þýðandanum meðan ég smíðaði það
  • Ef þú breytir ekki (Model, Cmd Msg) staðlinum geturðu notað fínna Elm-Return bókasafnið
  • Sumir telja að hafa ekki Html.map sem góða framkvæmd til að forðast að búa til „íhluti“
  • Þú getur notið mikils ávinnings af því að blanda þessum aðferðum, til dæmis gætirðu bara forðast Html.map fyrir áhorf, en samt notað OutMsg til uppfærslna, eða þú gætir notað NoMap aðeins fyrir efstu stig Msgs, með OutMsgs hér að neðan, meðan verið er að gera ytri þýddan íhlut

Auðlindir

Ég tel að samskipti barna og foreldra séu oft mikilvægari þegar ég er að stækka og gera SPA, þess vegna var mikið af hlutum sem ég fann að lesa þennan reddit þráð um Scaling Elm Apps:

Skál!