Skip to content
Mithril.js 2
Main Navigation ÚtmutatóAPI

magyar

English
简体中文
繁體中文
Español
Français
Русский
Português – Brasil
Deutsch
日本語
한국어
Italiano
Polski
Türkçe
čeština

magyar

English
简体中文
繁體中文
Español
Français
Русский
Português – Brasil
Deutsch
日本語
한국어
Italiano
Polski
Türkçe
čeština

Megjelenés

Sidebar Navigation

API

Alapvető API

m(selector, attributes, children)

render(element, vnodes)

mount(root, component)

route(root, defaultRoute, routes)

request(options)

parseQueryString(string)

buildQueryString(object)

buildPathname(object)

parsePathname(string)

trust(html)

fragment(attrs, children)

redraw()

censor(object, extra)

Opcionális API

stream()

Útmutató

Ezen az oldalon

route(root, defaultRoute, routes) ​

Leírás ​

Navigáció az alkalmazáson belüli oldalak között.

javascript
var Home = {
  view: function () {
    return 'Welcome';
  },
};

m.route(document.body, '/home', {
  '/home': Home, // defines `https://localhost/#!/home`
});

Egy alkalmazáson belül csak egy m.route hívás lehet.

Szignatúra ​

m.route(root, defaultRoute, routes)

ArgumentumTípusKötelezőLeírás
rootElementIgenEgy DOM elem, amely a részfa szülőcsomópontja lesz.
defaultRouteStringIgenAz az útvonal, amelyre átirányítás történik, ha az aktuális URL nem egyezik egyik útvonallal sem. Fontos megjegyezni, hogy ez nem a kezdeti útvonal. A kezdeti útvonal a böngésző címsorában lévő URL lesz.
routesObject<String,Component|RouteResolver>IgenEgy objektum, amelynek kulcsai útvonal karakterláncok, értékei pedig komponensek vagy egy RouteResolver.
returnsVisszatér: undefined

Hogyan kell olvasni a szignatúrákat

Statikus tagok ​

m.route.set ​

Átirányít egyező útvonalra, vagy az alapértelmezett útvonalra, ha nem található egyező útvonal. Aszinkron újrarajzolást vált ki az összes csatolási ponton.

m.route.set(path, params, options)

ArgumentumTípusKötelezőLeírás
pathStringIgenAz útvonal neve, előtag nélkül. Az útvonal tartalmazhat paramétereket, amelyek a params értékeivel vannak behelyettesítve.
paramsObjectNemÚtválasztási paraméterek. Ha a path útválasztási paraméterhelyeket tartalmaz, akkor ennek az objektumnak a tulajdonságai behelyettesítésre kerülnek az útvonal karakterláncba.
options.replaceBooleanNemMeghatározza, hogy új előzménybejegyzés jöjjön-e létre, vagy a jelenlegi legyen-e lecserélve. Alapértelmezés szerint false.
options.stateObjectNemA state objektum, amelyet az alapul szolgáló history.pushState / history.replaceState hívásnak kell átadni. Ez az állapotobjektum elérhetővé válik a history.state tulajdonságban, és egyesül az útválasztási paraméterek objektumával. Vegyük figyelembe, hogy ez az opció csak akkor működik, ha a pushState API-t használja, de figyelmen kívül hagyja, ha az útválasztó hashchange módba esik vissza (azaz, ha a pushState API nem érhető el).
options.titleStringNemA title karakterlánc, amelyet az alapul szolgáló history.pushState / history.replaceState hívásnak kell átadni.
returnsVisszatér: undefined

Ne feledd, hogy a .set használatakor a params-szal az útvonalat is definiálnod kell:

javascript
var Article = {
  view: function (vnode) {
    return 'This is article ' + vnode.attrs.articleid;
  },
};

m.route(document.body, {
  '/article/:articleid': Article,
});
m.route.set('/article/:articleid', { articleid: 1 });

m.route.get ​

Visszaadja az utolsó teljesen feloldott útvonalat, az előtag nélkül. Eltérhet a címsorban megjelenített útvonaltól, amíg egy aszinkron útvonal feloldásra vár.

path = m.route.get()

ArgumentumTípusKötelezőLeírás
returnsStringVisszaadja az utolsó teljesen feloldott útvonalat.

m.route.prefix ​

Definiál egy útválasztó előtagot. Az útválasztó előtag az URL egy része, amely meghatározza az útválasztó által használt stratégiát.

m.route.prefix = prefix

ArgumentumTípusKötelezőLeírás
prefixStringIgenAz az előtag, amely szabályozza a Mithril által használt útválasztási stratégiát.

Ez egy egyszerű tulajdonság, így olvashatod és írhatod is.

m.route.Link ​

Ez a komponens egy dinamikus útvonalas linket hoz létre. Lényege, hogy a linkeket hozzon létre helyi href-ekkel, amelyek az útvonal előtagot figyelembe véve átalakulnak.

