3. Templates
§ Re-use code
§ Encapsulate responsibility for a specific rendering
§ Knockout supports many popular templating engines
o
o
jQuery Templates
Underscore
§ Knockout has native templates
4. Named Templates in <script> tags
§ Encapsulate a template for re-use
<div
data-‐bind="template:
{name:
'personTmpl'}"></div>
<script
type="text/html"
id="personTmpl">
<span
data-‐bind="text:
firstName"></span>
<span
data-‐bind="text:
lastName"></span>
<button
data-‐bind="click:selectPerson">Add</button>
</script>
7. Control of Flow
if
• If truthy condition
ifnot
• If falsy condition
foreach
with
• Execute for each item in a list
• Shortcut to execute for the object
8. Control of Flow with a Template
§ Pass the context for the template with “foreach”
<tbody
data-‐bind="template:
{name:
'productsTmpl',
foreach:
lines}">
</tbody>
<script
type="text/html"
id="productsTmpl">
<tr>
<td
style="width:
100px;">
<input
data-‐bind="value:
quantity"
/>
</td>
...
</tr>
</script>
9. Conditional Control of Flow
Any “truthy” expression
<p
data-‐bind="if:
lines().length
>
0">
<span>Total
value:</span>
<span
data-‐bind="text:
grandTotal()"></span>
</p>
10. Change Context “with“Control of Flow
<div>
<div
data-‐bind="text:
model().brand"></div>
<div
data-‐bind="text:
model().name"></div>
</div>
Change the context
with “with”
<div
data-‐bind="with:
model">
<div
data-‐bind="text:
brand"></div>
<div
data-‐bind="text:
name"></div>
</div>
11. Parent Binding Contexts
§ Sometimes in templates you want to change
data binding scope (Data Context)
o
o
o
o
$data
$parent
$parents
$root
<button
data-‐bind="click:
$parent.addItem">Add</button>
14. Inline Templates with Control of Flow
§ If not reusing it, there is no need to name a template
§ Control of flow elements create an implicit template
<tbody
data-‐bind="foreach:
lines">
<tbody
<tr>
data-‐bind="template:
{name:
'productsTmpl',
foreach:
lines}">
<td
style="width:
100px;">
</tbody>
Template is
<input
data-‐bind="value:
qty"/>
</td>
<script
type="text/html"
id="productsTmpl">
created
anonymously
...
<tr>
and implicitly
</tr>
<td
style="width:
100px;">
</tbody>
<input
data-‐bind="value:
qty"
/>
</td>
...
</tr>
</script>
15. Knockout’s Native Template Engine
§ Templates inside DOM elements
o
o
<script>
Other DOM elements like <div>
§ Anonymous / Inline templates
o
o
All Part of the
Native Template Engine
in Knockout
Templates without a name
Shortcuts to Anonymous template binding
o
o
o
o
if
ifnot
with
foreach
No external
templating dependency
20. Dynamically Change Templates
§ Swap between multiple templates
§ Bind the name of the template
<div
data-‐bind="template:
{name:
templateChoice}">
<script
type="text/html"
id="tmplSummary">
...
</script>
<script
type="text/html"
id="tmplDetails">
...
</script>
my.vm.templateChoice
=
function
()
{
return
showDetails()
?
"tmplDetails"
:
"tmplSummary";
};
21. Control of Flow to Toggle Templates
§ if and ifnot bindings
<div
data-‐bind="ifnot:
showDetails()">
...
</div>
<div
data-‐bind="if:
showDetails()">
...
</div>
my.vm.showDetails
=
ko.observable(false);
24. Template Bindings
name
foreach
data
afterRender
afterAdd
beforeRemove
• Id of an element that contains the template
• Renders the template in foreach mode
• (once for each item)
• Object to supply as data for the template.
• If omitted, uses foreach context or the current context
• Callback invoked after DOM elements are rendered
• Callback invoked after DOM elements are added
• Callback invoked before DOM elements are removed
25. Template Binding Helpers
Callback to a method
<ul
data-‐bind="template:
{
in the viewmodel
name:
'friendsTemplate',
foreach:
model().Friends,
beforeRemove:
showAni,
beforeRemove:
function(elem)
{
$(elem).slideUp()
},
afterAdd:
hideAni}">
afterAdd:
function(elem)
{
$(elem).hide().slideDown()
}
}">
</ul>
28. Containerless Control of Flow Bindings
§ Comment syntax
o
Unlike traditional Javascript template in <script>
§ Use a template, without having a template!
o
o
What?!
He’s nuts!
§ Comment based control flow syntax
o
o
o
o
o
if
ifnot
foreach
with
template
All Part of the
Native Template Engine
in Knockout
29. Containerless Examples
Reduces Unneeded
Elements
<!-‐-‐
ko
with:
selectedPerson
-‐-‐>
<span
data-‐bind="text:
name"></span>
<input
data-‐bind="value:
salary"></input>
<!-‐-‐
/ko
-‐-‐>
Moves binding logic
outside of elements
<ul>
<li
class="category">Acoustic
Guitars<li>
<!-‐-‐
ko
foreach:acousticProducts
-‐-‐>
<li>
<span
data-‐bind="text:
shortDesc></span>
</li>
<!-‐-‐
/ko
-‐-‐>
</ul>