JQuery DataTables + KnockOut(+ BootStrap)错误?

时间:2012-11-29 09:12:09

标签: jquery twitter-bootstrap knockout.js datatables

我已将KnockOut observableArray绑定到jQuery DataTable。当我向这个数组动态添加项时,新项正确地在表中呈现,但是数据表本身的某些选项没有被刷新。寻呼机不会更新。 “无数据可用”消息也不会消失。

HTML:

<table class="table table-striped" id="tblSample">
    <thead>
        <tr>
            <th>Name</th>
        </tr>
    </thead>

    <tbody data-bind="foreach: List">
        <tr>
            <td data-bind="text: Name"></td>
        </tr>
    </tbody>
</table>
<button class="btn" type="button" data-bind="click: AddSample">Test</button>

淘汰赛模特:

var Sample = function(name) {
    this.Name = ko.observable(name);
};

var ViewModel = function() {
    var self = this;
    self.List = ko.observableArray();
    self.AddSample = function() {
        self.List.push(new Sample('New'));
    };
};

ko.applyBindings(new ViewModel());​

DOM ready:

$(document).ready(function() {

    $('#tblSample').dataTable({
        "sDom": "<'row'<'span6'l><'span6'f>r>t<'row'<'span6'i><'span6'p>>",
        "sPaginationType": "bootstrap",
        "bFilter": true,
        "bLengthChange": false,
        "bSort": true,
        "iDisplayLength": 15,
        "oLanguage": {
            "sLengthMenu": "_MENU_ records per pagina"
        }
    });
});

使用JSFiddle:http://jsfiddle.net/PhpDk/1

我做错了什么,或者这是一个错误?

谢谢, 尼科

(编辑:修复jsfiddle中的CDN链接)

2 个答案:

答案 0 :(得分:2)

有一个名为KoGrid的原生淘汰赛网格 https://github.com/ericmbarnard/KoGrid

但是,如果你真的想使用Datatables,那么就可以为它进行淘汰赛绑定(仅适用于1.9.0)

我已经在Github上分叉了这个绑定并对它进行了扩展(你可以从ViewModel访问Datables对象来刷新,过滤,排序等),你可以在这里找到它

https://github.com/AndersMalmgren/Knockout.Extensions

答案 1 :(得分:1)

这是做到这一点的方法......我已经做了一个jsfiddle显示:

为了使其工作,我必须为原始的knockout foreach绑定定义添加两个回调方法。我目前正试图让这些事件进入淘汰赛的最新版本。我需要添加一个beforeRenderAll和afterRenderAll回调来销毁数据表并在敲除foreach绑定后添加html重新初始化数据表。这就像一个魅力JSFiddle显示它有一个完全可编辑的jquery数据表,通过淘汰绑定到ViewModel。

ko.bindingHandlers.DataTablesForEach = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
    return ko.bindingHandlers.foreach.init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {

        var value = ko.unwrap(valueAccessor()),
        key = "DataTablesForEach_Initialized";

        var newValue = function () {
            return {
                data: value.data || value,
                beforeRenderAll: function(el, index, data){
                    if (ko.utils.domData.get(element, key)) {                                   
                        $(element).closest('table').DataTable().destroy();
                    }
                },
                afterRenderAll: function (el, index, data) {
                    $(element).closest('table').DataTable(value.options);
                }

            };
        };

        ko.bindingHandlers.foreach.update(element, newValue, allBindingsAccessor, viewModel, bindingContext);

        //if we have not previously marked this as initialized and there is currently items in the array, then cache on the element that it has been initialized
        if (!ko.utils.domData.get(element, key) && (value.data || value.length)) {
            ko.utils.domData.set(element, key, true);
        }

        return { controlsDescendantBindings: true };
}

};

jsfiddle w/ bootstrap