javascript
m(m.route.Link, { href: '/foo' }, 'foo');

// Hacsak az m.route.prefix nem változott az alapértelmezett stratégiáról, a következőre renderel:
// <a href="#!/foo">foo</a>

A linkek a következő speciális attribútumokat fogadják el:

  • A selector az, ami az m első argumentumaként kerülne átadásra: bármilyen szelektort érvényes, beleértve a nem a elemeket is.
  • A params és az options azonos nevű argumentumok, mint a m.route.set-ben definiáltak.
  • A disabled, ha true, letiltja az útválasztási viselkedést és a hozzá tartozó onclick kezelőt, és egy data-disabled="true" attribútumot csatol a kisegítő lehetőségekhez; ha az elem egy a, a href el lesz távolítva.

Az útválasztási viselkedés nem akadályozható meg az eseménykezelő API-val. Használd helyette a disabled attribútumot.

javascript
m(
  m.route.Link,
  {
    href: '/foo',
    selector: 'button.large',
    disabled: true,
    params: { key: 'value' },
    options: { replace: true },
  },
  'link name'
);

// A következőre renderel:
// <button disabled aria-disabled="true" class="large">link name</button>

vnode = m(m.route.Link, attributes, children)

ArgumentumTípusKötelezőLeírás
attributes.hrefObjectIgenA navigálni kívánt célútvonal.
attributes.disabledBooleanNemAkadálymentesen letiltja az elemet.
attributes.selectorString|Object|FunctionNemEgy szelektort a m-hez, alapértelmezés szerint "a".
attributes.optionsObjectNemBeállítja a m.route.set-nek átadott options-t.
attributes.paramsObjectNemBeállítja a m.route.set-nek átadott params-ot.
attributesObjectNemBármely más attribútum, amelyet továbbítani kell az m-nek.
childrenArray<Vnode>|String|Number|BooleanNemGyermek vnode-ok ehhez a linkhez.
returnsVnodeEgy vnode.

m.route.param ​

Lekér egy útvonalparamétert az utolsó teljesen feloldott útvonalból. Az útvonalparaméter egy kulcs-érték pár. Az útvonalparaméterek a következő helyekről származhatnak:

  • útvonal interpolációk (pl. ha egy útvonal /users/:id, és /users/1-re oldódik fel, akkor az útvonalparaméternek van egy id kulcsa és egy "1" értéke)
  • útválasztó lekérdezési karakterláncok (pl. ha az útvonal /users?page=1, akkor az útvonalparaméternek van egy page kulcsa és egy "1" értéke)
  • history.state (pl. ha a history.state {foo: "bar"}, akkor az útvonalparaméternek van egy foo kulcsa és egy "bar" értéke)

value = m.route.param(key)

ArgumentumTípusKötelezőLeírás
keyStringNemEgy útvonalparaméter neve (pl. id a /users/:id útvonalban, vagy page a /users/1?page=3 útvonalban, vagy egy kulcs a history.state-ben).
returnsString|ObjectVisszaadja a megadott kulcs értékét. Ha nincs megadva kulcs, akkor egy objektumot ad vissza, amely tartalmazza az összes interpolációs kulcsot.

Vegye figyelembe, hogy egy RouteResolver onmatch függvényében az új útvonal még nincs teljesen feloldva, és az m.route.param() az előző útvonal paramétereit adja vissza, ha vannak ilyenek. Az onmatch az új útvonal paramétereit kapja meg argumentumként.

m.route.SKIP ​

Egy speciális érték, amelyet egy útvonal feloldó onmatch hívásából lehet visszaadni a következő útvonalra ugráshoz.

RouteResolver ​

A RouteResolver egy nem komponens objektum, amely tartalmaz egy onmatch metódust és/vagy egy render metódust. Mindkét metódus opcionális, de legalább az egyiknek jelen kell lennie.

Ha egy objektum komponensként azonosítható (egy view metódus jelenléte vagy egy function/class által), akkor akkor is annak fogják tekinteni, ha rendelkezik onmatch vagy render metódusokkal. Mivel a RouteResolver nem egy komponens, nincsenek életciklus metódusai.

Általános szabályként a RouteResolvereknek ugyanabban a fájlban kell lenniük, mint az m.route hívásnak, míg a komponens definícióknak saját moduljaikban kell lenniük.

routeResolver = {onmatch, render}

Komponensek használatakor úgy gondolhatsz rájuk, mint egy speciális cukorra ehhez az útvonal feloldóhoz, feltételezve, hogy a komponensed Home:

javascript
var routeResolver = {
  onmatch: function () {
    return Home;
  },
  render: function (vnode) {
    return [vnode];
  },
};

routeResolver.onmatch ​

