If you want to show anything on your page, you’re going to have to write a template. A template is the html to display on each page view. And if you use resources, they nest! Ember, by default, uses the Handlebars template engine.
Lunchtime!
It’s a Friday and I want ribs for lunch. But I don’t want to go alone. I’ll just write an intranet app that lets me invite a few coworkers to lunch. Because email is hard.
Begin at the beginning.
The default template is the application template. you can tell it’s the application because it doesn’t have a name. The application template is used to lay out the main page structure and all the site branding. all other templates are nested inside and show up where the {{outlet}} tag is used.
<br/> <script type="text/x-handlebars"> <h1>Lunch-o-Matic!</h1> <div class="subtext">Meet your coworkers for lunch</div> {{outlet}} </script><br/>
But, that alone isn’t very interesting, is it?
Okay, lets start off by managing some expectations. I’ll cover Controllers next week, but I’ll be mentioning them often. About 1/2 of the cool things about templates have some counterpart in the controller supporting them. That said, I’m getting hungry. Let’s gather up the team and head out for Barbecue!
I Decide who Leaves and who Dines!
I need to display a list of my coworkers so I can pick a couple of them.
<br/> <script type="text/x-handlebars" data-template-name="lunchPicker"> <h2>Who's in?</h2> {{input value=lunchType placeholder="What's for Lunch"}} <table><tr><th>invite?</th><th>name</th><th>email</th></tr> {{#each employee in employees}} {{#if employee.isAvailable}} <tr><td>{{input type="checkbox" checked=employee.isSelected}}</td> <td>{{employee.fullName}} ({{employee.initials}})</td> <td>{{employee.email}}</td> </tr> {{/if}} {{/each}} </script><br/>
A few things to note in the above example. I’m using an {{input}} block to make a text field that binds to the controller property lunchType. That will be used to let everyone know what kind of food we’re going to eat! Next, I’m looping over the a list of employees using an {{#each}} block. The collection comes from another controller property. Each element is then scoped as ‘employee’ inside the each block. I can conditionally skip displaying an employee if they are not available. more correctly, I can use an {{#if}} block to show only the available employees. I display a checkbox using a built in helper, {{input}}. It binds the checked state of the input control to the isSelected property of the employee. The last three are simple data bindings to text. They just forward properties from the model to html.
The Web Without Links isn’t the True Web.
Let’s tweak the employee listing. I want to make the name link to their info page. I can use the {{link-to}} block.
<br/> ... <br/> <tr><td>{{input type='checkbox' checked=employee.isSelected}}</td><br/> <td>{{link-to 'employee' employee.employee_id}}<br/> {{employee.fullName}}<br/> {{/link-to}}<br/> ({{employee.initials}})</td><br/> <td>{{employee.email}}</td><br/> ...<br/>
But we need to DO something!
Wonderful! Things are moving right along. Now, how do I submit my selections? With an action! An action is a function in the controller. I promise, we will get to that later. Just trust me when I say our bindings put all the information in the model, so we don’t need to pass anything to the function. We just need to bind the action to a button, right after the end of our {{#each}} block.
<br/> ... <br/> <button {{action 'pickThem'}}>Choose these Coworkers</button><br/>
We can pass parameters in to the function, but we don’t need to at this time. In addition, we don’t have to worry about controlling event propagation or target a different controller. All of these are possible, just not necessary for us.
Your Bill Comes with Mints
There are a few things we can do to help us clean up our code from here.
Helper isn’t just for Hamburgers
A helper is a function that gets called like a block. It returns text to be displayed in the Html. If you need to format dates, for example, or want to display an employee’s spark-line for their time on the tread mill in the past two weeks.
Partials
Partials are templates that can be reused. They bind to what ever model or controller is in the context, just incase your data doesn’t look like you expected because you named something slightly wrong.
Views
A view can pick it’s own template. It has a bit more logic, but I’ wouldn’t go crazy building complex controls with them. In a couple weeks, we’ll cover Components and then we’ll go nuts.