0

我有一个 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>

我希望这些数据可以在特定列上排序(例如,这里指定的列是为了),但我无法成功实现这一点。我已经尝试了来自这个 knockout-kendo plugin issue post的解决方案,它适用于简单的对象,但不适用于可观察对象。所以我的问题是:如何通过 MVC 控制器将数据库中的数据映射到淘汰赛中的 observables 并在 Kendo 网格中显示它们,但仍然能够对它们进行排序?

谢谢,亚历克斯巴拉克

4

3 回答 3

2

您可以通过创建一个 JS 视图模型来表示从服务器返回的数据,并将数据映射到视图模型中来做到这一点。然后,您可以通过订阅匹配的可观察属性来设置简单的对象来实现排序。

这是一个例子: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);
于 2013-11-12T17:55:28.393 回答
1

作为替代方案,您可以在第 6844 和 6844 行修改 kendo.web.js(版本 2013.3.1119)。

代替

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));

通过使用敲除实用程序“ko.utils.unwrapObservable”,您可以获得可观察的值,以便在 kendo 比较列的值时使用

于 2014-01-08T20:03:41.707 回答
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;
    }

compare 方法是从 kendo 脚本中窃取的,但更改是属性是 typeof 函数的地方(ko.observable 是什么),它解包了值。另外,我添加了对数字的支持。

于 2015-12-17T11:31:55.993 回答