javascript - jQuery DataTables 和 Knockout 未正确绑定(bind)

标签 javascript jquery knockout.js datatables

我收到一个返回“Team”的 Ajax 调用。一支球队由 TeamName、LeagueName 和包含 Name、Position 和 TeamName 的 FootballPlayers 列表组成。 Ajax 调用正确返回团队 JSON,我将直接在团队上对属性进行 Knockout 绑定(bind)。但是,我想将 jQuery DataTable 绑定(bind)到玩家列表,但没有成功。我可以知道正在进行 DataTables 调用,因为我可以看到一些 DataTables 控件,例如“上一页 1 下一页”,但表中没有数据。如果有帮助的话,我可以将我所拥有的内容部署到公开可见的网站上。谢谢!

  • jQuery:版本 2.1.1
  • knockout :版本 3.2.0
  • 数据表:版本 1.10.4

HTML 表格

<table id="playerList">
    <thead>
        <tr>
            <th>Player Name <span class="glyphicon glyphicon-sort-by-alphabet" aria-hidden="true"></span></th>
            <th>Position <span class="glyphicon glyphicon-sort-by-alphabet" aria-hidden="true"></span></th>
            <th>Team <span class="glyphicon glyphicon-sort-by-alphabet" aria-hidden="true"></span></th>
        </tr>
    </thead>
    <!--<tbody data-bind='foreach: PlayerList'>-->
    <tbody>
        <tr>
            <td data-bind="text: $data.PlayerList.Name"></td>
            <td data-bind="text: $data.PlayerList.SelectedPosition"></td>
            <td data-bind="text: $data.PlayerList.TeamName"></td>
        </tr>
    </tbody>
</table>

Controller JavaScript

$('.retrieveTeam').click(function () {
        _getData('RetrieveTeam', JSON.stringify({ TeamKey: $(this).data("teamkey") }));

    });

function _getData(url, postdata) {
    var request = $.ajax({
        url: url,
        type: 'POST',
        data: postdata,
        datatype: "json",
        contentType: "application/json"
    });
    request.done(_requestDone);
    request.fail(_failedRequest)
}

function _requestDone(result)
{
    _bindTeam(result);
    my.Views.TeamView.showTeamInfo();
}

function _bindTeam(data) {
    if (!viewModel) {
        viewModel = ko.mapping.fromJS(data, {}, this);
        ko.applyBindings(viewModel);
        my.Views.TeamView.applyDataTable('#playerList');
    } else {
        ko.mapping.fromJS(data, viewModel);
    }        
}

查看 JavaScript

var applyDataTable = function applyDataTable(element) {
    $(element).DataTable(
        {
            responsive: true,
            bFilter: false,
            bInfo: false,
            bLengthChange: false
        });
}

最佳答案

这是我的做法...这个 fiddle 使用自定义的 DataTablesForEach 绑定(bind),还包括一个 knockout 的分支...我已经在 github 上使用 knockout 存储库创建了一个拉取请求。如果这个解决方案对您有帮助,请在我的拉取请求上留下评论,以便将其合并到 knockout 3.4 中。谢谢!

jsfiddle

pull request #1856 knockout/knockout repository on github

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 };
        }
    };

关于javascript - jQuery DataTables 和 Knockout 未正确绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26952903/

相关文章:

javascript - '+new Date'中的加号有什么作用

jquery - 如何将固定元素包含在相对元素中?

javascript - 使用 TypeScript 自定义 knockout 验证规则

javascript - 没有 onbeforeunload 和 unload 事件的浏览器返回事件

javascript - 如何更改knockout js网格中的列名称

jquery - 由于生成器 ko 的 jQuery 错误,Gulp 失败了默认任务

javascript - 从 Google map 中的建议 route 提取距离

javascript - Firefox Addon 中的 JQuery 导致多个警告

javascript - Meteor js 的 GridView

javascript - jquery工具覆盖,如何在切换覆盖时保留蒙版