Az onmatch hook akkor hívódik meg, amikor az útválasztónak meg kell találnia egy renderelendő komponenst. Útvonalváltozáskor egyszer hívódik meg, de a későbbi, ugyanazon az útvonalon történő újrarajzolásokkor nem. Használható logika futtatására a komponens inicializálása előtt (például hitelesítési logika, adat előtöltés, átirányítási analitika követés stb.).

Ez a metódus lehetővé teszi, hogy aszinkron módon definiáljuk, hogy melyik komponens kerül renderelésre, így alkalmas a kód felosztására és az aszinkron modul betöltésére. Egy komponens aszinkron rendereléséhez adj vissza egy ígéretet, amely egy komponensre oldódik fel.

Az onmatch-ról további információkért lásd a haladó komponens feloldás szekciót.

routeResolver.onmatch(args, requestedPath, route)

ArgumentumTípusLeírás
argsObjectAz útválasztási paraméterek.
requestedPathStringAz utolsó útválasztási művelet által kért útválasztó útvonal, beleértve az interpolált útválasztási paraméterértékeket, de az előtag nélkül. Amikor az onmatch meghívásra kerül, az útvonal feloldása nem fejeződött be, és az m.route.get() még mindig az előző útvonalat adja vissza.
routeStringAz utolsó útválasztási művelet által kért útválasztó útvonal, az interpolált útválasztási paraméterértékek nélkül.
returnsComponent|\Promise<Component>|undefinedVisszaad egy komponenst vagy egy ígéretet, amely egy komponensre oldódik fel.

Ha az onmatch egy komponenst vagy egy ígéretet ad vissza, amely egy komponensre oldódik fel, akkor ez a komponens kerül felhasználásra a RouteResolver render metódusának első argumentumában a vnode.tag-ként. Ellenkező esetben a vnode.tag "div"-re van állítva. Hasonlóképpen, ha az onmatch metódus elmarad, a vnode.tag szintén "div".

Ha az onmatch egy ígéretet ad vissza, amelyet elutasítanak, az útválasztó visszairányít a defaultRoute-ra. Ezt a viselkedést felülbírálhatod a .catch meghívásával az ígéretláncon, mielőtt visszaadnád.

routeResolver.render ​

A render metódus minden újrarajzoláskor meghívásra kerül, ha az útvonal egyezik. Hasonló a komponensek view metódusához, és azért létezik, hogy egyszerűsítse a komponens kompozíciót. Azt is lehetővé teszi, hogy felülírjuk a Mithril.js alapértelmezett viselkedését, amely a teljes részfát lecseréli.

vnode = routeResolver.render(vnode)

ArgumentumTípusLeírás
vnodeObjectEgy vnode, amelynek attribútum objektuma útválasztási paramétereket tartalmaz. Ha az onmatch nem ad vissza egy komponenst vagy egy ígéretet, amely egy komponensre oldódik fel, a vnode tag mezője alapértelmezés szerint "div".
vnode.attrsObjectEgy URL paraméterértékek térképe.
returnsArray<Vnode>|VnodeA renderelendő vnode-ok.

A vnode paraméter egyszerűen m(Component, m.route.param())-ként van definiálva, ahol a Component az útvonal feloldott komponense (az routeResolver.onmatch után), és az m.route.param() a itt dokumentáltak szerint. Ha kihagyod ezt a metódust, az alapértelmezett visszatérési érték [vnode], egy fragmentbe csomagolva, így használhatsz kulcsparamétereket. Egy :key paraméterrel kombinálva egy egyelemes kulcsolt fragment lesz, mivel valami olyasmire renderelődik, mint [m(Component, {key: m.route.param("key"), ...})].

Hogyan működik ​

Az útválasztás egy olyan rendszer, amely lehetővé teszi az egyoldalas alkalmazások (SPA) létrehozását, azaz olyan alkalmazásokét, amelyek "oldalról" "oldalra" tudnak menni anélkül, hogy teljes böngészőfrissítést okoznának.

Lehetővé teszi a zökkenőmentes navigációt, miközben megőrzi az egyes oldalak egyedi könyvjelzővel való ellátásának lehetőségét, valamint az alkalmazás böngésző előzmény mechanizmusán keresztüli navigálásának lehetőségét.

Az oldalak frissítése nélküli útválasztást részben a history.pushState API teszi lehetővé. Ennek az API-nak a használatával programozottan megváltoztatható a böngésző által megjelenített URL egy oldal betöltése után, de az alkalmazásfejlesztő felelőssége annak biztosítása, hogy egy adott URL-re való navigálás hideg állapotból (pl. egy új lap) a megfelelő jelölést renderelje.

Útválasztási stratégiák ​

