autoredraw docs
This commit is contained in:
parent
6b15378c41
commit
26a5d7d6bb
2 changed files with 121 additions and 0 deletions
120
docs/autoredraw.md
Normal file
120
docs/autoredraw.md
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
# The auto-redraw system
|
||||
|
||||
Mithril implements a virtual DOM diffing system for fast rendering, and in addition, it offers various mechanisms to gain granular control over the rendering of an application.
|
||||
|
||||
When used idiomatically, Mithril employs an auto-redraw system that synchronizes the DOM whenever changes are made in the data layer. The auto-redraw system becomes enabled when you call `m.mount` or `m.route` (but it stays disabled if your app is bootstrapped solely via `m.render` calls).
|
||||
|
||||
The auto-redraw system simply consists of triggering a re-render function behind the scenes after certain functions complete.
|
||||
|
||||
### After event handlers
|
||||
|
||||
Mithril automatically redraws after DOM event handlers that are defined in a Mithril view:
|
||||
|
||||
```javascript
|
||||
var MyComponent = {
|
||||
view: function() {
|
||||
return m("div", {onclick: doSomething})
|
||||
}
|
||||
}
|
||||
|
||||
function doSomething() {
|
||||
//a redraw happens synchronously after this function runs
|
||||
}
|
||||
|
||||
m.mount(document.body, MyComponent)
|
||||
```
|
||||
|
||||
You can disable an auto-redraw for specific events by setting `e.redraw` to `false`.
|
||||
|
||||
```javascript
|
||||
var MyComponent = {
|
||||
view: function() {
|
||||
return m("div", {onclick: doSomething})
|
||||
}
|
||||
}
|
||||
|
||||
function doSomething(e) {
|
||||
e.redraw = false
|
||||
// no longer triggers a redraw when the div is clicked
|
||||
}
|
||||
|
||||
m.mount(document.body, MyComponent)
|
||||
```
|
||||
|
||||
|
||||
### After m.request
|
||||
|
||||
Mithril automatically redraws after [`m.request`](request.md) completes:
|
||||
|
||||
```javascript
|
||||
m.request("/api/v1/users").then(function() {
|
||||
//a redraw happens after this function runs
|
||||
})
|
||||
```
|
||||
|
||||
You can disable an auto-redraw for a specific request by setting the `background` option to true:
|
||||
|
||||
```javascript
|
||||
m.request("/api/v1/users", {background: true}).then(function() {
|
||||
//does not trigger a redraw
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
### After route changes
|
||||
|
||||
Mithril automatically redraws after [`m.route.set()`](route.md#routeset) calls (or route changes via links that use [`m.route.link`](route.md#routelink)
|
||||
|
||||
```javascript
|
||||
var RoutedComponent = {
|
||||
view: function() {
|
||||
return [
|
||||
// a redraw happens asynchronously after the route changes
|
||||
m("a", {href: "/", oncreate: m.route.link}),
|
||||
m("div", {
|
||||
onclick: function() {
|
||||
m.route.set("/")
|
||||
}
|
||||
}),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
m.route(document.body, "/", {
|
||||
"/": RoutedComponent,
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### When Mithril does not redraws
|
||||
|
||||
Mithril does not redraw after 3rd party library event handlers. In those cases, you must manually call [`m.redraw()`](redraw.md).
|
||||
|
||||
Mithril also does not redraw after lifecycle methods. This is because lifecycle methods run within the redraw cycle and allowing a nested redraw to run could cause loss of stability or even stack overflows. If you need to trigger a redraw within a lifecycle method, you should call `m.redraw` from within the callback of an asynchronous function such as `requestAnimationFrame`, `Promise.resolve` or `setTimeout`.
|
||||
|
||||
```javascript
|
||||
var StableComponent = {
|
||||
oncreate: function(vnode) {
|
||||
vnode.state.height = vnode.dom.offsetHeight
|
||||
requestAnimationFrame(function() {
|
||||
m.redraw()
|
||||
})
|
||||
},
|
||||
view: function() {
|
||||
return m("div", "This component is " + vnode.state.height + "px tall")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Mithril does not auto-redraw vnode trees that are rendered via `m.render`. This means redraws do not occur after event changes and `m.request` calls for templates that were rendered via `m.render`. Thus, if your architecture requires manual control over when rendering occurs (as can sometimes be the case when using libraries like Redux), you should use `m.render` instead of `m.mount`.
|
||||
|
||||
Remember that `m.render` expects a vnode tree, and `m.mount` expects a component:
|
||||
|
||||
```javascript
|
||||
// wrap the component in a m() call for m.render
|
||||
m.render(document.body, m(MyComponent))
|
||||
|
||||
// don't wrap the component for m.mount
|
||||
m.mount(document.body, MyComponent)
|
||||
```
|
||||
|
|
@ -9,6 +9,7 @@
|
|||
- [Components](components.md)
|
||||
- [Lifecycle methods](lifecycle-methods.md)
|
||||
- [Keys](keys.md)
|
||||
- [Autoredraw system](autoredraw.md)
|
||||
- Social
|
||||
- [Community chat](https://gitter.im/lhorie/mithril.js)
|
||||
- [Mithril Jobs](https://github.com/lhorie/mithril.js/wiki/JOBS)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue