System automatycznego odświeżania
Mithril.js implementuje system różnicowania wirtualnego DOM, który zapewnia szybkie renderowanie. Dodatkowo, oferuje różne mechanizmy umożliwiające precyzyjną kontrolę nad procesem renderowania aplikacji.
Idiomatyczne użycie Mithril.js opiera się na systemie automatycznego odświeżania, który synchronizuje DOM za każdym razem, gdy modyfikowane są dane. System ten jest aktywowany po wywołaniu m.mount
lub m.route
(pozostaje jednak wyłączony, jeśli aplikacja jest uruchamiana wyłącznie za pomocą m.render
).
System automatycznego odświeżania polega na wyzwalaniu funkcji ponownego renderowania w tle po zakończeniu wykonywania określonych operacji.
Po obsłudze zdarzeń
Mithril.js automatycznie odświeża widok po obsłudze zdarzeń DOM zdefiniowanych w widoku Mithril.js:
var MyComponent = {
view: function () {
return m('div', { onclick: doSomething });
},
};
function doSomething() {
// odświeżenie następuje synchronicznie po wykonaniu tej funkcji
}
m.mount(document.body, MyComponent);
Można wyłączyć automatyczne odświeżanie dla konkretnych zdarzeń, ustawiając właściwość e.redraw
na false
.
var MyComponent = {
view: function () {
return m('div', { onclick: doSomething });
},
};
function doSomething(e) {
e.redraw = false;
// nie wyzwala odświeżenia po kliknięciu na div
}
m.mount(document.body, MyComponent);
Po m.request
Mithril.js automatycznie odświeża widok po zakończeniu działania funkcji m.request
:
m.request('/api/v1/users').then(function () {
// odświeżenie następuje po wykonaniu tej funkcji
});
Można wyłączyć automatyczne odświeżanie dla konkretnego żądania, ustawiając opcję background
na true
:
m.request('/api/v1/users', { background: true }).then(function () {
// nie wyzwala odświeżenia
});
Po zmianach routingu
Mithril.js automatycznie odświeża widok po wywołaniach m.route.set()
oraz po zmianach routingu za pomocą linków wykorzystujących m.route.Link
.
var RoutedComponent = {
view: function () {
return [
// odświeżenie następuje asynchronicznie po zmianie routingu
m(m.route.Link, { href: '/' }),
m('div', {
onclick: function () {
m.route.set('/');
},
}),
];
},
};
m.route(document.body, '/', {
'/': RoutedComponent,
});
Kiedy Mithril.js nie odświeża widoku
Mithril.js nie odświeża widoku po wywołaniach setTimeout
, setInterval
, requestAnimationFrame
, natywnych obietnicach (Promise
) oraz w obsłudze zdarzeń bibliotek zewnętrznych (np. callbackach Socket.io). W takich przypadkach należy ręcznie wywołać m.redraw()
.
Mithril.js nie odświeża również widoku po wykonaniu metod cyklu życia komponentu. Fragmenty interfejsu użytkownika mogą być odświeżane po wywołaniu oninit
, ale inne części interfejsu mogły już zostać odświeżone, zanim dana obsługa oninit
zostanie uruchomiona. Metody takie jak oncreate
i onupdate
są uruchamiane po odświeżeniu interfejsu użytkownika.
Jeśli konieczne jest jawne wywołanie m.redraw()
w metodzie cyklu życia, należy wywołać m.redraw()
, co spowoduje asynchroniczne odświeżenie.
function StableComponent() {
var height = 0;
return {
oncreate: function (vnode) {
height = vnode.dom.offsetHeight;
m.redraw();
},
view: function () {
return m('div', 'This component is ' + height + 'px tall');
},
};
}
Mithril.js nie odświeża automatycznie drzew vnode renderowanych za pomocą m.render
. Oznacza to, że odświeżenia nie występują po zmianach zdarzeń i wywołaniach m.request
dla szablonów, które zostały renderowane za pomocą m.render
. Zatem, jeśli architektura aplikacji wymaga ręcznej kontroli nad momentem renderowania (co ma miejsce przy korzystaniu z bibliotek takich jak Redux), należy użyć m.render
zamiast m.mount
.
Należy pamiętać, że m.render
oczekuje drzewa vnode, a m.mount
oczekuje komponentu:
// opakuj komponent w wywołanie m() dla m.render
m.render(document.body, m(MyComponent));
// nie owijaj komponentu dla m.mount
m.mount(document.body, MyComponent);
Mithril.js może również unikać automatycznego odświeżania, jeśli częstotliwość żądanych odświeżeń jest wyższa niż jedna klatka animacji (zwykle około 16 ms). Oznacza to na przykład, że podczas korzystania z szybko wyzwalanych zdarzeń, takich jak onresize
lub onscroll
, Mithril.js automatycznie ograniczy liczbę odświeżeń, aby uniknąć spadków wydajności.