Az útválasztási stratégia meghatározza, hogy egy könyvtár hogyan valósíthatja meg az útválasztást. Három általános stratégia létezik, amelyeket felhasználhatunk egy SPA útválasztási rendszer megvalósítására, és mindegyiknek más-más buktatói vannak:

  • m.route.prefix = '#!' (alapértelmezett) – Az URL fragment azonosítójának (más néven hash) részének használata. Az ezt a stratégiát használó URL általában a következőképpen néz ki: https://localhost/#!/page1.
  • m.route.prefix = '?' – A lekérdezési karakterlánc használata. Az ezt a stratégiát használó URL általában a következőképpen néz ki: https://localhost/?/page1.
  • m.route.prefix = '' – Az útvonalnév használata. Az ezt a stratégiát használó URL általában a következőképpen néz ki: https://localhost/page1.

A hash stratégia garantáltan működik azokban a böngészőkben, amelyek nem támogatják a history.pushState-et, mert vissza tud esni az onhashchange használatára. Használd ezt a stratégiát, ha a hasheket tisztán helyi szinten szeretnéd tartani.

A lekérdezési karakterlánc stratégia lehetővé teszi a szerveroldali észlelést, de nem jelenik meg normál útvonalként. Használd ezt a stratégiát, ha támogatni szeretnéd és potenciálisan észlelni szeretnéd a horgonyzott linkeket szerveroldalon, és nem tudod elvégezni az útvonalnév stratégia támogatásához szükséges változtatásokat (például ha Apache-ot használsz, és nem tudod módosítani a .htaccess-edet).

Az útvonalnév stratégia a legtisztább megjelenésű URL-eket eredményezi, de megköveteli a szerver beállítását, hogy az egyoldalas alkalmazás kódját minden olyan URL-ről kiszolgálja, amelyre az alkalmazás képes útvonalat létrehozni. Használd ezt a stratégiát, ha tisztább megjelenésű URL-eket szeretnél.

A hash stratégiát használó egyoldalas alkalmazások gyakran használják azt a konvenciót, hogy felkiáltójelet tesznek a hash után, jelezve, hogy a hashet útválasztási mechanizmusként használják, és nem horgonyokhoz való hivatkozásra. A #! karakterlánc hashbang néven ismert.

Az alapértelmezett stratégia a hashbangot használja.

Tipikus használat ​

Általában létre kell hoznod néhány komponenst, hogy az útvonalakhoz rendelhesd őket:

javascript
var Home = {
  view: function () {
    return [m(Menu), m('h1', 'Home')];
  },
};

var Page1 = {
  view: function () {
    return [m(Menu), m('h1', 'Page 1')];
  },
};

A fenti példában két komponens van: Home és Page1. Mindegyik tartalmaz egy menüt és valamilyen szöveget. A menü maga is komponensként van definiálva az ismétlés elkerülése érdekében:

javascript
var Menu = {
  view: function () {
    return m('nav', [
      m(m.route.Link, { href: '/' }, 'Home'),
      m(m.route.Link, { href: '/page1' }, 'Page 1'),
    ]);
  },
};

Most már definiálhatunk útvonalakat, és hozzárendelhetjük a komponenseinket:

javascript
m.route(document.body, '/', {
  '/': Home,
  '/page1': Page1,
});

Itt két útvonalat adunk meg: / és /page1, amelyek a megfelelő komponenseiket renderelik, amikor a felhasználó az egyes URL-ekre navigál.

Navigálás különböző útvonalakra ​

A fenti példában a Menu komponensnek két m.route.Link-je van. Ez létrehoz egy elemet, alapértelmezés szerint egy <a>-t, és beállítja úgy, hogy ha a felhasználó rákattint, akkor az önmagában egy másik útvonalra navigáljon. Nem navigál távolról, csak helyben.

Programozott módon is navigálhat az m.route.set(route) segítségével. Például m.route.set("/page1").

Az útvonalak közötti navigáláskor az útválasztó automatikusan kezeli az előtagot. Más szóval, hagyd ki a hashbang #!-t (vagy bármilyen előtagot, amire az m.route.prefix-et beállítottad), amikor Mithril.js útvonalakat linkelsz, beleértve az m.route.set-ben és az m.route.Link-ben is.

Ne feledd, hogy a komponensek közötti navigáláskor a teljes részfát lecseréli. Használj útvonal feloldót render metódussal, ha csak a részfát szeretnéd javítani.

Útválasztási paraméterek ​

Néha szeretnénk, hogy egy változó azonosító vagy hasonló adat megjelenjen az útvonalban, de nem akarunk explicit módon külön útvonalat megadni minden lehetséges azonosítóhoz. Ennek eléréséhez a Mithril.js támogatja a paraméterezett útvonalakat:

javascript
var Edit = {
  view: function (vnode) {
    return [m(Menu), m('h1', 'Editing ' + vnode.attrs.id)];
  },
};
m.route(document.body, '/edit/1', {
  '/edit/:id': Edit,
});

A fenti példában egy /edit/:id útvonalat definiáltunk. Ez létrehoz egy dinamikus útvonalat, amely megfelel minden olyan URL-nek, amely /edit/-tel kezdődik, és amelyet valamilyen adat követ (pl. /edit/1, edit/234 stb.). Az id érték ezután a komponens vnode attribútumaként van hozzárendelve (vnode.attrs.id).

Lehetőség van több argumentumot is megadni egy útvonalban, például a /edit/:projectID/:userID a komponens vnode attribútum objektumán a projectID és a userID tulajdonságokat eredményezné.

Kulcsparaméter ​

Amikor egy felhasználó egy paraméterezett útvonalról ugyanarra az útvonalra navigál egy másik paraméterrel (pl. /page/1-ről /page/2-re való áttérés egy /page/:id útvonal esetén), a komponens nem kerülne újból létrehozásra a semmiből, mivel mindkét útvonal ugyanarra a komponensre oldódik fel, és így egy virtuális dom helyben történő diff-et eredményez. Ennek mellékhatása az onupdate hook aktiválása az oninit/oncreate helyett. Azonban viszonylag gyakori, hogy egy fejlesztő szinkronizálni szeretné a komponens újbóli létrehozását az útvonalváltozási eseményhez.

Ennek eléréséhez kombinálhatod az útvonalparaméterezést a kulcsokkal egy kényelmes megoldás érdekében:

javascript
m.route(document.body, '/edit/1', {
  '/edit/:key': Edit,
});

Ez azt jelenti, hogy az útvonal gyökérkomponensének vnode-jában a key útvonalparaméter elérhető lesz. Az útvonalparaméterek a vnode-ban attrs-okká válnak. Így, amikor egyik oldalról a másikra ugrunk, a key megváltozik, és a komponens a semmiből újra létrejön (mivel a kulcs azt mondja a virtuális dom motornak, hogy a régi és az új komponensek különböző entitások).

Ezt az ötletet tovább lehet vinni olyan komponensek létrehozására, amelyek újratöltéskor újra létrehozzák magukat:

m.route.set(m.route.get(), {key: Date.now()})

Vagy akár használhatod a history state funkciót az újratölthető komponensek eléréséhez anélkül, hogy az URL-t szennyeznéd:

m.route.set(m.route.get(), null, {state: {key: Date.now()}})

Ne feledd, hogy a kulcsparaméter csak komponens útvonalakon működik. Ha útvonal feloldót használsz, akkor egy egyelemes kulcsolt fragmentet kell használnod, átadva a key: m.route.param("key")-t, hogy ugyanazt elérd.

Variadikus útvonalak ​

Használhatunk variadikus útvonalakat is, azaz egy olyan útvonalra, amelynek argumentuma URL útvonalneveket tartalmaz, amelyek perjeleket tartalmaznak:

javascript
m.route(document.body, '/edit/pictures/image.jpg', {
  '/edit/:file...': Edit,
});

404-es hibák kezelése ​

Izomorf/univerzális JavaScript alkalmazások esetén egy URL paraméter és egy variadikus útvonal kombinációja nagyon hasznos az egyéni 404-es hibaoldal megjelenítéséhez.

404 Nem található hiba esetén a szerver egy egyéni oldalt küld vissza a kliensnek. Amikor a Mithril.js betöltődik, átirányítja a klienst az alapértelmezett útvonalra, mert nem tudja, hogy az az útvonal.

javascript
m.route(document.body, '/', {
  '/': homeComponent,
  // [...]
  '/:404...': errorPageComponent,
});

Előzmény állapot ​

Teljes mértékben kihasználhatjuk a mögöttes history.pushState API-t a felhasználói navigációs élmény javítása érdekében. Például egy alkalmazás "megjegyezheti" egy nagy űrlap állapotát, amikor a felhasználó elnavigál egy oldalról. Így, ha a felhasználó megnyomja a böngészőben a Vissza gombot, az űrlap kitöltve lesz, nem pedig üres.

Például létrehozhatsz egy ilyen űrlapot:

javascript
var state = {
  term: '',
  search: function () {
    // save the state for this route
    // this is equivalent to `history.replaceState({term: state.term}, null, location.href)`
    m.route.set(m.route.get(), null, {
      replace: true,
      state: { term: state.term },
    });

    // navigate away
    location.href = 'https://google.com/?q=' + state.term;
  },
};

var Form = {
  oninit: function (vnode) {
    state.term = vnode.attrs.term || ''; // populated from the `history.state` property if the user presses the back button
  },
  view: function () {
    return m('form', [
      m("input[placeholder='Search']", {
        oninput: function (e) {
          state.term = e.target.value;
        },
        value: state.term,
      }),
      m('button', { onclick: state.search }, 'Search'),
    ]);
  },
};

m.route(document.body, '/', {
  '/': Form,
});

Így ha a felhasználó keres, majd a Vissza gombot nyomja meg, a bemenet továbbra is a keresési kifejezéssel lesz kitöltve. Ez a technika javíthatja a nagy űrlapok és más olyan alkalmazások felhasználói élményét, ahol a nem perzisztált állapot előállítása fáradságos a felhasználó számára.

