Skip to content

Commit

Permalink
composable views
Browse files Browse the repository at this point in the history
  • Loading branch information
yoshuawuyts committed Mar 13, 2018
1 parent 03feaaa commit c541d7f
Showing 1 changed file with 66 additions and 0 deletions.
66 changes: 66 additions & 0 deletions content/docs/views/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
<body>
<header>This is the header</header>
${childView(state, emit)}
<footer>This is the footer</footer>
</body>
`
}
}

function main (state, emit) { // 5.
return html`
<h1>I'm the main view</h1>
`
}

function foo (state, emit) { // 6.
return html`
<h1>fooooooooooo view</h1>
`
}
```

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'`.

0 comments on commit c541d7f

Please sign in to comment.