diff --git a/content/docs/views/index.md b/content/docs/views/index.md index 65a79b4..ba80f0a 100644 --- a/content/docs/views/index.md +++ b/content/docs/views/index.md @@ -214,3 +214,69 @@ module.exports = function (state, emit) { showing the same title we already have, then we don't need to do anything. Conditional statements are less instructions on the CPU than function calls, so this provides us with a little speedup (and less noise). + +## Composable Views +As applications grow, you'll probably find that there will be plenty of views +that share a lot of the same layout. If you find that you're repeating the same +layout in a lot of code, it can be beneficial to make it reusable instead. + +The most common way to create reusable templates, is to create a function that +takes a view as an argument and returns a view. Inside the function the +childView is called, and wrapped with some HTML. The end result is a nicely +composed function that's also known as a "composable view", "higher order view", +"template". + +This might sound a little abstract. So let's create an example higher order +view, which has a static header and footer, but takes the content as an +argument. + +_note: There's not an exact word for what we're doing here. Because it's a +pattern, and not an API the exact word also doesn't matter too much. This is +also not at all the only way to compose functions - so don't worry too much +about getting the terminology right - we're also just making it up as we go._ + +```js +var html = require('choo/html') +var choo = require('choo') + +var app = choo() +app.route('/', template(main)) // 1. +app.route('/bar', template(bar)) // 2. +app.mount('body') + +function template (childView) { // 3. + return (state, emit) => { // 4. + return html` + +
This is the header
+ ${childView(state, emit)} + + + ` + } +} + +function main (state, emit) { // 5. + return html` +

I'm the main view

+ ` +} + +function foo (state, emit) { // 6. + return html` +

fooooooooooo view

+ ` +} +``` + +1. We create a route `'/'` which calls the `template` function, and passes it + the `main` view function. +2. We create a route `'/foo'` which calls the `template` function, and passes it + the `foo` view function. +3. This is where the bulk of the action happens. We create a function named + `'template'` which takes a view as an argument (`childView`). +4. The `'template'` function returns another function. This is the function + we'll be passing to `app.route()`. It's a valid view. When the view is + called, it calls the `childView`, and wraps it with DOM elements. +5. We define a view named `'main'`. +6. We define a view named `'foo'`.