Életciklus-metódusok
Használat
A komponensek és a virtuális DOM csomópontok használhatnak életciklus-metódusokat, más néven hookokat, melyek a DOM elem élettartama során különböző pontokon futnak le.
// Példa hook komponensben
var ComponentWithHook = {
oninit: function (vnode) {
console.log('komponens inicializálása');
},
view: function () {
return 'hello';
},
};
// Példa hook vnode-ban
function initializeVnode() {
console.log('vnode inicializálása');
}
m(ComponentWithHook, { oninit: initializeVnode });
Minden életciklus metódus megkapja a vnode-ot első argumentumként, és a this
kulcsszó a vnode.state
-hez van kötve.
Az életciklus metódusok csak a m.render()
hívás mellékhatásaként hívódnak meg. Nem hívódnak meg, ha a DOM a Mithril-en kívül kerül módosításra.
A DOM elem életciklusa
Egy DOM elem tipikusan létrejön és hozzáadásra kerül a dokumentumhoz. Ezután frissülhetnek az attribútumai vagy a gyermek csomópontjai, amikor egy UI esemény bekövetkezik és az adat megváltozik; és az elem eltávolítható a dokumentumból.
Miután egy elemet eltávolítottak, ideiglenesen megőrizhető a memóriában. A tárolt elemet újra lehet használni egy későbbi frissítésben (ezt a folyamatot DOM újrahasznosításnak nevezik). Egy elem újrahasznosítása elkerüli annak a teljesítményköltségét, hogy újra létre kelljen hozni egy nemrég létezett elem másolatát.
oninit
Az oninit(vnode)
hook meghívódik, mielőtt a virtuális DOM motor feldolgozna egy vnode-ot. Az oninit
garantáltan lefut, mielőtt a DOM elem a dokumentumhoz lenne csatolva, és garantáltan lefut a szülő vnode-okon a gyermekeik előtt, de nem garantálja az ősök és leszármazottak DOM elemeinek létezését. Soha ne próbálja elérni a vnode.dom
-ot az oninit
metódusból.
Ez a hook nem hívódik meg, amikor egy elem frissül, de meghívódik, ha egy elemet újrahasznosítanak.
Más hookokhoz hasonlóan az oninit
callback-ben a this
kulcsszó a vnode.state
-re mutat.
Az oninit
hook segít a komponens állapotának inicializálásában a vnode.attrs
vagy a vnode.children
segítségével átadott argumentumok alapján.
function ComponentWithState() {
var initialData;
return {
oninit: function (vnode) {
initialData = vnode.attrs.data;
},
view: function (vnode) {
return [
// megjeleníti az adatokat az inicializálási időből:
m('div', 'Initial: ' + initialData),
// megjeleníti az aktuális adatokat:
m('div', 'Current: ' + vnode.attrs.data),
];
},
};
}
m(ComponentWithState, { data: 'Hello' });
Ebből a metódusból nem szabad szinkron módon módosítani a modell adatokat. Mivel az oninit
nem garantálja más elemek állapotát, az ebből a metódusból származó modellváltozások nem biztos, hogy tükröződnek a felhasználói felület minden részén a következő renderelési ciklusig.
oncreate
Az oncreate(vnode)
hook meghívódik, miután egy DOM elem létrejött és a dokumentumhoz lett csatolva. Az oncreate
garantáltan a renderelési ciklus végén fut le, így biztonságos elolvasni az elrendezési értékeket, mint például a vnode.dom.offsetHeight
és a vnode.dom.getBoundingClientRect()
ebből a metódusból.
Ez a hook nem hívódik meg, amikor egy elem frissül.
Más hookokhoz hasonlóan az oncreate
callback-ben a this
kulcsszó a vnode.state
-re mutat. Azok a DOM elemek, amelyek vnode-jai rendelkeznek oncreate
hookkal, nem lesznek újrahasznosítva.
Az oncreate
hook hasznos az elrendezési értékek elolvasására, amelyek újrarajzolást válthatnak ki, animációk indítására és harmadik féltől származó könyvtárak inicializálására, amelyekhez a DOM elemre való hivatkozás szükséges.
var HeightReporter = {
oncreate: function (vnode) {
console.log(
'Inicializálva a következő magassággal: ',
vnode.dom.offsetHeight
);
},
view: function () {},
};
m(HeightReporter, { data: 'Hello' });
Ebből a metódusból nem szabad szinkron módon módosítani a modell adatokat. Mivel az oncreate
a renderelési ciklus végén fut le, az ebből a metódusból származó modellváltozások nem fognak tükröződni a felhasználói felületen a következő renderelési ciklusig.
onupdate
Az onupdate(vnode)
hook meghívódik, miután egy DOM elem frissült. Az onupdate
garantáltan a renderelési ciklus végén fut le, így biztonságos elolvasni az elrendezési értékeket, mint például a vnode.dom.offsetHeight
és a vnode.dom.getBoundingClientRect()
ebből a metódusból.
Ez a hook csak akkor hívódik meg, ha az elem létezett az előző renderelési ciklusban. Nem hívódik meg, amikor egy elem létrejön vagy amikor újrahasznosítják.
Azok a DOM elemek, amelyek vnode-jai rendelkeznek onupdate
hookkal, nem kerülnek újrahasznosításra.
Az onupdate
hook hasznos az elrendezési értékek olvasására, amelyek újrarajzolást válthatnak ki, és a felhasználói felületet befolyásoló állapot dinamikus frissítésére harmadik féltől származó könyvtárakban, miután a modell adatai megváltoztak.
function RedrawReporter() {
var count = 0;
return {
onupdate: function () {
console.log('Eddigi újrarajzolások: ', ++count);
},
view: function () {},
};
}
m(RedrawReporter, { data: 'Hello' });
onbeforeremove
Az onbeforeremove(vnode)
hook meghívódik, mielőtt egy DOM elem leválasztásra kerül a dokumentumról. Ha egy Promise kerül visszaadásra, a Mithril.js csak a Promise lefutása után választja le a DOM elemet.
Ez a hook csak azon a DOM elemen hívódik meg, amely elveszíti a parentNode
-ját, de nem hívódik meg a gyermek elemeiben.
Más hookokhoz hasonlóan az onbeforeremove
callback-ben a this
kulcsszó a vnode.state
-re mutat. Azok a DOM elemek, amelyek vnode-jai rendelkeznek onbeforeremove
hookkal, nem kerülnek újrahasznosításra.
var Fader = {
onbeforeremove: function (vnode) {
vnode.dom.classList.add('fade-out');
return new Promise(function (resolve) {
setTimeout(resolve, 1000);
});
},
view: function () {
return m('div', 'Bye');
},
};
onremove
Az onremove(vnode)
hook meghívódik, mielőtt egy DOM elem eltávolításra kerül a dokumentumból. Ha egy onbeforeremove
hook is definiálva van, az onremove
hook az onbeforeremove
által visszaadott promise befejezése után fut le.
Ez a hook minden olyan elemen meghívódik, amelyet eltávolítanak a dokumentumból, függetlenül attól, hogy közvetlenül a szülőjéről lett-e leválasztva, vagy egy másik elem gyermeke, amelyet leválasztottak.
Más hookokhoz hasonlóan az onremove
callback-ben a this
kulcsszó a vnode.state
-re mutat. Azok a DOM elemek, amelyek vnode-jai rendelkeznek onremove
hookkal, nem kerülnek újrahasznosításra.
Az onremove
hook hasznos a takarítási feladatok elvégzésére.
function Timer() {
var timeout = setTimeout(function () {
console.log('lejárt az idő');
}, 1000);
return {
onremove: function () {
clearTimeout(timeout);
},
view: function () {},
};
}
onbeforeupdate
Az onbeforeupdate(vnode, old)
hook meghívódik, mielőtt egy vnode különbségkeresésen (diffing) esne át egy frissítésben. Ha ez a függvény definiálva van és false
értéket ad vissza, a Mithril.js megakadályozza, hogy a vnode-on, és következésképpen a vnode gyermekein különbségkeresés történjen.
Ez a hook önmagában nem akadályozza meg egy virtuális DOM fa generálását, hacsak az adott fa nincs egy komponensen belül beágyazva.
Más hookokhoz hasonlóan az onbeforeupdate
callback-ben a this
kulcsszó a vnode.state
-re mutat.
Ez a hook hasznos a frissítések késleltetésének csökkentésére olyan esetekben, amikor túl nagy DOM fa van.
Kerülendő anti-minták
Bár a Mithril.js rugalmas, néhány kódmintát nem ajánlott használni:
Kerülje az elhamarkodott optimalizálásokat
Az onbeforeupdate
-et csak utolsó megoldásként szabad használni a különbségkeresés kihagyására. Kerülje a használatát, hacsak nincs észrevehető teljesítményproblémája.
A tipikus teljesítményproblémák, amelyek az onbeforeupdate
segítségével javíthatók, egyetlen nagy elemtömbben gyökereznek. Ebben az összefüggésben a "nagy" általában bármely olyan tömböt jelent, amely nagyszámú csomópontot tartalmaz, legyen az széles eloszlású (a hírhedten nagy, 5000 soros táblázat), vagy egy mély, sűrű fában.
Ha teljesítményproblémája van, először gondolja át, hogy a felhasználói felület jó felhasználói élményt nyújt-e, és ha nem, javítsa ki. Például nagyon valószínűtlen, hogy egy felhasználó valaha is átszitálna 5000 sornyi nyers táblázatos adatot, és nagyon valószínű, hogy egy felhasználó számára könnyebb lenne egy olyan keresési funkciót használni, amely csak a néhány legrelevánsabb elemet adja vissza.
Ha egy tervezés alapú megoldás nem kivitelezhető, és optimalizálnia kell egy nagyszámú DOM elemet tartalmazó felhasználói felületet, alkalmazza az onbeforeupdate
-et a legnagyobb tömb szülő csomópontján, és értékelje újra a teljesítményt. Az esetek túlnyomó többségében egyetlen ellenőrzésnek elegendőnek kell lennie. Abban a ritka esetben, ha nem, ismételje meg, de egyre óvatosabbnak kell lennie minden új onbeforeupdate
deklarációval. Több onbeforeupdate
egy kódszagot jelez, amely a tervezési munkafolyamatban lévő prioritási problémákat jelzi.
Kerülje az optimalizálás alkalmazását az alkalmazás más területeire "csak a biztonság kedvéért". Ne feledje, hogy általánosságban elmondható, hogy több kód magasabb karbantartási költséget von maga után, mint kevesebb kód, és az onbeforeupdate
-hez kapcsolódó hibák különösen nehezen háríthatók el, ha az objektum identitására támaszkodik a feltételes ellenőrzésekhez.
Még egyszer, az onbeforeupdate
hookot csak utolsó lehetőségként szabad használni.