使用knockoutjs进行数据表数据绑定 [英] Datatable data binding using knockoutjs

查看:117
本文介绍了使用knockoutjs进行数据表数据绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用datatable knockoutjs绑定将数据呈现到表中。
我使用以下链接和代码将数据呈现到表中。 http://datatables.net/dev/knockout/

I want to render data into table using datatable knockoutjs binding. I am using the below link and code for rendering data into table. http://datatables.net/dev/knockout/

我在上面的示例中做的唯一更改是在渲染年龄数据时,我在age col中添加了输入框以供记录,而在表底部添加Updatebutton,以便用户可以更改其年龄并单击更新按钮数据应自动更新,并在下一页中反映在表格中。

The only change I did in above example is while rendering age data I have added input box in age col for ever record and Updatebutton at the bottom of table, so that user can change his age and click of update button data should be updated automatically and in next page it should reflect in table.

我面临的问题是我无法更新本地js人模型,因此无法使用knockoutjs绑定更新的数据。

The issue am facing is that i am unable to update local js "people" model and hence unable to bind updated data using knockoutjs.

ko.observableArray.fn.subscribeArrayChanged = function(addCallback, deleteCallback) {
    var previousValue = undefined;
    this.subscribe(function(_previousValue) {
        previousValue = _previousValue.slice(0);
    }, undefined, 'beforeChange');
    this.subscribe(function(latestValue) {
        var editScript = ko.utils.compareArrays(previousValue, latestValue);
        for (var i = 0, j = editScript.length; i < j; i++) {
            switch (editScript[i].status) {
                case "retained":
                    break;
                case "deleted":
                    if (deleteCallback)
                        deleteCallback(editScript[i].value);
                    break;
                case "added":
                    if (addCallback)
                        addCallback(editScript[i].value);
                    break;
            }
        }
        previousValue = undefined;
    });
};`


 `var data = [
    { id: 0, first: "Allan", last: "Jardine", age: 86 },
    { id: 1, first: "Bob", last: "Smith", age: 54 },
    { id: 2, first: "Jimmy", last: "Jones", age: 32 }
]; `

   `var Person = function(data, dt) {
    this.id    = data.id;
    this.first = ko.observable(data.first);
    this.last  = ko.observable(data.last);
    this.age   = ko.observable(data.age);

    // Subscribe a listener to the observable properties for the table
    // and invalidate the DataTables row when they change so it will redraw
     var that = this;
    $.each( [ 'first', 'last', 'age' ], function (i, prop) {
        that[ prop ].subscribe( function (val) {
            // Find the row in the DataTable and invalidate it, which will
            // cause DataTables to re-read the data
            var rowIdx = dt.column( 0 ).data().indexOf( that.id );
            dt.row( rowIdx ).invalidate();
        } );
    } ); 
};

    $(document).ready(function() {

var people = ko.mapping.fromJS( [] );
    //loadData();

    var dt = $('#example').DataTable( {
        "bPaginate": false,
        "bInfo" : false,
        "bAutoWidth" : false,
        "sDom" : 't',
        "columns": [
            { "data": 'id' },
            { "data": 'first' },
            { "data": 'age',
                "mRender": function (data, type, row ) {    
                                var html = '<div style="display:inline-flex">' + 
                                                '<input type="text" class="headerStyle h5Style" id="ageId" value="'+data()+'"/>' +
                                                '</div>';

                                  return html;
                            } 
             }
        ]


    } );


    // Update the table when the `people` array has items added or removed
    people.subscribeArrayChanged(
        function ( addedItem ) {
            dt.row.add( addedItem ).draw();
        },
        function ( deletedItem ) {
            var rowIdx = dt.column( 0 ).data().indexOf( deletedItem.id );
            dt.row( rowIdx ).remove().draw();
        }
    );

    // Convert the data set into observable objects, and will also add the
    // initial data to the table
    ko.mapping.fromJS(
        data,
        {
            key: function(data) {
            var d = data;

                return ko.utils.unwrapObservable(d.id);        
            },
            create: function(options) {
                return new Person(options.data, dt);
            }    
        },
        people
    );



} );


推荐答案

我做了一个小提琴解决方案

I made a fiddle with a solution

http://jsfiddle.net/Jarga/hg45z9rL/

点击更新会将当前的淘汰模型显示为按钮下方的文本。

Clicking "Update" will display the current knockout model as text below the button.

缺少什么是通过在render函数中添加一个监听器来链接文本框到observable的更改。此外,每一行的文本框都被赋予相同的ID,这也不是一个好主意。 (注意:事件别名只是为了防止与其他处理程序发生冲突)

What was missing was the linking the change of the textbox to the observable by adding a listener in the render function. Also each row's textbox was being given the same id, which is not a good idea either. (Note: the event aliases are just to prevent collision with other handlers)

更改渲染函数以构建有用的ID并添加以下内容应该有效:

Changing the render function to build useful ids and adding the following should work:

$('#' + id).off('change.grid')
$('#' + id).on('change.grid', function() {
    row.age($(this).val());
});

理想情况下,Knockout会为您处理此事,但因为您没有调用applyBindings,也没有创建数据绑定属性对于html元素,所有淘汰赛真正给你的是可观察的模式。

Ideally Knockout would handle this for you but since you are not calling applyBindings nor creating the data-bind attributes for the html elements all that knockout really gives you here is the observable pattern.

编辑:其他解决方案

通过在模板中添加 data-bind 属性并将敲除模型绑定到模板,您可以让Knockout处理渲染。表元素。

Looking into it a little bit more you can let Knockout handle the rendering by adding the data-bindattribute into the template and binding your knockout model to the table element.

var html = '<div style="display:inline-flex">' + 
    '<input type="text" class="headerStyle h5Style" id="' + id + '" data-bind="value: $data[' + cell.row + '].age"/>'

ko.applyBindings(people, document.getElementById("example"));

这将在构建 Person 对象也是。

这是第二个解决方案的另一个小提琴:

Here is another fiddle with the 2nd solution:

http://jsfiddle.net/Jarga/a1gedjaa/

我觉得这样可以简化解决方案。但是,我不知道它的执行效率,也没有用分页测试它,所以可能需要做额外的工作。使用此方法,mRender函数永远不会被重新执行,并且输入的DOM操作完全使用knockout完成。

I feel like this simplifies the solution. However, i do not know how efficient it performs nor have i tested it with paging so additional work may need to be done. With this method the mRender function is never re-executed and the DOM manipulation for the input is done entirely with knockout.

这篇关于使用knockoutjs进行数据表数据绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