Útválasztó előtagjának módosítása ​

Az útválasztó előtag az URL azon része, amely meghatározza az útválasztó által használt stratégiát.

javascript
// set to pathname strategy
m.route.prefix = '';

// set to querystring strategy
m.route.prefix = '?';

// set to hash without bang
m.route.prefix = '#';

// set to pathname strategy on a non-root URL
// e.g. if the app lives under `https://localhost/my-app` and something else
// lives under `https://localhost`
m.route.prefix = '/my-app';

Haladó komponens megoldás ​

Ahelyett, hogy egy komponenst egy útvonalhoz rendelnénk, megadhatunk egy RouteResolver objektumot vagy RouteResolver-t. Egy RouteResolver objektum tartalmaz egy onmatch() és/vagy egy render() metódust. Mindkét metódus választható, de legalább az egyiknek jelen kell lennie.

javascript
m.route(document.body, '/', {
  '/': {
    onmatch: function (args, requestedPath, route) {
      return Home;
    },
    render: function (vnode) {
      return vnode; // egyenértékű a m(Home)-mal
    },
  },
});

A RouteResolver-ek hasznosak a különféle haladó útválasztási felhasználási esetek megvalósításához.

Elrendezési komponens körbefoglalása ​

Gyakran kívánatos az összes vagy a legtöbb útvonalhoz rendelt komponenst egy újrafelhasználható sablonba (gyakran "elrendezésnek" nevezik) csomagolni. Ehhez először létre kell hoznia egy olyan komponenst, amely tartalmazza a közös jelölőnyelvet, amely a különböző komponensek köré kerül:

javascript
var Layout = {
  view: function (vnode) {
    return m('.layout', vnode.children);
  },
};

A fenti példában az elrendezés csupán egy <div class="layout"> elemből áll, amely tartalmazza a komponensnek átadott gyermekeket, de a valós életben ez olyan összetett lehet, amennyire csak szükséges.

Az elrendezés körbefoglalásának egyik módja egy névtelen komponens definiálása az útvonalak térképén:

javascript
// 1. példa
m.route(document.body, '/', {
  '/': {
    view: function () {
      return m(Layout, m(Home));
    },
  },
  '/form': {
    view: function () {
      return m(Layout, m(Form));
    },
  },
});

Azonban vegye figyelembe, hogy mivel a legfelső szintű komponens egy névtelen komponens, a / útvonalról a /form útvonalra (vagy fordítva) való ugráskor az lebontásra kerül. Emiatt újra létrehozza a DOM-ot. Ha az Layout komponensben életciklus metódusok vannak definiálva, az oninit és az oncreate hook-ok minden útvonalváltáskor lefutnak. Az alkalmazástól függően ez kívánatos lehet, vagy nem.

Ha azt szeretné, hogy az Layout komponens a változások alapján frissüljön, és ne legyen minden alkalommal újra létrehozva, akkor ehelyett egy RouteResolver-t kell használnia gyökér objektumként:

javascript
// 2. példa
m.route(document.body, '/', {
  '/': {
    render: function () {
      return m(Layout, m(Home));
    },
  },
  '/form': {
    render: function () {
      return m(Layout, m(Form));
    },
  },
});

Vegye figyelembe, hogy ebben az esetben, ha az Layout komponens rendelkezik oninit és oncreate életciklus metódusokkal, akkor azok csak az első útvonalváltáskor futnak le (feltételezve, hogy minden útvonal ugyanazt az elrendezést használja).

A két példa közötti különbség szemléltetése érdekében az 1. példa egyenértékű ezzel a kóddal:

javascript
// funkcionálisan egyenértékű az 1. példával
var Anon1 = {
  view: function () {
    return m(Layout, m(Home));
  },
};
var Anon2 = {
  view: function () {
    return m(Layout, m(Form));
  },
};

m.route(document.body, '/', {
  '/': {
    render: function () {
      return m(Anon1);
    },
  },
  '/form': {
    render: function () {
      return m(Anon2);
    },
  },
});

Mivel az Anon1 és az Anon2 különböző komponensek, az alágaik (beleértve az Layout-ot is) a semmiből újra létrejönnek. Ez akkor is megtörténik, ha a komponenseket RouteResolver nélkül használják közvetlenül.

A 2. példában, mivel az Layout a legfelső szintű komponens mindkét útvonalon, az Layout komponens DOM-ja összehasonlításra kerül (azaz sértetlenül marad, ha nincsenek változások), és csak a Home-ról a Form-ra való változás váltja ki a DOM ezen szakaszának újbóli létrehozását.

Átirányítás ​

A RouteResolver onmatch hook-ja lehetővé teszi logika futtatását, mielőtt egy útvonal legfelső szintű komponense inicializálódik. Használhatja a Mithril m.route.set() függvényét vagy a natív HTML history API-ját. A history API-val történő átirányításkor az onmatch hook-nak egy soha be nem teljesülő Promise-t kell visszaadnia, hogy az útvonalváltás ne fejeződjön be. Az m.route.set() belsőleg megszakítja a megfeleltetett útvonal feloldását, így ez nem szükséges vele.

