Alkalmazás architektúrája elmében

Ez az útmutató azt az általános felépítést írja le, amelyet az Elm minden alkalmazásában megtalál. a TodoMVC-től az álomíróhoz.

Tanulni fogunk egy nagyon egyszerű módon kapcsolódni egy alkalmazás, amely egy végtelenül beágyazott blokk. Nagymértékben javítja a modularitást, egyszerűsíti a kódok újrafelhasználását és tesztelését. Ezzel összetett alkalmazásokat hozhat létre, összetevőként törölheti azokat. Egy kis példával indulunk, és fokozatosan bővítjük ezeket az alapelveket.

Érdekes módon egy ilyen architektúra természetes módon keletkezik Elmben. Magának a nyelvnek a megtervezése hozza hozzá, akár olvassa ezt a szöveget, akár nem. Ezt a mintát egyszerűen Elm segítségével találtam meg, és megdöbbentette az egyszerűség és az erő.

Megjegyzés. A kód kipróbálásához telepítenie kell az Elm-et, és ki kell készítenie az adattárat. Minden példa utasításokat tartalmaz a kód futtatására vonatkozóan.

Alapfogadás

Az egyes programok logikája három jól elkülönülő részre oszlik: modell, frissítés és megjelenítés. Ezt a csontváz projektet minden alkalommal elindíthatja, majd fokozatosan töltse ki az adott feladat részleteit.

Az egész oktatóanyag ezt a mintát kis változásokkal és kiegészítésekkel fogjuk használni.

1. példa: Számláló

A kód egy nagyon egyszerű modellel kezdődik. Csak egy számot kell nyomon követnünk:

Amikor frissíti a modellt, ez is nagyon egyszerű. Meghatározzuk az elvégzendő műveletek sorát, és hozzáadhatjuk a feldolgozást a frissítési funkcióhoz:

Most csak a modellünk megjelenítéséhez szükséges. Az elm-html használatával HTML-t készítünk, amely megjelenik a böngészőben. Hozzunk létre egy div. tartalmaz: egy csökkentő gombot, egy divot a számláló aktuális értékével és egy növelési gombot.

A nézet funkció legnehezebb része a Signal.Address. Ezzel foglalkozunk a következő részben, de most szeretném, ha megjegyeznéd, hogy ez a kód teljesen deklaratív. Vigye a modellt és ad ki néhány Html-et. És ez minden. Semmi esetre sem csinálunk kézi DOM változást, amely sok lehetőséget kínál az optimalizálásra, sőt nagyban felgyorsítja mindent. Nagyszerű. Ráadásul a nézetfunkció a leggyakoribb feladat, és létrehozásakor felhasználhatjuk az Elm modulrendszer, a tesztkeretek és a könyvtárak teljes erejét.

Ez az Elm alkalmazás bármely elrendezésének lényege. A példák, amelyeket alább láthatunk, csak ennek a vastag mintanak a kis változatai: a modell, a frissítés, a nézet.

Visszavonulás: Alkalmazásának revitalizálása jelekkel

Vessünk egy pillantást a kód részével a Signal.Address.

Ezt megelőzően csak a tiszta funkciókról és a változatlan adatokról beszéltünk. Nagyszerű, de reagálni kell a külvilág eseményeire is. Elmben jelek vannak. A jel olyan érték, amely idővel változik, lehetővé téve számunkra, hogy beszéljünk arról, hogyan változik a modellünk.

Elvileg minden program rendelkezik ezzel a kis kóddal, amely az egész alkalmazást szolgálja. Az 1. példában ez így néz ki:

Szeretném felhívni a figyelmet néhány részletre:

  1. A modell kiindulási értékével a 0 értékkel kezdjük.
  2. A frissítési funkciót használjuk a modell állapotának továbbfejlesztéséhez.
  3. Válaszolunk a csatornára érkező cselekvésekre (cselekvésre).
  4. Mindezt megjelenítjük a képernyőn a nézet funkció segítségével.

Ahelyett, hogy azonnal megpróbálnám megérteni, hogy mi történik minden sorban, először azt javaslom, hogy vizsgálja meg, mi történik magas szinten.

