【问题标题】:jQuery DataTables and Knockout not binding properlyjQuery DataTables 和 Knockout 没有正确绑定
【发布时间】:2014-11-16 01:49:40
【问题描述】:

我收到一个返回“团队”的 Ajax 调用。一个团队由一个 TeamName、LeagueName 和一个包含 Name、Position 和 TeamName 的 FootballPlayers 列表组成。 Ajax 调用正确地返回了 Team JSON,我将直接将 Knockout 绑定到 Team 上的属性。但是,我想将一个 jQuery DataTable 绑定到播放器列表,但没有成功。我可以看出正在进行 DataTables 调用,因为我可以看到一些 DataTables 控件,例如“Previous 1 Next”,但表中没有数据。如果有帮助的话,我可以将我所拥有的东西部署到一个公开可见的网站上。谢谢!

  • jQuery:版本 2.1.1
  • 淘汰赛:版本 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>

控制器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
        });
}

【问题讨论】:

    标签: javascript jquery knockout.js datatables


    【解决方案1】:

    我是这样做的……这个小提琴使用自定义 DataTablesForEach 绑定,还包括一个淘汰赛的分支……我在 github 上创建了一个带有淘汰赛存储库的拉取请求。如果此解决方案对您有帮助,请对我的拉取请求发表评论,以将其合并到淘汰赛 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 };
            }
        };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-19
      • 2016-01-10
      • 2012-11-17
      • 1970-01-01
      • 2016-02-13
      • 2019-07-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多