Példa: Hitelesítés ​

Az alábbi példa bemutatja, hogyan lehet megvalósítani egy bejelentkezési falat, amely megakadályozza, hogy a felhasználók láthassák a /secret oldalt, hacsak nem jelentkeznek be.

javascript
var isLoggedIn = false;

var Login = {
  view: function () {
    return m('form', [
      m(
        'button[type=button]',
        {
          onclick: function () {
            isLoggedIn = true;
            m.route.set('/secret');
          },
        },
        'Login'
      ),
    ]);
  },
};

m.route(document.body, '/secret', {
  '/secret': {
    onmatch: function () {
      if (!isLoggedIn) m.route.set('/login');
      else return Home;
    },
  },
  '/login': Login,
});

Amikor az alkalmazás betöltődik, az onmatch meghívódik, és mivel az isLoggedIn hamis, az alkalmazás átirányít a /login oldalra. Miután a felhasználó megnyomta a bejelentkezés gombot, az isLoggedIn igaz értékre állítódik, és az alkalmazás átirányít a /secret oldalra. Az onmatch hook ismét lefut, és mivel az isLoggedIn ezúttal igaz, az alkalmazás rendereli a Home komponenst.

Az egyszerűség kedvéért a fenti példában a felhasználó bejelentkezett állapotát egy globális változóban tároljuk el, és ennek az értéke változik, amikor a felhasználó a bejelentkezés gombra kattint. A valós alkalmazásokban a felhasználónak megfelelő bejelentkezési adatokat kell megadnia. A bejelentkezés gombra kattintva egy kérés indul el a szerver felé a felhasználó hitelesítéséhez.

javascript
var Auth = {
  username: '',
  password: '',

  setUsername: function (value) {
    Auth.username = value;
  },
  setPassword: function (value) {
    Auth.password = value;
  },
  login: function () {
    m.request({
      url: '/api/v1/auth',
      params: { username: Auth.username, password: Auth.password },
    }).then(function (data) {
      localStorage.setItem('auth-token', data.token);
      m.route.set('/secret');
    });
  },
};

var Login = {
  view: function () {
    return m('form', [
      m('input[type=text]', {
        oninput: function (e) {
          Auth.setUsername(e.target.value);
        },
        value: Auth.username,
      }),
      m('input[type=password]', {
        oninput: function (e) {
          Auth.setPassword(e.target.value);
        },
        value: Auth.password,
      }),
      m('button[type=button]', { onclick: Auth.login }, 'Login'),
    ]);
  },
};

m.route(document.body, '/secret', {
  '/secret': {
    onmatch: function () {
      if (!localStorage.getItem('auth-token')) m.route.set('/login');
      else return Home;
    },
  },
  '/login': Login,
});

Adatok előtöltése ​

Jellemzően egy komponens inicializáláskor adatokat tölthet be. Az adatok ilyen módon történő betöltése kétszer rendereli a komponenst. Az első renderelési fázis az útválasztáskor következik be, a második pedig a kérés befejezése után. Fontos megjegyezni, hogy a loadUsers() egy Promise-t ad vissza, de az oninit által visszaadott bármely Promise jelenleg figyelmen kívül van hagyva. A második renderelési fázis az m.request background opciójából származik.

javascript
var state = {
  users: [],
  loadUsers: function () {
    return m.request('/api/v1/users').then(function (users) {
      state.users = users;
    });
  },
};

m.route(document.body, '/user/list', {
  '/user/list': {
    oninit: state.loadUsers,
    view: function () {
      return state.users.length > 0
        ? state.users.map(function (user) {
            return m('div', user.id);
          })
        : 'loading';
    },
  },
});

A fenti példában az első rendereléskor a felhasználói felület a "loading" szöveget jeleníti meg, mivel a state.users egy üres tömb, mielőtt a kérés befejeződne. Ezután, amint az adatok elérhetővé válnak, a felhasználói felület újrarajzolódik, és megjelenik a felhasználói azonosítók listája.

A RouteResolver-ek használhatók az adatok előtöltésére a komponens renderelése előtt. Ezzel elkerülhető a felhasználói felület villogása, és nem lesz szükség betöltési indikátorra.

javascript
var state = {
  users: [],
  loadUsers: function () {
    return m.request('/api/v1/users').then(function (users) {
      state.users = users;
    });
  },
};

m.route(document.body, '/user/list', {
  '/user/list': {
    onmatch: state.loadUsers,
    render: function () {
      return state.users.map(function (user) {
        return m('div', user.id);
      });
    },
  },
});

A fentiek alapján a render csak a kérés befejezése után fut le, így a feltételes operátor redundáns.

