knockout mvvm-m5-slides
DESCRIPTION
Playlists : https://www.youtube.com/watch?v=CtWmndjPCgU&index=2&list=PLLQgkMVoGtcvDCRBcW4vOlHPq8eEndm1ZTRANSCRIPT
Templates, Control of Flow, and Containerless Bindings
John Papa @john_papa
http://johnpapa.net
Outline
§ Named Templates § Control of Flow § Binding Contexts § Inline Templates § Dynamically Choosing a Template § Template Binding Helpers § Containerless Bindings
Templates
§ Re-use code § Encapsulate responsibility for a specific rendering § Knockout supports many popular templating engines
o jQuery Templates o Underscore
§ Knockout has native templates
Named Templates in <script> tags
<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>
§ Encapsulate a template for re-use
DEMO Named Templates
Outline
§ Named Templates § Control of Flow § Binding Contexts § Inline Templates § Dynamically Choosing a Template § Template Binding Helpers § Containerless Bindings
Control of Flow
• If truthy condition if
• If falsy condition ifnot
• Execute for each item in a list foreach
• Shortcut to execute for the object with
Control of Flow with a Template
<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>
§ Pass the context for the template with “foreach”
Conditional Control of Flow
<p data-‐bind="if: lines().length > 0"> <span>Total value:</span> <span data-‐bind="text: grandTotal()"></span>
</p>
Any “truthy” expression
Change Context “with“Control of Flow
<div data-‐bind="with: model"> <div data-‐bind="text: brand"></div> <div data-‐bind="text: name"></div>
</div>
<div> <div data-‐bind="text: model().brand"></div> <div data-‐bind="text: model().name"></div>
</div>
Change the context with “with”
Parent Binding Contexts
<button data-‐bind="click: $parent.addItem">Add</button>
§ Sometimes in templates you want to change data binding scope (Data Context) o $data o $parent o $parents o $root
DEMO Control of Flow and Binding Contexts
Outline
§ Named Templates § Control of Flow § Binding Contexts § Inline Templates § Dynamically Choosing a Template § Template Binding Helpers § Containerless Bindings
<tbody data-‐bind="template: {name: 'productsTmpl', foreach: lines}">
</tbody> <script type="text/html" id="productsTmpl"> <tr> <td style="width: 100px;">
<input data-‐bind="value: qty" /> </td> ... </tr>
</script>
<tbody data-‐bind="foreach: lines"> <tr> <td style="width: 100px;">
<input data-‐bind="value: qty"/> </td> ... </tr>
</tbody>
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
Template is created
anonymously and implicitly
Knockout’s Native Template Engine
§ Templates inside DOM elements o <script> o Other DOM elements like <div>
§ Anonymous / Inline templates o Templates without a name o Shortcuts to Anonymous template binding
o if o ifnot o with o foreach
All Part of the Native Template Engine
in Knockout
No external templating dependency
<div data-‐bind="template: {if: isSelected}"> <span data-‐bind="text:name"></span> </div> <div data-‐bind="if: isSelected"> <span data-‐bind="text:name"></span> </div>
if and ifnot
“if” shortcut
<div data-‐bind="template: {ifnot: isSelected}"> <span data-‐bind="text:name"></span> </div>
<div data-‐bind="ifnot: isSelected"> <span data-‐bind="text:name"></span> </div>
“ifnot” shortcut
<div data-‐bind="template: {foreach: products}"> <span data-‐bind="text:name"></span> </div> <div data-‐bind="foreach: products"> <span data-‐bind="text:name"></span> </div>
foreach and with
“foreach“ shortcut
<div data-‐bind="template: {if: selectedProduct, data: selectedProduct}"> <span data-‐bind="text:name"></span> </div> <div data-‐bind="with: selectedProduct"> <span data-‐bind="text:name"></span> </div>
“with” shortcut
DEMO Native Template Engine: Inline Templates
Outline
§ Named Templates § Control of Flow § Binding Contexts § Inline Templates § Dynamically Choosing a Template § Template Binding Helpers § Containerless Bindings
<div data-‐bind="template: {name: templateChoice}"> <script type="text/html" id="tmplSummary"> ... </script> <script type="text/html" id="tmplDetails"> ...
</script>
Dynamically Change Templates
§ Swap between multiple templates § Bind the name of the template
my.vm.templateChoice = function () { return showDetails() ? "tmplDetails" : "tmplSummary"; };
<div data-‐bind="ifnot: showDetails()"> ... </div> <div data-‐bind="if: showDetails()"> ... </div>
Control of Flow to Toggle Templates
§ if and ifnot bindings
my.vm.showDetails = ko.observable(false);
DEMO Dynamically Choosing a Template
Outline
§ Named Templates § Control of Flow § Binding Contexts § Inline Templates § Dynamically Choosing a Template § Template Binding Helpers § Containerless Bindings
Template Bindings • Id of an element that contains the template
name
• Renders the template in foreach mode • (once for each item) foreach
• Object to supply as data for the template. • If omitted, uses foreach context or the current context data
• Callback invoked after DOM elements are rendered afterRender
• Callback invoked after DOM elements are added afterAdd
• Callback invoked before DOM elements are removed beforeRemove
<ul data-‐bind="template: { name: 'friendsTemplate', foreach: model().Friends, beforeRemove: function(elem) { $(elem).slideUp() }, afterAdd: function(elem) { $(elem).hide().slideDown() } }"> </ul>
<ul data-‐bind="template: { name: 'friendsTemplate', foreach: model().Friends, beforeRemove: showAni, afterAdd: hideAni}"> </ul>
Template Binding Helpers
Callback to a method in the viewmodel
DEMO Template Binding Helpers
Outline
§ Named Templates § Control of Flow § Binding Contexts § Inline Templates § Dynamically Choosing a Template § Template Binding Helpers § Containerless Bindings
Containerless Control of Flow Bindings
§ Comment syntax o Unlike traditional Javascript template in <script>
§ Use a template, without having a template! o What?! o He’s nuts!
§ Comment based control flow syntax o if o ifnot o foreach o with o template
All Part of the Native Template Engine
in Knockout
<ul> <li class="category">Acoustic Guitars<li> <!-‐-‐ ko foreach:acousticProducts -‐-‐> <li> <span data-‐bind="text: shortDesc></span> </li> <!-‐-‐ /ko -‐-‐> </ul>
Containerless Examples
<!-‐-‐ ko with: selectedPerson -‐-‐> <span data-‐bind="text: name"></span> <input data-‐bind="value: salary"></input> <!-‐-‐ /ko -‐-‐>
Reduces Unneeded Elements
Moves binding logic outside of elements
DEMO Containerless/Comment Bindings
Summary
§ Native Template Engine o Named Templates and Anonymous / Inline Templates
§ Control of Flow o if, ifnot, with, foreach, template
§ Binding Contexts o $data, $parent, $parents, $root
§ Dynamically Choosing a Template o template: {name: myObservableProperty}
§ Template Binding Helpers o name, data, foreach, afterRender, afterAdd, beforeRemove
§ Containerless/Comment Bindings o <!– ko foreach: products -->
§ External Templates o https://github.com/ifandelse/Knockout.js-External-Template-Engine
For more in-depth online developer training visit
on-demand content from authors you trust