Vaiko ir tėvų bendravimas guobose: „OutMsg vs Translator vs NoMap“ šablonai

Kai jūsų programa „Guoba“ pradės augti, norėsite ją suskaidyti mažesniais gabalėliais, kad būtų galima mastelį pakeisti. Apie tai rašiau kitame tinklaraščio įraše: struktūrizuotas „TodoMVC“ pavyzdys su „Guoba“.

Dalis, jei dėl šio mastelio padidėjimo reikia išsiųsti pranešimą iš modulio jo tėvui, pavyzdžiui, kai naršymo mygtukai konkrečiame rodinyje turi nusiųsti pranešimą aukščiausio lygio maršrutizatoriui.

Po kurio laiko aš pradėjau pastebėti 3 skirtingus modelius, kaip tai tvarkyti, ir vėl pritaikiau Elm TodoMVC visiems šiems skirtingiems požiūriams į šią saugyklą, kad galėtumėte palyginti juos.

„OutMsg“ modelis

Manau, kad Folkertdevas buvo pirmasis, kurį mačiau rašydamas apie vaiko ir tėvų bendravimą Guobose, jo tinklaraštis gana gerai paaiškina šį požiūrį.

Tačiau, apibendrinant, jūs iš esmės grąžinate papildomą savo atnaujinimo funkcijos vertę. Taigi užuot grąžinęs:

(Modelis, „Cmd Msg“)

Jūs grąžinate tai:

(„Model“, „Cmd Msg“, „OutMsg“)

Tada tėvų atnaujinimo funkcija yra atsakinga už tvarkymą. Tokiu būdu vaikui nereikia nieko žinoti apie savo tėvą, bet tėvas turi žinoti apie savo vaiko išvestines.

Aš įgyvendinau „TodoMVC“ naudodamas šį metodą. Bet jei norite patikrinti realaus pasaulio mastelį, Richardas Feldmanas tokiu būdu įgyvendino „elm-spa“ pavyzdį.

Kitas pavyzdys, kuriame naudojamas šis požiūris, yra „elm-datepicker“.

Vertėjo modelis

Vertėjo schema yra labai panaši į „OutMsg“, tačiau užuot žinojęs apie vaiko žinučių tipus, tėvas perduoda vertėją, kuris bus sugeneruotas. Alexas Lewas savo požiūrį čia paaiškina daug geriau.

Iš esmės jūs turite vertėją, kuris yra toks įrašas:

įveskite slapyvardį TranslationD Dictionary msg =
  {onInternalMessage: InternalMsg -> msg
  , onPlayerWin: Int -> žinutė
  , onPlayerLose: msg
  }

Aš taip pat įgyvendinau „TodoMVC“ naudodamas šį metodą ir manau, kad guobų automatinis užbaigimas taip pat yra geras pavyzdys.

Guobos-tėvo-vaiko atnaujinimas yra biblioteka, kuri padeda atnaujinti vaiką-tėvą, kuris, atrodo, atitinka šį modelį.

„NoMap“ modelis

Tai kažkas, ką pastebėjau, kad darau. Pagrindinė idėja yra vengti daryti „Cmd.map“ ir „Html.map“, todėl visi turi kalbėti ta pačia kalba, kitaip tariant, jūsų atnaujinimo ir peržiūros funkcijos turės grąžinti aukščiausio lygio „Msg“ tipą.

Turėdami tai, greičiausiai, turėsite žinutes, tokias kaip „MsgForLogin“, „MsgForRouter“ ir kt., Taigi savo rodinyje darytumėte ką nors panašaus:

mygtukas [onClick (MsgForLogin SignUp)] []

Taip aš pirmą kartą rekonstravau „TodoMVC“, tiesą sakant, pirmą kartą pamatęs „OutMsg“ nesupratau jo priežasties, nes aš nebendravau su savo žinutėmis.

Peržiūrėkite žaibolaidų programą, kad gautumėte didesnį šio metodo pavyzdį. Be to, atrodo, kad ši programa seka Kriso Jenkinso būdu struktūruoti „Guobų“ programas, o tai palaiko šį požiūrį, nes jis atskiria „Msgs“ tipus „Types.elm“ faile.

