javascript - KnockoutJS showing a sorted list by item category -
i started learning knockout week , has gone except 1 issue.
i have list of items sort multiple ways 1 of ways want sort needs have different display standard list. example lets have code
var betterlistmodel = function () { var self = this; food = [ { "name":"apple", "quantity":"3", "category":"fruit", "cost":"$1", },{ "name":"ice cream", "quantity":"1", "category":"dairy", "cost":"$6", },{ "name":"pear", "quantity":"2", "category":"fruit", "cost":"$2", },{ "name":"beef", "quantity":"1", "category":"meat", "cost":"$3", },{ "name":"milk", "quantity":"5", "category":"dairy", "cost":"$4", }]; self.allitems = ko.observablearray(food); // initial items // initial sort self.sortme = ko.observable("name"); ko.utils.compareitems = function (l, r) { if (self.sortme() =="cost"){ return l.cost > r.cost ? 1 : -1 } else if (self.sortme() =="category"){ return l.category > r.category ? 1 : -1 } else if (self.sortme() =="quantity"){ return l.quantity > r.quantity ? 1 : -1 }else { return l.name > r.name ? 1 : -1 } }; }; ko.applybindings(new betterlistmodel()); and html
<p>your values:</p> <ul class="deckcontents" data-bind="foreach:allitems().sort(ko.utils.compareitems)"> <li><div style="width:100%"><div class="left" style="width:30px" data-bind="text:quantity"></div><div class="left fixedwidth" data-bind="text:name"></div> <div class="left fixedwidth" data-bind="text:cost"></div> <div class="left fixedwidth" data-bind="text:category"></div><div style="clear:both"></div></div></li> </ul> <select data-bind="value:sortme"> <option selected="selected" value="name">name</option> <option value="cost">cost</option> <option value="category">category</option> <option value="quantity">quantity</option> </select> </div> so can sort these fine field might sort them name , display this
3 apple $1 fruit 1 beef $3 meat 1 ice cream $6 dairy 5 milk $4 dairy 2 pear $2 fruit here fiddle of have far http://jsfiddle.net/darksbane/x7kvb/
this display fine sorts except category sort. want when sort them category display this
fruit 3 apple $1 fruit 2 pear $2 fruit meat 1 beef $3 meat dairy 1 ice cream $6 dairy 5 milk $4 dairy does have idea how might able display differently 1 sort?
your view shouldn't contain logic beyond necessary render it. thus,
foreachbindingdata-bind="foreach:allitems().sort(ko.utils.compareitems)"should becomecomputedobservable.you should move
<option>data model , take advantage ofoptionsdata-bind.
to address actual question, you'll take advantage of template binding , containerless if binding.
the template binding allow change look/feel of view based on selected sort type. 2 templates available, default-template handles regular display , category-template category based rendering.
<script type="text/html" id="category-template"> <ul class="deckcontents" data-bind="foreach:sorteditems"> <li> <!-- ko if: $root.outputcategory($index()) --> <div data-bind="text:category"></div> <!-- /ko --> <span class="indented" data-bind="text:name"></span> <span class="indented" data-bind="text:cost"></span> <span class="indented" data-bind="text:category"></span> </li> </ul> the html usage: <div data-bind='template: { name: currenttemplate, data: $data}'></div> currenttemplate computed observable returns template id based on sort type.
in way or must assign priority categories. have done declaring var categorypriority = ["fruit", "meat", "dairy"].
have @ my fiddle. i didn't address fixedwidth used default-template you'll need handle css styling line way want.
edit: is there way dynamically add item list , have show in sorted list automatically?
pushing new item: when want knockout "notify" other elements don't want
readobservablearray usingallitems()before performing push. instead, you'll push observablearray usingallitems.pushin-turn cause knockout triggercomputed observables(that depend on observable) evaluate,subscriptionsexecute, dom elements update ... etc.computed dependencies: in order computed "depend" on observable has
readinside of provided evaluator function. since,sorteditemsreadssorttype"trigger" re-evaluation. thus, changingallitems.sortallitems().sortcausessorteditemsevaluate whenever changes madeallitems.
Comments
Post a Comment