A kék rész a mi programunk, azaz pontosan a modell / update / display, amelyről beszéltünk. Legtöbbször dolgozhat anélkül, hogy elhagyná a határait ezen a területen.

Újak itt a "csatornák", és hogyan engedélyezik az új műveletek (Akció) megjelenését a felhasználói bevitelre válaszul. A képen a szaggatott vonalak a monitorról a programra vonatkoznak. Amikor bizonyos csatornákat hozzárendelünk a nézet funkcióhoz. meghatározzuk, hogyan illeszkedik a felhasználó tevékenysége a kódunkba. Ne feledje, hogy nem végezzük el ezeket a műveleteket, hanem egyszerűen regisztráljuk őket a fő programunkra. Ez az elválasztás kulcsfontosságú!

Szeretném megjegyezni, hogy ez a kód a Signal by and large-lal ugyanazt jelenti az összes Elm programban. Lehet, hogy többet szeretne tudni a jelekről. de az olvasás folytatásához elegendő lesz e közös megegyezés. Szeretnénk leírni az architektúrát, és nem szabad elakadni, hogy minden működik. Így folytassuk a példánk bővítését!

2. példa: Egy számlálópár

Az első példában egy egyszerű számlálót hoztunk létre, de hogyan fog ez kicsinyíteni, amikor két számlálóra van szükségünk? Meg tudjuk őrizni a modularitást?

Fő feladatunk az előző példa teljes kódjának újrafelhasználása. Ehhez egy független számlálómodult hozunk létre. amelyben a számláló végrehajtásának minden részletét megfogalmaztuk. Az egyetlen változás a nézet funkció. így nem fogom nyilvánosságra hozni az összes régi definíciót.

Most, hogy van az alapszámláló modulunk. Létre kell hozni az CounterPair alkalmazást. Mint mindig, a modellel kezdjük:

A mi modellünk két rekordot tartalmazó rekord, minden olyan számlán, amelyet a képernyőn meg akarunk jeleníteni. Ez teljes mértékben tükrözi az alkalmazás állapotát. Mi is az init funkció. új modell létrehozása, amikor szükségünk van rá.

Ezután meghatározzuk a támogatni kívánt műveletek sorát. Ezúttal: resetelhetünk minden számlálót, frissíthetjük a felső számlálót vagy frissíthetjük az alsó számlálót.

Ne feledje, hogy csatlakozási típusunk a Counter.Action típusát jelzi. de nem ismerjük ezeknek az akcióknak a finomságát. A frissítési funkció létrehozásakor egyszerűen elküldjük ezeket a műveleteket a megfelelő helyre:

És végül csak a kijelző funkcióját kell megtennie, amely megmutatja mind a mérőt, mind a képernyőn megjelenő reset gombot.

3. példa: A számlálók dinamikus listája

Néhány számláló hűvös, de mi van a számlálók listájával, amelyhez újakat adhatsz hozzá és törölheted őket igény szerint? Foglalkozni fog a recepción?

Ebben a példában azonos számlálómodult használunk. a 2. példában leírtak szerint.

Ez azt jelenti, hogy azonnal megkezdődik a CounterList modul. Mint mindig, a modellel kezdjük:

Most modellünk a számlálók listája, mindegyik saját egyedi azonosítóval rendelkezik. Ezek az azonosítók lehetővé teszik számunkra, hogy megkülönböztessük a számlálókat, és mikor szeretnénk frissíteni a negyedik, könnyű módja lesz erre. (Ezenkívül ezek az azonosítók kényelmes módot adnak arra, hogy egyedi kulcsot határozzanak meg, amikor az elemek megjelenítésének optimalizálására gondolunk, de most nem foglalkozunk ezzel a témával). Ezenkívül a modell egy következő mezővel is rendelkezik. Segítségével egyedi számlálókat rendelhetünk hozzá új számlálók hozzáadásakor.

Lássunk egy sor intézkedést, amelyet alkalmazhatunk a modellünkre. Szeretnénk hozzáadni a számlálókat, törölni őket, és megváltoztatnunk az egyes számlálók értékeit.

Típusegyesítő tevékenységünk nagyon hasonlít a fent leírt viselkedéshez.

Ismerjük meg a frissítési funkciót.

