我有一个MVC网站,我使用Kendo UI和knockout.js来显示页面。一种情况是通过$.getJSON
从服务器获取数据库信息,然后在KendoUI网格上显示此信息。
<div data-bind="kendoGrid:{sortable:true, data:users, rowTemplate:'userRowTemplate'}>
<table>
<thead>
<tr>
<th>Username</th>
<th>First Name</th>
<th>Last Name</th>
</tr>
</thead> </table>
</div>
<script type="text/html">
<tr>
<td data-bind="text: Username"></td>
<td data-bind="text: FirstName"></td>
<td data-bind="text: LastName"></td>
<tr>
</script>
和javascript:
<script type="text/javascript">
var ViewModel = function () {
var self=this;
self.users=ko.mapping.fromJS([]);
$getJSON("/UserManagementController/GetUsers",function(data){
ko.mapping.fromJS(data,{},self.users);
});
};
$(document).ready(function(){
var newViewModel=new ViewModel();
ko.applyBindings(newViewModel);
});
</script>
我希望这些数据可以在特定列上进行排序(这里指定的那些是例如),但我无法成功实现这一点。我尝试过this knockout-kendo plugin issue post的解决方案,该解决方案适用于简单对象,但不适用于可观察对象。所以我的问题是:如何将数据从数据库通过MVC控制器映射到淘汰赛中的观察者并在Kendo网格中显示它们,但仍能够对它们进行排序?
谢谢, 亚历克斯巴拉克
答案 0 :(得分:2)
您可以通过创建JS视图模型来表示从服务器返回的数据,并将数据映射到视图模型中。然后,您可以通过订阅匹配的observable属性来设置简单对象,以实现排序。
这是一个例子: http://jsfiddle.net/R4Jys/1/
HTML:
<div data-bind="kendoGrid: gridOptions(myList)"></div>
<script id="rowTmpl" type="text/html">
<tr>
<td>
<span data-bind="text: firstName" />
</td>
<td>
<span data-bind="text: lastName" />
</td>
<td>
<span data-bind="text: userName" />
</td>
</tr>
</script>
JavaScript的:
var gridItem = function () {
var self = this;
self.firstName = ko.observable();
self.firstNameSort;
self.firstName.subscribe(function (value) {
self.firstNameSort = value;
});
self.lastName = ko.observable();
self.lastNameSort;
self.lastName.subscribe(function (value) {
self.lastNameSort = value;
});
self.userName = ko.observable();
self.userNameSort;
self.userName.subscribe(function (value) {
self.userNameSort = value;
});
self.other = ko.observable('test');
return self;
};
var vm = function() {
var self = this;
self.myList = ko.observableArray();
self.test = ko.observable();
self.gridOptions = function (data) {
return {
data: data,
rowTemplate: 'rowTmpl',
useKOTemplates: true,
scrollable: true,
sortable: true,
columns: [
{
field: "firstNameSort",
title: "First Name",
width: 130
},
{
field: "lastNameSort",
title: "Last Name",
filterable: true
},
{
field: "userNameSort",
title: "Username"
}
]
}
};
var data = [{'firstName':'Steve', 'lastName':'Jones', 'userName': 'steve.jones'},
{'firstName':'Janet', 'lastName':'Smith', 'userName': 'janet.smith'},
{'firstName':'April', 'lastName':'Baker', 'userName': 'april.baker'},
{'firstName':'Dave', 'lastName':'Lee', 'userName': 'dave.lee'},
{'firstName':'Jack', 'lastName':'Bennet', 'userName': 'jack.bennet'},
{'firstName':'Chris', 'lastName':'Carter', 'userName': 'chris.carter'}];
self.myList(ko.utils.arrayMap(data, function(item) {
var g = new gridItem();
ko.mapping.fromJS(item, {}, g);
return g;
}));
};
var pageVm = new vm();
ko.applyBindings(pageVm);
答案 1 :(得分:1)
作为替代方案,您可以在6844行和第6844行修改kendo.web.js(版本2013.3.1119)。 6844.
替换
compare: function(field) {
var selector = this.selector(field);
return function (a, b) {
a = selector(a);
b = selector(b);
使用
compare: function(field) {
var selector = this.selector(field);
return function (a, b) {
a = ko.utils.unwrapObservable(selector(a));
b = ko.utils.unwrapObservable(selector(b));
通过使用knockout实用程序“ko.utils.unwrapObservable”,当kendo比较列的值时,您可以获取observable的值
答案 2 :(得分:0)
DEFINE CUSTOM COMPARE FUNCTION将提供解决方案,您可以在字段定义中覆盖比较功能。
所以你可以这样做:
$("#grid").kendoGrid({
dataSource: dataSource,
sortable: true,
columns: [{
field: "item",
sortable: {
compare: function(a, b) {
var valueA = a["item"];
var valueB = b["item"];
if (typeof valueA === "function") valueA = valueA();
if (typeof valueB === "function") valueB = valueB();
if (this.isNumeric(valueA) && this.isNumeric(valueB))
{
valueA = parseFloat(valueA);
valueB = parseFloat(valueB);
}
if (valueA && valueA.getTime && valueB && valueB.getTime)
{
valueA = valueA.getTime();
valueB = valueB.getTime();
}
if (valueA === valueB)
{
return a.__position - b.__position;
}
if (valueA == null)
{
return -1;
}
if (valueB == null)
{
return 1;
}
if (valueA.localeCompare)
{
return valueA.localeCompare(valueB);
}
return valueA > valueB ? 1 : -1;
}
}
}]
});
private isNumeric(input)
{
return (input - 0) == input && ('' + input).trim().length > 0;
}
比较方法是从kendo脚本中窃取的,但更改是属性是typeof函数(ko.observable是什么),它会解包该值。另外,我添加了对数字的支持。