07月04, 2017

bootstrap-table的小坑

这几天在做新的需求,因为之前老的代码都是bootstrap-table,所以我也直接拿过来使用。

在使用的过程中,算是踩了一些坑,简单记录一下。

我的需求是客户端分页,这个听上去蛮简单的。在实际中遇到了一些坎:

  • url的方式

bootstrap-table通过url接口,去ajax请求数据,但它要求response是一个数组,它会将这个数组作为data来做渲染。

  • 直接data

先请求数据,数据请求好,处理得到数组,然后通过$table.bootstrapTable来初始化table。

这样看似没有问题,其实是有一个隐患,比如说toolbar的刷新等按钮,没什么意义了。

且做自定义搜索时,重新$table.bootstrapTable,是不会生效的。只能先destroy,再重新初始化。

其实我也尝试过如下的代码:

$table.bootstrapTable("refresh", {data:  data});

但发现不支持,细想如果为了客户端,真这样设计是否值得。毕竟还有服务端的考虑,到处充斥if else,确实不是太好。

  • ajax配置

服务端的写法如下:

var ajaxRequest = function (params) {
    var data = params.data;
    $.getJSON("/vault/secret/secret/queryForPage.json",
        {
            "offset": data.offset,
            "limit": data.limit,
            "search": data.search,
            "appId" : data.appId,
            "order": data.order,
            "sort": data.sort,
        },
        function (resp) {
            if (resp.head.status === 'Y') {
                var rows = resp.body.rows;
                var pageableJO = resp.body.pageableJO;
                params.success({
                    total: pageableJO.total,
                    rows: rows
                });
            }
        });
};

/** 初始化表格 */
$table.bootstrapTable({
    ajax: ajaxRequest,
    toolbar: "#toolbar",
    toolbarAlign: 'left',        // 工具栏对齐方式
    //detailFormatter : detailFormatter,
    //method: 'get',                      //请求方式(*)
    striped: true,                      //是否显示行间隔色
    sidePagination: "server",           //分页方式:client客户端分页,server服务端分页(*)
    classes: 'table table-bordered', // Class样式
    silent: true, // 必须设置刷新事件
    formatNoMatches: function () { //没有匹配的结果
        return '无符合条件的记录';
    },

    pagination: true,                   //是否显示分页(*)
    sortable: true,                     //是否启用排序
    sortOrder: "asc",                   //排序方式
    ...
})

所以我下意识地把客户端的ajax也这样写:

var ajaxRequest = function (params) {
    var data = params.data;
    $.getJSON("/vault/secret/secret/queryForPage.json",
        function (resp) {
            if (resp.head.status === 'Y') {
                var rows = resp.body;   // 这里得到数组
                params.success({
                     rows: rows
                });
            }
        });
};

结果数据出不来,出于偷懒的目的,在github上提了一个issue

等了好久,没啥回应。(不得不说,像antd的issue还是回复的挺快的)

那就自己翻源码,查看实现吧。最后让我找到一些代码:

// ....

request = $.extend({}, calculateObjectValue(null, this.options.ajaxOptions), {
    type: this.options.method,
    url:  url || this.options.url,
    data: this.options.contentType === 'application/json' && this.options.method === 'post' ?
        JSON.stringify(data) : data,
    cache: this.options.cache,
    contentType: this.options.contentType,
    dataType: this.options.dataType,
    success: function (res) {
        res = calculateObjectValue(that.options, that.options.responseHandler, [res], res);

        that.load(res);
        that.trigger('load-success', res);
        if (!silent) that.$tableLoading.hide();
    },
    error: function (res) {
        that.trigger('load-error', res.status, res);
        if (!silent) that.$tableLoading.hide();
    }
});

// ...

BootstrapTable.prototype.load = function (data) {
    var fixedScroll = false;

    // #431: support pagination
    if (this.options.sidePagination === 'server') {
        this.options.totalRows = data[this.options.totalField];
        fixedScroll = data.fixedScroll;
        data = data[this.options.dataField];
    } else if (!$.isArray(data)) { // support fixedScroll
        fixedScroll = data.fixedScroll;
        data = data.data;
    }

    this.initData(data);
    this.initSearch();
    this.initPagination();
    this.initBody(fixedScroll);
};

看到上面这两段,大概想到了,应该返回一个数组,而不需要一个对象,所以代码如下:

var ajaxRequest = function (params) {
    var data = params.data;
    $.getJSON("/vault/secret/secret/queryForPage.json",
        function (resp) {
            if (resp.head.status === 'Y') {
                var rows = resp.body;   // 这里得到数组
                params.success(rows);
            }
        });
};

话说上面的params设计也是不错的,它可以得到option里面的queryParams参数。

var ajaxRequest = function (params) {
    var data = params.data;
    $.getJSON("/vault/sysmanage/group/queryAuthGroups.json?search=" + data.search,
        function (resp) {
            if (resp.head.status === 'Y') {
                params.success(resp.body);
            }
        });
};

/** ajaxRequest */
$table.bootstrapTable({
    ajax: ajaxRequest,
    toolbar: "#toolbar",
    toolbarAlign: 'left',       // 工具栏对齐方式
    striped: true,                      //是否显示行间隔色
    sidePagination: "client",           //分页方式:client客户端分页,server服务端分页(*)
    pagination: true,                   //是否显示分页(*)
    sortable: true,                     //是否启用排序
    sortOrder: "asc",                   //排序方式
    pageNumber: 1,                       //初始化加载第一页,默认第一页
    pageSize: 5,                       //每页的记录行数(*)
    pageList: [5, 10, 15, 20],        //可供选择的每页的行数(*)
    search: false,                       //是否显示表格搜索,此搜索是客户端搜索不会进服务端
    searchOnEnterKey: true,
    queryParams: function (params) {
        return {
            "search": $('#groupName').val()
        }
    },
    uniqueId: "id",
    idField: "id",
    ...
})

然后当refresh的时候,它会重新去拼接URL($('#groupName').val()可能会发生变化)。

本文链接:www.my-fe.pub/post/bootstap-table-note.html

-- EOF --

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。