淘汰赛 - 可分组阵列 [英] Knockout - groupable array
问题描述
我的问题是如何从可观察数组(过滤器)中提取一些数据?
我在这里找到类似的问题:
类似的问题
但我不知道如何实现它。
这里是测试:
jsfiddle
HTML代码:
< h2>您的座位预留(< span data- bind =text:seats()。length>< / span>)< / h2>
< h4>
按用餐类型分配:
< table>
< thead>
< tr data-bind =foreach:availableMeals>
< th>< span data-bind =text:mealName>< / span>< / th>
< / tr>
< / thead>
< tbody>
< tr data-bind =foreach:availableMeals>
< td> ???< / td>
< / tr>
< / tbody>
< / table>
< / h4>
< table>
< thead>< tr>
Passenger name< th> Meal< th>< th> Surcharge< th>< th>< th>
< / tr>< / thead>
< tbody data-bind =foreach:seats>
< tr>
< td>< input data-bind =value:name/>< / td>
< td>< select data-bind =options:$ root.availableMeals,value:meal,optionsText:'mealName'>< / select>< / td>
< td data-bind =text:formattedPrice>< / td>
< td>< a href =#data-bind =click:$ root.removeSeat>删除< / a>< / td>
< / tr>
< / tbody>
< / table>
< button data-bind =click:addSeat,enable:seats()。length< 7>保留另一个座位< / button>
< h3 data-bind =visible:totalSurcharge()> 0>
总附加费:$< span data-bind =text:totalSurcharge()。toFixed(2)>< / span>
< / h3>
JS code:
//从链接延伸到来自stackoverflow的类似问题:
ko.observableArray.fn.distinct = function(prop){
var target = this;
target.index = {};
target.index [prop] = ko.observable({});
//通过已设置好的组,保释出来。
if(target.index&& target.index [prop])return target;
ko.computed(function(){
//重建索引
var propIndex = {};
ko.utils.arrayForEach(target(),function item){
var key = ko.utils.unwrapObservable(item [prop]);
if(key){
propIndex [key] = propIndex [key] || [];
propIndex [key] .push(item);
}
});
target.index [prop](propIndex);
});
回报目标;
};
//在座位预订网格中表示一行的类
函数SeatReservation(name,initialMeal){
var self = this;
self.name = name;
self.meal = ko.observable(initialMeal);
self.formattedPrice = ko.computed(function(){
var price = self.meal()。price;
return price?$+ price.toFixed 2):无;
});
}
//此屏幕的整体viewmodel,以及初始状态
函数ReservationsViewModel(){
var self = this;
//不可编辑的目录数据 - 将来自服务器
self.availableMeals = [
{mealName:标准(三明治),价格:0},
{膳食名称:Premium(龙虾),价格:34.95},
{膳食名称:Ultimate(whole zebra),价格:290}
];
//可编辑数据
self.seats = ko.observableArray([
新SeatReservation(Steve,self.availableMeals [0]),
新SeatReservation (Bert,self.availableMeals [0]),
新SeatReservation(Steve,self.availableMeals [1]),
新SeatReservation(John,self.availableMeals [1]) ,
新SeatReservation(Frank,self.availableMeals [1]),
新SeatReservation(Evan,self.availableMeals [2])
]);
//计算数据
self.totalSurcharge = ko.computed(function(){
var total = 0;
for(var i = 0; i< ; self.seats()。length; i ++)
total + = self.seats()[i] .meal()。price;
return total;
});
//操作
self.addSeat = function(){
self.seats.push(new SeatReservation(,self.availableMeals [0]));
self.removeSeat = function(seat){self.seats.remove(seat)}
}
ko.applyBindings(new ReservationsViewModel());
我从KO教程开始工作:pb是我想按膳食类型显示客户分布?
开箱即用并不提供任何可分组数组。 b $ b
然而Knockout的带有一些实用功能 a> like: 可以帮助您以手动构建自己的自定义分组。 下面是示例 Demo JSFiddle 。 如果你想拥有一些更复杂的数组处理函数,你应该检出 Underscore.js 库有一些非常好的功能,比如 From the tutorial, I am trying to understand this promising framework.
My question is how to extract some data from an observable array (filter)?
I found a similar quesion here :
similar question But I don't know how to implement it.
here is the test :
jsfiddle HTML code: JS code : I worked from the KO tutorial : the pb is I want to display a distribution of customers by meal types? Out of the box Knockout doesn't provide any "groupable array". However Knockout comes with some utility functions like: which can help you to build your own custom grouping by hand. So here is a how sample Demo JSFiddle. If you want to have some more sophisticated array handling functions you should checkout the Underscore.js library which has some really nice functions like 这篇关于淘汰赛 - 可分组阵列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
ko.utils.arrayForEach
ko.utils.arrayFilter
mealDistribution
实现的示例:
self.mealDistribution = ko.computed(function(){
var seatCount = self.seats()。length;
var result = [];
ko.utils.arrayForEach(self.availableMeals,function(meal){
var mealCount = ko.utils.arrayFilter(self.seats(),function(item){
return item.meal()== meal})。length;
result.push(mealCount / seatCount);
});
返回结果;
});
groupBy
, countBy
<h2>Your seat reservations (<span data-bind="text: seats().length"></span>)</h2>
<h4>
Distribution by meal type:
<table>
<thead>
<tr data-bind="foreach: availableMeals">
<th><span data-bind="text: mealName"></span></th>
</tr>
</thead>
<tbody>
<tr data-bind="foreach: availableMeals">
<td>???</td>
</tr>
</tbody>
</table>
</h4>
<table>
<thead><tr>
<th>Passenger name</th><th>Meal</th><th>Surcharge</th><th></th>
</tr></thead>
<tbody data-bind="foreach: seats">
<tr>
<td><input data-bind="value: name" /></td>
<td><select data-bind="options: $root.availableMeals, value: meal, optionsText: 'mealName'"></select></td>
<td data-bind="text: formattedPrice"></td>
<td><a href="#" data-bind="click: $root.removeSeat">Remove</a></td>
</tr>
</tbody>
</table>
<button data-bind="click: addSeat, enable: seats().length < 7">Reserve another seat</button>
<h3 data-bind="visible: totalSurcharge() > 0">
Total surcharge: $<span data-bind="text: totalSurcharge().toFixed(2)"></span>
</h3>
// extend from the link to the similar question from stackoverflow:
ko.observableArray.fn.distinct = function(prop) {
var target = this;
target.index = {};
target.index[prop] = ko.observable({});
//Group by already set up, bail out.
if (target.index && target.index[prop]) return target;
ko.computed(function() {
//rebuild index
var propIndex = {};
ko.utils.arrayForEach(target(), function(item) {
var key = ko.utils.unwrapObservable(item[prop]);
if (key) {
propIndex[key] = propIndex[key] || [];
propIndex[key].push(item);
}
});
target.index[prop](propIndex);
});
return target;
};
// Class to represent a row in the seat reservations grid
function SeatReservation(name, initialMeal) {
var self = this;
self.name = name;
self.meal = ko.observable(initialMeal);
self.formattedPrice = ko.computed(function() {
var price = self.meal().price;
return price ? "$" + price.toFixed(2) : "None";
});
}
// Overall viewmodel for this screen, along with initial state
function ReservationsViewModel() {
var self = this;
// Non-editable catalog data - would come from the server
self.availableMeals = [
{ mealName: "Standard (sandwich)", price: 0 },
{ mealName: "Premium (lobster)", price: 34.95 },
{ mealName: "Ultimate (whole zebra)", price: 290 }
];
// Editable data
self.seats = ko.observableArray([
new SeatReservation("Steve", self.availableMeals[0]),
new SeatReservation("Bert", self.availableMeals[0]),
new SeatReservation("Steve", self.availableMeals[1]),
new SeatReservation("John", self.availableMeals[1]),
new SeatReservation("Frank", self.availableMeals[1]),
new SeatReservation("Evan", self.availableMeals[2])
]);
// Computed data
self.totalSurcharge = ko.computed(function() {
var total = 0;
for (var i = 0; i < self.seats().length; i++)
total += self.seats()[i].meal().price;
return total;
});
// Operations
self.addSeat = function() {
self.seats.push(new SeatReservation("", self.availableMeals[0]));
}
self.removeSeat = function(seat) { self.seats.remove(seat) }
}
ko.applyBindings(new ReservationsViewModel());
ko.utils.arrayForEach
ko.utils.arrayFilter
mealDistribution
implementation could look like:self.mealDistribution = ko.computed(function () {
var seatCount = self.seats().length;
var result = [];
ko.utils.arrayForEach(self.availableMeals, function (meal) {
var mealCount = ko.utils.arrayFilter(self.seats(), function (item) {
return item.meal() == meal}).length;
result.push(mealCount / seatCount);
});
return result;
});
groupBy
, countBy