Das Auto-Redraw-System
Mithril.js implementiert ein virtuelles DOM-Diffing-System für schnelles Rendering und bietet zusätzlich verschiedene Mechanismen, um eine detaillierte Kontrolle über das Rendering einer Anwendung zu erhalten.
In der typischen Anwendung verwendet Mithril.js ein Auto-Redraw-System, das das DOM synchronisiert, sobald Änderungen in der Datenebene vorgenommen werden. Das Auto-Redraw-System wird aktiviert, wenn Sie m.mount
oder m.route
aufrufen. Es bleibt jedoch deaktiviert, wenn Ihre App ausschließlich durch m.render
-Aufrufe initialisiert wird.
Das Auto-Redraw-System löst nach Abschluss bestimmter Funktionen automatisch ein Neuzeichnen (Re-Render) im Hintergrund aus.
Nach Ereignishandlern
Mithril.js führt automatisch ein Neuzeichnen nach DOM-Ereignis-Handlern aus, die in einer Mithril.js-View definiert sind:
var MyComponent = {
view: function () {
return m('div', { onclick: doSomething });
},
};
function doSomething() {
// Ein Neuzeichnen erfolgt synchron nach Ausführung dieser Funktion
}
m.mount(document.body, MyComponent);
Sie können das automatische Neuzeichnen für bestimmte Ereignisse deaktivieren, indem Sie e.redraw
auf false
setzen.
var MyComponent = {
view: function () {
return m('div', { onclick: doSomething });
},
};
function doSomething(e) {
e.redraw = false;
// Es wird kein Neuzeichnen mehr ausgelöst, wenn auf das Div-Element geklickt wird.
}
m.mount(document.body, MyComponent);
Nach m.request
Mithril.js führt nach Beendigung von m.request
automatisch ein Neuzeichnen aus:
m.request('/api/v1/users').then(function () {
// Nach Ausführung dieser Funktion erfolgt ein Neuzeichnen
});
Sie können das automatische Neuzeichnen für eine bestimmte Anfrage deaktivieren, indem Sie die Option background
auf true
setzen:
m.request('/api/v1/users', { background: true }).then(function () {
// Löst kein Neuzeichnen aus
});
Nach Routenänderungen
Mithril.js führt nach m.route.set()
-Aufrufen und nach Routenänderungen über Links mit m.route.Link
automatisch ein Neuzeichnen aus.
var RoutedComponent = {
view: function () {
return [
// Nach der Routenänderung erfolgt ein asynchrones Neuzeichnen
m(m.route.Link, { href: '/' }),
m('div', {
onclick: function () {
m.route.set('/');
},
}),
];
},
};
m.route(document.body, '/', {
'/': RoutedComponent,
});
Wann Mithril.js kein Neuzeichnen durchführt
Mithril.js führt nach setTimeout
, setInterval
, requestAnimationFrame
, nativen Promise
-Auflösungen und Ereignis-Handlern von Drittanbieterbibliotheken (z. B. Socket.io-Callbacks) kein Neuzeichnen aus. In diesen Fällen müssen Sie m.redraw()
manuell aufrufen.
Mithril.js führt auch kein Neuzeichnen nach Lebenszyklusmethoden durch. Teile der Benutzeroberfläche werden möglicherweise nach einem oninit
-Handler neu gerendert. Es kann aber auch sein, dass andere Teile der Benutzeroberfläche bereits neu gerendert wurden, wenn ein bestimmter oninit
-Handler aufgerufen wird. Handler wie oncreate
und onupdate
werden ausgelöst, nachdem die Benutzeroberfläche neu gezeichnet wurde.
Wenn Sie explizit ein Neuzeichnen innerhalb einer Lebenszyklusmethode auslösen möchten, sollten Sie m.redraw()
aufrufen. Dies löst ein asynchrones Neuzeichnen aus.
function StableComponent() {
var height = 0;
return {
oncreate: function (vnode) {
height = vnode.dom.offsetHeight;
m.redraw();
},
view: function () {
return m('div', 'Diese Komponente ist ' + height + ' Pixel hoch');
},
};
}
Mithril.js führt kein automatisches Neuzeichnen für Vnode-Bäume aus, die über m.render
gerendert werden. Dies bedeutet, dass nach Ereignisänderungen und m.request
-Aufrufen für Vnode-Bäume, die über m.render
gerendert wurden, keine Neuzeichnungen erfolgen. Wenn Ihre Architektur also eine manuelle Steuerung des Renderzeitpunkts erfordert (wie es beispielsweise bei der Verwendung von Bibliotheken wie Redux der Fall sein kann), sollten Sie m.render
anstelle von m.mount
verwenden.
Beachten Sie, dass m.render
einen Vnode-Baum erwartet und m.mount
eine Komponente:
// Verwenden Sie die Komponente in einem m()-Aufruf für m.render
m.render(document.body, m(MyComponent));
// Umschließen Sie die Komponente nicht für m.mount
m.mount(document.body, MyComponent);
Mithril.js vermeidet möglicherweise auch automatische Neuzeichnungen, wenn die Frequenz der angeforderten Neuzeichnungen höher als ein Animationsframe ist (typischerweise etwa 16 ms). Dies bedeutet beispielsweise, dass Mithril.js bei Verwendung von schnell auslösenden Ereignissen wie onresize
oder onscroll
die Anzahl der Neuzeichnungen automatisch reduziert, um Verzögerungen zu vermeiden.