为了账号安全,请及时绑定邮箱和手机立即绑定

加强 ColumnBuilder

标签:
JavaScript

设计思路

上次我们说到,由于 Layui 表格列的 templet 属性可以是一段 HTML,所以可以在这上面大做文章,今天就来加强我们的 ColumnBuilder,希望它能灵活的配置单元格呈现。

这样设想:

  • 可以为 templet 赋予一段 HTML,但是直接给 HTML 不太好操作,所以引入 jQuery,允许通过配置 jQuery 对象的方式来赋予 templet HTML
  • 对常见的一些处理进行封装,比如添加 css class,直接设置样式,format 值等

因为我们的 Builder 里需要:

  • setElementCreator,用于创建 jQuery 对象
  • 定义一组设置 jQuery 对象的函数,用于对 jQuery 对象($el)进行加工(设置样式等)
    • 如果有 setElementCreator 用它来产生这个 $el
    • 如果没有 setElementCreator,默认产生一个 $span(即 <span>
    • 定义一个 function list 用来保存设置的处理函数,有点像事件处理(观察者模式)

代码

HTML 中引入 jQuery

<script src="libs//jquery/jquery.min.js"></script>

加强 ColumnBuilder

配置处理函数

export class ColumnBuilder {
    constructor(field, title) {
        this.options = { field, title };

        // 处理函数列表,默认为空数组
        // 之所以不默认为 undefined 或 null,是为了避免使用时需要先判断
        this.fns = [];
    }

    /**
     * 默认创建 jQuery 对象的方法,默认创建一个 span
     * 默认呈现字段值,否则如果没有处理方法来处理 text 会什么也不显示
     */
    createSpanElement(row) {
        const { options } = this;
        const $span = $("<span>");
        const v = row[options.field];
        $span.text(v);
        return $span;
    }

    /**
     * 设置 Element Creator,非必须
     */
    setElementCreator(elCreator) {
        this.createElement = elCreator;
        return this;
    }

    /**
     * 添加处理函数
     * @param {(row, $el) => void} fn 一个函数,根据 row 加工 $el
     */
    addFn(fn) {
        this.fns.push(fn);
        return this;
    }

    /**
     * 用于设置格式处理函数的的快捷方法
     * @param {(row) => string} format 根据 row 生成要呈现的字符串内容
     */
    setFormat(format) {
        return this.addFn((row, $tr) => $tr.text(format(row)));
    }


    /**
     * 用于设置 CSS class 处理函数的快捷方法
     * @param {(row) => string} cls 根据 row 返回需要现予的 css class 名称
     */
    setClass(cls) {
        return this.addFn((row, $tr) => $tr.addClass(cls(row)));
    }

    /**
     * 用于设置样式处理函数的快捷方法
     * @param {(row) => {}} styles 根据 row 返回一个可用于 $.fn.css() 的样式对象
     */
    setStyles(styles) {
        return this.addFn((row, $tr) => $tr.css(styles(row)));
    }
    
    ... 其他原来的配置方法
}

改进 build() 方法

export class ColumnBuilder {
    ...
    
    build() {
        const options = {
            ...this.options
        };
        const { fns } = this;

        if (fns.length || this.createElement) {
            const createElement = this.createElement
                || (row => this.createSpanElement(row));
            console.log(createElement)
            options.templet = row => {
                const $el = createElement(row);
                fns.forEach(fn => fn(row, $el));
                
                // 昨天说过可以通过包一层元素再取 innerHTML 的方法来获取 HTML
                return $("<div>").append($el).html();
            }
        }

        return options;
    }
    
    ...
}

使用改进后的 ColumnBuilder

给标题添加链接

直接用设置一个创建 <a> 的 element creator 就好

column("title", "标题")
    .set("minWidth", "200")
    .setElementCreator(row => {
        return $("<a href='#'>").text(row.title || "");
    })
    .build(),

根据难度显示不同的颜色

column("grade", "难度")
    .set("align", "center")
    .setStyles(row => {
        // 用查表的办法避免 switch 或者 if-else
        // 如果查找表能封装在外面就更好,可以避免每次重建
        return {
            "入门": { color: "#00aa00" },
            "高级": { color: "#ff6666" },
        }[row.grade] || {};
    })
    .build(),

实效

图片描述

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消