Sorting and filtering not working in knockout kend

2019-06-09 18:36发布

问题:

I am using Knockout-Kendo.js and i had no problems binding data to the grid and seeing changes when observable array changes.

However

  1. Sorting does not work and there are no js errors.

Please note that tasks is a ko.observableArray()

        <div data-bind="kendoGrid: {
                data: tasks,
                columns: [
                    { field: 'TaskId', title: 'Task Id' },
                    { field: 'Description', title: 'Description' },
                    { field: 'RaisedBy', title: 'Requested User' },
                    { field: 'Status', title: 'Status' },
                    { field: '', title: '' }
                ],
                rowTemplate: 'Template',
                useKOTemplates: true,
                editable: false,
                filterable: true,
                sortable: true,
                scrollable: false,
                pageable: {pageSize: 5 }
                }">
        </div>


<script id="Template" type="text/html">
    <tr>
        <td><div data-bind="text: TaskId"></div></td>
        <td><div data-bind="text: Description"></div></td>            
        <td><div data-bind="text: RaisedBy"></div></td>            
        <td><div data-bind="text: Status"></div></td>
        <td><button data-bind="click: $root.viewDetails">View</button></td>
    </tr>
</script>
  1. Filtering does not work either and this is what i see in the console.

Uncaught TypeError: undefined is not a function (anonymous function) VM3445:3 o.filter kendo.web.min.js:11 o.process kendo.web.min.js:11 ct.extend.query kendo.web.min.js:11 ct.extend._query kendo.web.min.js:11 ct.extend.filter kendo.web.min.js:11 g.extend.filter kendo.web.min.js:19 g.extend._submit kendo.web.min.js:19 b.extend.proxy.b.isFunction.i jquery-1.9.1.js:7223 b.event.dispatch jquery-1.9.1.js:9593

JSfiddle - http://jsfiddle.net/fc0ukq9o/

I found that the JSFiddle works without any problem, with the observable array.

However in my case the observable array was getting populated by the below code, which automatically creates observable properties for each of the properties on data. After this i can see that the sort and filter stops working.

$.each(data.source, function (index, data) {
                    self.tasks.push(ko.mapping.fromJS({
                        TaskId: data.TaskId,
                        Description: data.Description,
                        RaisedBy: data.RaisedBy,
                        Status: data.Status
                    }));
                });

回答1:

Wow, that was tough one, but I guess I solved it, see demo.

The problem with your approach is that Kendo knows nothing about KO observables, and knockout-kendo just passes data as plain JS object to Kendo. So if you want to be able to change data in your table, you should use some workaround. My approach was to use valueHasMutated method to tell knockout that task in tasks array was updated.

Here is how view model looks like:

function ViewModel() {
    var self = this;
    self.tasks = ko.observableArray();
    self.viewDetails = function(data) {
        alert(data.TaskId);
    };
    self.changeData = function() {
        self.tasks()[0].TaskId = 3;
        self.tasks.valueHasMutated(); // this will tell knockout that tasks were changed
    }
};

tasks is an observable array of Task objects:

function Task(id, description, raisedBy, status) {
    this.TaskId = id;
    this.Description = description;
    this.RaisedBy = raisedBy;
    this.Status = status;
};

I also added initialisation method that has dummy data:

ViewModel.prototype.init = function() {
    var self = this;
    var data = {
        source: [
            new Task(1, "Task 1", "User 1", "New"),
            new Task(2, "Task 2", "User 2", "Closed"),
            new Task(3, "Task 3", "User 3", "In progress"),
            new Task(4, "Task 4", "User 4", "New"),
            new Task(5, "Task 5", "User 5", "In progress")
        ]
    };
    self.tasks(data.source);
}

So now sorting works as it should, and in case you change some of the tasks (press "Change data" button in jsfiddle), table is refreshed.