„Elm-taco“ biblioteka naudoja „OutMsg“ ir „NoMap“ šablonų derinį, turėdama aukščiausio lygio „taco“, į kurį galite siųsti pranešimus.

Stebėjimai ir palyginimai

Tirdamas ir reaguodamas į šiuos modelius, atkreipiau dėmesį į kai kuriuos dalykus, kurie gali būti pranašumai ar trūkumai, atsižvelgiant į jūsų poreikius:

  • „NoMap“ tėvų atnaujinimo funkcija išlieka tokia pati, kaip auga jūsų programa, o „OutMsg“ ir „Versti“ tėvų atnaujinimo funkcija gali labai išaugti, nes turite tvarkyti kiekvieno vaiko „OutMsg“ (pavyzdys).
  • Į „OutMsg“ ir „Versti“ įdėtuosius modulius nereikia nieko importuoti iš aukštesnių tėvų, todėl jie yra labiau įkapsuliuoti, kad būtų lengviau ištraukti ir paskelbti kai kuriuos submodulius kaip biblioteką, pvz.
  • Kad „NoMap“ veiktų, jūsų žinutės turėtų būti pateikiamos atskirame atnaujinimo faile, kitaip turėsite priklausomybės ciklą. Tai yra gera priežastis priversti jus suskaidyti dalykus, bet tuo pat metu blogai, jei norite turėti po vieną failą kiekvienam moduliui („Home.elm“, „Login.elm“, „Router.elm“).
  • „NoMap“ yra lengviau siųsti žinutes kitur, tačiau gali būti sunkiau sekti visus jos sukeltus valstybės pokyčius.
  • Kaip išmatuota šio rašymo metu, „TodoMVC“ reaktoriams „NoMap“ metodas turi 546 LOC, „OutMsg 561“ ir „Translator 612“, jei tai jums svarbu.
  • Naudodamiesi „NoMap“, jūs turite naudoti _ „visa apimančią“ bylą, kad nepaisytumėte žinučių iš kitų vietų, kurių nenorite tvarkyti, taigi kompiliatoriui yra mažiau pagalbos, jis negali pasakyti, ko jums trūksta (ačiū @mordrax, kad nurodėte kad dėl guobos lieknėja)
  • Naudodamiesi „OutMsg“ ir „Translator“, galite tiesiog ieškoti tipų ar vertėjų, kad sužinotumėte, kokie vaiko ir tėvų ryšiai yra reikalingi, taigi sudarytojas gali padėti jums juos įdiegti, o „NoMap“ šis ryšys yra labiau numanomas.
  • Panašu, kad vertėjo požiūris yra gera idėja, kai suteikiate savo žinutes išoriniam komponentui, pavyzdžiui, automatiniam užbaigimui.
  • Man buvo sunku sekti vertėjo modelį, o kuriant jį buvo sunkiau suprasti klaidų pranešimus iš kompiliatoriaus Elm
  • Jei nepakeisite (Model, Cmd Msg) standarto, galite naudoti puikią guobų grąžinimo biblioteką
  • Kai kurie žmonės mano, kad nenaudokite HTML.map kaip gerą praktiką, kad išvengtumėte „komponentų“
  • Sumaišydami šiuos metodus galite gauti daug naudos, pavyzdžiui, galite tiesiog išvengti HTML žemėlapių, skirtų vaizdams, vis tiek naudodami „OutMsg“ naujinimams, arba „NoMap“ galėtumėte naudoti tik aukščiausio lygio žinutėms, „OutMsgs“ apačioje, pateikiant išorinį išverstą komponentą

Šaltiniai

Manau, kad vaikų ir tėvų bendravimas dažnai yra svarbesnis, kai keičiamas mastelis ir daromi SPA, todėl daug dalykų, kuriuos radau, perskaičiau šią reddit giją apie „Scaling Elm Apps“:

Džiaugsmas!