Kód felosztás ​

Egy nagyméretű alkalmazásban kívánatos lehet az egyes útvonalak kódjának igény szerinti letöltése, ahelyett, hogy az összes kódot előre betöltenénk. A kódbázis ilyen módon történő felosztása kódosztásként vagy késleltetett betöltésként ismert. A Mithril.js-ben ez úgy érhető el, hogy egy Promise-t adunk vissza az onmatch hook-ból:

A legegyszerűbb formájában a következőket lehet tenni:

javascript
// Home.js
module.export = {
  view: function () {
    return [m(Menu), m('h1', 'Home')];
  },
};
javascript
// index.js
function load(file) {
  return m.request({
    method: 'GET',
    url: file,
    extract: function (xhr) {
      return new Function(
        'var module = {};' + xhr.responseText + ';return module.exports;'
      );
    },
  });
}

m.route(document.body, '/', {
  '/': {
    onmatch: function () {
      return load('Home.js');
    },
  },
});

Azonban a valóságban, ahhoz, hogy ez éles környezetben működjön, a Home.js modul összes függőségét egyetlen fájlba kell csomagolni. Ezt a fájlt szolgálja ki a szerver.

Szerencsére számos eszköz segíti a modulok késleltetett betöltéshez történő csomagolását. Íme egy példa a natív dinamikus import(...) használatával, amelyet sok csomagoló támogat:

javascript
m.route(document.body, '/', {
  '/': {
    onmatch: function () {
      return import('./Home.js');
    },
  },
});

Ellenőrzött útvonalak ​

Bizonyos speciális esetekben szükség lehet az útvonalak paramétereinek szigorúbb ellenőrzésére, például csak numerikus azonosítókat engedélyezni. Ezt meglehetősen egyszerűen megteheti, ha m.route.SKIP értéket ad vissza egy útvonalról.

javascript
m.route(document.body, '/', {
  '/view/:id': {
    onmatch: function (args) {
      if (!/^\d+$/.test(args.id)) return m.route.SKIP;
      return ItemView;
    },
  },
  '/view/:name': UserView,
});

Rejtett útvonalak ​

Például, ha egy felhasználó nem tekinthet meg egy másik felhasználót, nem szeretnénk engedélyezési hibát mutatni. Ehelyett úgy teszünk, mintha az adott útvonal nem létezne, és egy 404-es oldalt jelenítünk meg. Ebben az esetben használhatja az m.route.SKIP parancsot, hogy úgy tegyen, mintha az útvonal nem létezne.

javascript
m.route(document.body, '/', {
  '/user/:id': {
    onmatch: function (args) {
      return Model.checkViewable(args.id).then(function (viewable) {
        return viewable ? UserView : m.route.SKIP;
      });
    },
  },
  '/:404...': PageNotFound,
});

Útvonal blokkolása ​

A RouteResolver onmatch megakadályozhatja az útvonal betöltését egy soha be nem teljesülő Promise visszaadásával. Ez felhasználható a redundáns útvonalváltási kísérletek észlelésére és megszakítására:

javascript
m.route(document.body, '/', {
  '/': {
    onmatch: function (args, requestedPath) {
      if (m.route.get() === requestedPath) return new Promise(function () {});
    },
  },
});

Külső integráció ​

Bizonyos helyzetekben előfordulhat, hogy együtt kell működnie egy másik keretrendszerrel, például a React-tel. Íme, hogyan kell csinálni:

  • Definiálja az összes útvonalat az m.route használatával a szokásos módon, de győződjön meg arról, hogy csak egyszer használja. Több útvonalpont nem támogatott.
  • Ha el kell távolítania az útválasztási feliratkozásokat, használja az m.mount(root, null) parancsot, ugyanazzal a gyökérelemmel, amelyet az m.route(root, ...) parancsban használt. Az m.route belsőleg az m.mount függvényt használja a működéshez, tehát ez nem varázslat.

Íme egy példa a React-tel:

jsx
class Child extends React.Component {
  constructor(props) {
    super(props);
    this.root = React.createRef();
  }

  componentDidMount() {
    m.route(this.root, '/', {
      // ...
    });
  }

  componentDidUnmount() {
    m.mount(this.root, null);
  }

  render() {
    return <div ref={this.root} />;
  }
}

És itt van a durva megfelelője a Vue-val:

html
<div ref="root"></div>
javascript
Vue.component('my-child', {
  template: `<div ref="root"></div>`,
  mounted: function () {
    m.route(this.$refs.root, '/', {
      // ...
    });
  },
  destroyed: function () {
    m.mount(this.$refs.root, null);
  },
});
Pager
Előző oldalmount(root, component)
Következő oldalrequest(options)

A MIT licenc alapján kiadva.

Copyright (c) 2024 Mithril Contributors

https://mithril.js.org/route.html

A MIT licenc alapján kiadva.

Copyright (c) 2024 Mithril Contributors