Dar*_*ane 1 javascript jquery knockout.js
我本周刚刚开始学习淘汰赛,除了这一个问题外,一切都进展顺利.
我有一个项目列表,我按多种方式排序,但我想要排序的方式之一需要有一个不同于标准列表的显示.举个例子,假设我有这个代码
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());
Run Code Online (Sandbox Code Playgroud)
和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>
Run Code Online (Sandbox Code Playgroud)
因此,我可以通过任何字段对这些进行排序,我可以按名称对它们进行排序,它将显示类似的内容
3 Apple $1 Fruit
1 Beef $3 Meat
1 Ice Cream $6 Dairy
5 Milk $4 Dairy
2 Pear $2 Fruit
Run Code Online (Sandbox Code Playgroud)
这是我到目前为止的一个小提琴http://jsfiddle.net/Darksbane/X7KvB/
除了类别排序外,此显示适用于所有排序.我想要的是当我按类别对它们进行排序时,就像这样显示它
Fruit
3 Apple $1 Fruit
2 Pear $2 Fruit
Meat
1 Beef $3 Meat
Dairy
1 Ice Cream $6 Dairy
5 Milk $4 Dairy
Run Code Online (Sandbox Code Playgroud)
有没有人知道我怎么能够以这种不同的方式显示它?
您的视图不应包含超出渲染所需的逻辑.因此,您的foreach绑定
data-bind="foreach:allItems().sort(ko.utils.compareItems)"应成为computed可观察的.
您应该将<option>数据移动到模型中并利用options数据绑定.
要解决实际问题,您将利用template绑定和containerless if绑定.
该template绑定将允许你改变基础上,选择排序类型视图的外观/感受.因此有2个模板可用,default-template它们处理常规显示,category-template特别是基于类别的渲染.
<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>
Run Code Online (Sandbox Code Playgroud)
html用法:<div data-bind='template: { name: currentTemplate, data: $data}'></div>where currentTemplate是一个计算的observable,它根据排序类型返回模板id.
您必须以某种方式为类别指定优先级.我通过宣布这样做了var categoryPriority = ["Fruit", "Meat", "Dairy"].
看看我的小提琴.我没有解决所fixedWidth使用的问题default-template所以你需要处理CSS样式以便按照你想要的方式排列.
编辑:有没有办法动态地将项目添加到列表并让它自动显示在排序列表中?
推送一个新项目:如果你想让knockout"通知"其他元素,那么在执行推送之前你不想read使用observableArray allItems().相反,你将进入observableArray,使用allItems.push它反过来将导致knockout触发computed observables(依赖于这个observable)来评估,subscriptions执行,DOM元素更新......等等.
计算依赖关系:为了使计算机"依赖"另一个可观察对象,它必须read位于提供的求值函数内部.因为,sortedItems只读取sortType是重新评估的唯一"触发器".因此,无论何时进行更改,都要更改allItems.sortto to allItems().sortcause .sortedItemsallItems
请参阅依赖关系跟踪的工作原理
| 归档时间: |
|
| 查看次数: |
1208 次 |
| 最近记录: |