Table.js 6.38 KB
import template from "./Table.html";
import style from "antd/lib/table/style/index.css";

class Table {
    useModules = ["esNgAntd"];

    props = {
        columns: Array,
        dSource: Array,
        rowSelection: Object,
        rowKey: String,
        loading: Number,
        onChange: Function,
        size: String,
    };

    state = {
        size: this.props.size || "default",
        dataSource: [],
        selectedrecordKeys: [],
        selectedrecords: [],
        isSelectAll: false,
        rowKey: this.props.rowKey || "id",
        sortDirections: ["ascend", "descend"],
        sorter: {
            field: null,
            order: null,
        },
    };

    template = template;

    watch = {
        dSource: (newValue) => {
            if (newValue !== undefined) {
                let dataSource = [];
                newValue.forEach((record, index) => {
                    let row = {};
                    if (this.props.rowSelection) {
                        row.checked = false;
                        row.disabled = false;
                    }
                    if (
                        this.props.rowSelection &&
                        typeof this.props.rowSelection.getCheckboxProps ===
                            "function"
                    ) {
                        let extraAttr =
                            this.props.rowSelection.getCheckboxProps(record);
                        row = Object.assign(row, extraAttr);
                    }
                    this.props.columns.forEach((column) => {
                        row[column.key] = column.render
                            ? this.getRender(column, record, index)
                            : record[column.key];
                    });
                    // 主键
                    if (this.props.rowKey !== undefined) {
                        row[this.state.rowKey] = record[this.state.rowKey];
                    } else {
                        row[this.state.rowKey] = index + 1;
                    }
                    dataSource[index] = row;
                });
                this.state.dataSource = dataSource;
            }
        },
        "rowSelection.selectedRowKeys": (newVal) => {
            if (Array.isArray(newVal)) {
                this.state.selectedrecordKeys = newVal;
                this.state.dataSource.map(function (row, key) {
                    row.checked = newVal.includes(key);
                });
            }
        },
    };

    constructor() {
        esNgAntd.createStyle("ant-table", style);
        // 初始化默认排序
        this.props.columns.forEach((column) => {
            if (column.sortOrder) {
                this.state.sorter.field = column.key;
                this.state.sorter.order = column.sortOrder;
            }
        });
    }

    getParameterName(fn) {
        if (typeof fn !== "object" && typeof fn !== "function") return;
        const COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm;
        const DEFAULT_PARAMS = /=[^,)]+/gm;
        const FAT_ARROWS = /=>.*$/gm;
        let code = fn.prototype
            ? fn.prototype.constructor.toString()
            : fn.toString();
        code = code
            .replace(COMMENTS, "")
            .replace(FAT_ARROWS, "")
            .replace(DEFAULT_PARAMS, "");
        let result = code
            .slice(code.indexOf("(") + 1, code.indexOf(")"))
            .match(/([^\s,]+)/g);
        return result === null ? [] : result;
    }

    getRender(column, record, index) {
        let params = this.getParameterName(column.render);
        let render = column.render(record[column.key], record, index);
        if ($attrs.dSource) {
            if (params[0]) {
                render = render.replace(
                    new RegExp(`(\{\{.*?)${params[0]}(.*?\}\})`, "g"),
                    `$1${$attrs.dSource}[${index}].${column.key}$2`
                );
            }
            if (params[1]) {
                render = render.replace(
                    new RegExp(`(\{\{.*?)${params[1]}(.*?\}\})`, "g"),
                    `$1${$attrs.dSource}[${index}]$2`
                );
            }
            if (params[2]) {
                render = render.replace(
                    new RegExp(`(\{\{.*?)${params[2]}(.*?\}\})`, "g"),
                    `$1${index}$2`
                );
            }
        }
        return render;
    }

    handleSelectAll(event) {
        this.state.isSelectAll = event.target.checked;
        this.state.selectedrecordKeys = [];
        this.state.selectedrecords = [];
        this.state.dataSource.map((record, key) => {
            if (record.disabled === false) {
                record.checked = event.target.checked;
            }
            if (record.checked) {
                this.state.selectedrecordKeys.push(key);
                this.state.selectedrecords.push(this.props.dSource[key]);
            }
            return record;
        });
        if (typeof this.props.rowSelection.onChange === "function") {
            this.props.rowSelection.onChange(
                this.state.selectedrecordKeys,
                this.state.selectedrecords
            );
        }
    }

    handleSelect(event, index) {
        let pos = this.state.selectedrecordKeys.findIndex(
            (value) => value === index
        );
        if (event.target.checked && pos === -1) {
            this.state.selectedrecordKeys.push(index);
            this.state.selectedrecords.push(this.props.dSource[index]);
        } else {
            this.state.selectedrecordKeys.splice(pos, 1);
            this.state.selectedrecords.splice(pos, 1);
        }
        if (this.state.selectedrecordKeys.length === 0) {
            this.state.isSelectAll = false;
        }
        if (typeof this.props.rowSelection.onChange === "function") {
            this.props.rowSelection.onChange(
                this.state.selectedrecordKeys,
                this.state.selectedrecords
            );
        }
    }

    handleSorter(key) {
        this.state.sorter.field = key;
        if (this.state.sorter.order === null) {
            this.state.sorter.order = "ascend";
        } else if (this.state.sorter.order === "ascend") {
            this.state.sorter.order = "descend";
        } else if (this.state.sorter.order === "descend") {
            this.state.sorter.order = null;
            this.state.sorter.field = null;
        }
        this.props.onChange({
            sorter: this.state.sorter,
        });
    }
}