【问题标题】:Kendo UI and knockout.js rowTemplate sortingKendo UI 和 knockout.js rowTemplate 排序
【发布时间】:2013-07-16 01:10:09
【问题描述】:

我有一个 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 控制器将数据库中的数据映射到淘汰赛中的 observables 并在 Kendo 网格中显示它们,但仍然能够对它们进行排序?

谢谢, 亚历克斯·巴拉克

【问题讨论】:

    标签: asp.net-mvc knockout.js kendo-ui


    【解决方案1】:

    您可以通过创建一个 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);
    

    【讨论】:

      【解决方案2】:

      作为替代方案,您可以在第 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 比较列的值时使用

      【讨论】:

        【解决方案3】:

        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 是什么),它解包了值。另外,我添加了对数字的支持。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-11-23
          • 1970-01-01
          • 2018-10-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-08-27
          • 1970-01-01
          相关资源
          最近更新 更多