Az egyes esetek általános leírása:

Beszúrás - először új számlálót hozunk létre, és a lista végére helyezzük. Ezután megnöveljük a következőID-et úgy, hogy legközelebb készen álljon az azonosító.

Eltávolítás - Távolítsa el az első elemet a számlálók listáján.

Módosítás - Átmegyünk a számlálók listáján, és ha a kívánt azonosítót elkapjuk, a számláló műveletét hívjuk.

Csak a megjelenített funkció maradt.

Amikor létrehozzuk az alkalmazás nézetfunkcióját, az egyes listaelemeken a viewCounter funkciót használjuk. És amikor létrehozunk és törlünk olyan gombokat, amelyek közvetlenül a cím címére küldik az üzeneteket.

Hasonló azonosító trükk használható bárhol, ahol dinamikusan beágyazott összetevőkre van szükség. A számlálók meglehetősen egyszerűek, de ez a minta pontosan ugyanúgy működik, ha van egy listája a felhasználói profilokról, tweetekről, hírek hírcsatornákról vagy termékekről.

4. példa: A számlálók speciális listája

Oké, a dolgok egyszerű és moduláris a számlálók listájához, de mi van, ha egy közös reset gomb helyett mindegyik számlálónak megvan a saját törlési gombja? Biztosan eltöri mindent!

Nem, működik.

Ebben az esetben szükségünk van egy új módra a számlálók gombjaival történő létrehozásához. Elhagyhatjuk a régi nézet funkciót, és csak egy új viewWithRemoveButton-ot adhatunk hozzá. amely egy kissé eltérő modellt fog húzni. Nem szükséges duplikálni a kódot, vagy őrült mutatványokat hagyni örökléssel vagy túlterheléssel. Egyszerűen új funkciót adunk hozzá a modul nyilvános felületéhez, amely az új funkciókat valósítja meg!

Most, hogy van egy viewWithRemoveButton. létrehozhatunk egy CounterList modult. amelyben összegyűjtjük az összes számlálót. A Model típus ugyanazt fogja használni, mint a 3. példában: a számlálók listája és egy egyedi szám.

A lehetséges lépések kissé eltérnek. Az összes régi számláló törlése helyett csak azt szeretnénk törölni, amelynek azonosítója megegyezik a megadott számmal.

A frissítési funkció nem különbözik nagymértékben az előző példától.

Amikor eltávolításra kerül, eltávolítjuk a számlálót, amelynek azonosítója meg kell szüntetni. A többiek mindegyike ugyanolyan.

Végül összegyűjtjük mindezt együtt:

Alapvető leckék

Alapvető vétel - Mindent a Model típus körül építettek. frissítés funkció frissítéséhez és a funkció megjelenítéséhez. Továbbá csak ennek a módszernek az eltérései vannak.

Kontextus hozzáadása - Néha további információkra van szüksége a modell frissítéséhez vagy megjelenítéséhez. Ezeket a funkciókat mindig hozzá lehet adni a fő típus típusának betöltése nélkül.

Minden fészkelő szinten meghatározhatjuk ezt a kontextust. amely a belső komponensekhez szükséges.

Könnyű tesztelés - Minden funkció tiszta. Ez lehetővé teszi számukra, hogy nagyon könnyű tesztelni - nincs szükség speciális inicializálásra vagy mesterséges környezetre, csak adja meg azokat az érveket, amelyeket meg akar próbálni.

Egy másik sablon

Van egy másik fontos módszer az alapmódszer kibővítésére. Előfordulhat például, hogy frissítenie kell az összetevőt, és az eredménytől függően a program egy másik részén módosítania kell valami mást. A frissítési funkciót meghosszabbíthatja. így több információt nyer.

A feldolgozási logikai frissítéstől függően. elmondhatjuk valakinek a fentieket, hogy frissítsék a tartalmat vagy adjanak ki valamit. Hasonlóképpen, egy komponens eltávolíthatja magát:

Ha nem teljesen világos, hogy ez hogyan működik, akkor talán egy példát fogok írni, amely ezt a technikát használja. Addig is hasonló példákat tekinthet meg az Elm TodoMVC alkalmazás vicces verziójára.

Kapcsolódó cikkek