Datatables init ajax请求初始值

时间:2015-07-26 18:01:31

标签: javascript ajax knockout.js datatables

我有一个带有数据表和淘汰赛js的应用程序。

KnockoutJS应用程序用于管理其他过滤表的关键字(标签)。

var table = $("#news").DataTable({
    "ajax": {
        url: "{{ base_url('news/load_news/full') }}",
        data: function (d) {
            d.keywords = ko.toJSON(keywords.keywords);
        }
    },
    "processing": true,
    "serverSide": true,
    "bFilter": false,
    "bLengthChange": false
});

通过Ajax请求在页面加载时填充KnockoutJS模型。

我得到的主要问题是第一个Datatables Ajax请求,我有空关键字数组。如果我单击更新表按钮,d.keywords不为空。

我认为这个问题是因为Ajax请求是异步的,所以我如何强制数据表等到填充了KnockoutJS应用程序已填充?

==================

   function refresh_table() {
        table.ajax.reload(null, false); // reload DataTable
        fresh_news_alert.hide();
    }

2 个答案:

答案 0 :(得分:1)

您应该将DataTable初始化放在自定义绑定中。这将确保在您的Knockout视图模型初始化和绑定之前不会调用它。

答案 1 :(得分:0)

此解决方案使用我创建的自定义绑定,该绑定取决于挖空叉。如果您喜欢这个解决方案,请在拉取请求上留下评论,以便将其合并为intp knockout 3.4,谢谢。

example on jsfiddle

knockout pull request

ko.bindingHandlers.DataTablesForEach = {

        init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
             var nodes = Array.prototype.slice.call(element.childNodes, 0);
            ko.utils.arrayForEach(nodes, function (node) {
                if (node && node.nodeType !== 1) {
                    node.parentNode.removeChild(node);
                }
            });
            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().clear();
                            $(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 };
        }
    };