Автоматическая перерисовка
Mithril.js использует систему сравнения виртуального DOM для быстрой отрисовки и предоставляет различные механизмы для детального контроля над процессом перерисовки приложения.
При правильном использовании Mithril.js задействует систему автоматической перерисовки, которая синхронизирует DOM при внесении изменений в данные приложения. Автоматическая перерисовка включается при вызове m.mount
или m.route
(но остается отключенной, если ваше приложение отрисовывается исключительно через вызовы m.render
).
Система автоматической перерисовки автоматически запускает функцию перерисовки после завершения определенных операций.
После обработчиков событий
Mithril.js автоматически перерисовывает DOM после выполнения обработчиков DOM-событий, определенных в представлении Mithril.js:
var MyComponent = {
view: function () {
return m('div', { onclick: doSomething });
},
};
function doSomething() {
// перерисовка выполняется синхронно после завершения этой функции
}
m.mount(document.body, MyComponent);
Вы можете отключить автоматическую перерисовку для конкретного события, установив свойство e.redraw
в значение false
.
var MyComponent = {
view: function () {
return m('div', { onclick: doSomething });
},
};
function doSomething(e) {
e.redraw = false;
// больше не вызывает перерисовку при нажатии на div
}
m.mount(document.body, MyComponent);
После m.request
Mithril.js автоматически перерисовывает DOM после завершения m.request
:
m.request('/api/v1/users').then(function () {
// перерисовка происходит после выполнения этой функции
});
Вы можете отключить автоматическую перерисовку для конкретного запроса, установив для параметра background
значение true
:
m.request('/api/v1/users', { background: true }).then(function () {
// не вызывает перерисовку
});
После изменений маршрута
Mithril.js автоматически перерисовывает DOM после вызовов m.route.set()
и после изменений маршрута через ссылки, созданные с помощью m.route.Link
.
var RoutedComponent = {
view: function () {
return [
// перерисовка происходит асинхронно после изменения маршрута
m(m.route.Link, { href: '/' }),
m('div', {
onclick: function () {
m.route.set('/');
},
}),
];
},
};
m.route(document.body, '/', {
'/': RoutedComponent,
});
В каких случаях Mithril.js не выполняет перерисовку
Mithril.js не перерисовывает DOM после setTimeout
, setInterval
, requestAnimationFrame
, нативных промисов Promise
и обработчиков событий сторонних библиотек (например, обратных вызовов Socket.io). В этих случаях необходимо вручную вызвать m.redraw()
.
Mithril.js также не перерисовывает DOM после выполнения методов жизненного цикла компонента. Некоторые элементы интерфейса могут быть перерисованы после обработчика oninit
, но другие элементы интерфейса, возможно, уже были перерисованы к моменту срабатывания обработчика oninit
. Обработчики, такие как oncreate
и onupdate
, срабатывают после перерисовки пользовательского интерфейса.
Если вам необходимо инициировать перерисовку из метода жизненного цикла, следует вызвать m.redraw()
, что вызовет асинхронную перерисовку.
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 не выполняет автоматическую перерисовку vnode-деревьев, которые отображаются с помощью m.render
. Это означает, что перерисовки не происходят после изменений, вызванных событиями. Также перерисовки не происходят после вызовов m.request
для шаблонов, отрисованных с помощью m.render
. Таким образом, если ваша архитектура требует ручного управления процессом рендеринга (что иногда бывает при использовании таких библиотек, как Redux), вам следует использовать m.render
вместо m.mount
.
Помните, что m.render
ожидает дерево vnode, а m.mount
ожидает компонент:
// оберните компонент в вызов m() для m.render
m.render(document.body, m(MyComponent));
// не оборачивайте компонент для m.mount
m.mount(document.body, MyComponent);
Mithril.js также может избегать автоматической перерисовки, если частота запрошенных перерисовок превышает один кадр анимации (обычно около 16 мс). Это означает, например, что при использовании частых событий, таких как onresize
или onscroll
, Mithril.js будет автоматически ограничивать количество перерисовок, чтобы избежать задержек.