angular表格封装

50 阅读1分钟

表格模版

<!-- table.template.html -->
<!-- table.template.html -->
<div class="table-responsive">
    <table class="table table-striped table-bordered table-hover">
        <thead>
            <tr>
                <th ng-repeat="col in columns" ng-style="col.width && {'width': col.width + 'px'}">
                    {{col.text}}
                </th>
                <th ng-if="buttons.length > 0">操作</th>
            </tr>
        </thead>
        <tbody>
            <tr ng-repeat="item in data track by $index">
                <td ng-repeat="col in columns" ng-click="handleRowClick(item, col, $event)"
                    ng-style="col.width && {'width': col.width + 'px'}">
                    <span ng-if="!col.isLink">
                        {{col.formatter ? col.formatter(item[col.key]) : item[col.key]}}
                    </span>
                    <a ng-if="col.isLink" ng-href="{{col.getLink ? col.getLink(item) : (col.linkTemplate)}}"
                        target="_blank">
                        {{col.formatter ? col.formatter(item[col.key]) : item[col.key]}}
                    </a>
                </td>
                <!-- 操作列 - 独立按钮 -->
                <td ng-if="buttons.length > 0">
                    <div class="table-actions">
                        <button ng-repeat="btn in buttons" ng-if="!btn.show || btn.show(item)"
                            class="btn btn-xs {{btn.btnClass}}" ng-click="executeAction(btn.action, item)"
                            title="{{btn.text}}">
                            <i class="fa {{btn.icon}}" ng-if="btn.icon"></i>
                            <span ng-if="!btn.iconOnly">{{btn.text}}</span>
                        </button>
                    </div>
                </td>
            </tr>
            <tr ng-if="!data || data.length === 0">
                <td colspan="{{columns.length + (buttons.length > 0 ? 1 : 0)}}" class="text-center">暂无数据</td>
            </tr>
        </tbody>
    </table>
    {{totalItems}} -- {{pageSize}} -- {{pageIndex}}
    <div class="padding20" ng-if="totalItems > pageSize">
        <uib-pagination total-items="totalItems" ng-model="pageIndex" ng-change="pageChanged(pageIndex)" max-size="10"
            boundary-link-numbers="true" rotate="false"></uib-pagination>
    </div>
</div>
<style>
    /* 表格基础样式 */
    .table-responsive {
        overflow-x: auto;
        min-height: 0.01%;
    }

    .table {
        width: 100%;
        margin-bottom: 20px;
    }

    .table th {
        background-color: #f9f9f9;
        white-space: nowrap;
        vertical-align: middle;
    }

    /* 操作按钮样式 */
    .btn-group {
        white-space: nowrap;
    }

    /* 下拉菜单箭头样式 */
    .dropdown-toggle .caret {
        margin-left: 5px;
    }

    /* 空数据提示 */
    .text-center {
        text-align: center;
        color: #999;
        padding: 20px !important;
    }
</style>

表格封装逻辑

app.directive('smartTable', function () {
    return {
        restrict: 'E',
         //'E' - 仅作为元素使用:<smart-table></smart-table>
         //'A' - 仅作为属性使用:<div smart-table></div>
         //'C' - 仅作为类名使用:<div class="smart-table"></div>
         //'M' - 仅作为注释使用:<!-- directive: smart-table -->
        scope: {
            columns: '=',       // 列配置  等价于 columns: '=columns'
            data: '=',         // 表格数据
            onRowClick: '&',   // 行点击回调
            actionButtons: '=',  // 操作按钮配置
            totalItems: '=',    // 总条目数
            pageIndex: '=',   // 当前页码
            pageSize: '=',      // 每页大小
            onPageChange: '&'   // 页码变化回调
        },
        templateUrl: '../common/template/table.template.html', // 使用 templateUrl 而不是 template
        link: function (scope) {
            // 默认按钮配置
            scope.defaultButtons = [
                {
                text: '查看',
                icon: 'fa-eye',
                btnClass: 'btn-info',
                action: 'view',
                show: function(item) { return true; }
                },
                {
                text: '编辑',
                icon: 'fa-edit',
                btnClass: 'btn-primary',
                action: 'edit',
                show: function(item) { return true; }
                },
                {
                text: '删除',
                icon: 'fa-trash',
                btnClass: 'btn-danger',
                action: 'delete',
                show: function(item) { return true; }
                }
            ];
      
            // 合并自定义按钮
            scope.buttons = angular.copy(scope.defaultButtons);
            if (scope.actionButtons && scope.actionButtons.length) {
                scope.buttons = scope.actionButtons;
            }
            
            // 执行操作
            scope.executeAction = function(action, item) {
                scope.$emit('tableAction', { action: action, item: item });
            };

            // 处理行点击
            scope.handleRowClick = function(item, col, event) {
                // 如果点击的是操作按钮,则不跳转
                if (angular.element(event.target).closest('.table-actions').length) {
                    return;
                }
                
                if (scope.onRowClick) {
                    scope.onRowClick({item: item, column: col, $event: event});
                }
            };

            // 分页变化处理
            scope.pageChanged = function(pageIndex = 1, pageSize = 10) {
                if (scope.onPageChange) {
                    scope.onPageChange({
                        pageIndex: pageIndex,
                        pageSize: pageSize
                    });
                }
            };

            // 初始化分页参数
            scope.$watch('pageSize', function(newVal) {
                if (newVal) {
                    scope.pageChanged();
                }
            });
        }
    };
});

页面使用

<smart-table columns="columns" data="data" on-row-click="onRowClick(item,column,$event)" action-buttons="actionButtons"
    total-items="totalItems" page-index="pageIndex" page-size="pageSize"
    on-page-change="onPageChange(pageIndex, pageSize)">
</smart-table>
</smart-table>

基本数据定义

 // 表格数据
    $scope.data = [
        { id: 1, name: '张三', age: 25, status: 'active' },
        { id: 2, name: '李四', age: 30, status: 0 },
        { id: 3, name: '张二三', age: 25, status: 1 },
        { id: 4, name: '李二四', age: 30, status: 0 },
    ];
    // 行点击处理
    $scope.onRowClick = function (item, column, $event) {
        console.log('行被点击:', item, column, $event);
        // if (column.key !== 'name') return
        // // 实际项目中可以使用 $state.go() 跳转
        // const url = 'http://jenkins.chinahuanong.com.cn/view/%E5%95%86%E5%9F%8E/job/mall-deploy/view/%E6%B5%8B%E8%AF%95%E7%8E%AF%E5%A2%83k8s/job/test-k8s-apolloadmin-h5/'
        // $window.open(url, '_blank');
    };
    // 操作按钮配置
    $scope.actionButtons = [
        {
            text: '查看',
            icon: 'fa-eye',
            btnClass: 'btn-info',
            action: 'view',
            show: function (item) { return true; }
        },
        {
            text: '编辑',
            icon: 'fa-edit',
            btnClass: 'btn-primary',
            action: 'edit',
            show: function (item) { return item.status === 'active'; }
        },
        {
            text: '删除',
            icon: 'fa-trash',
            btnClass: 'btn-danger',
            action: 'delete',
            show: function (item) { return true; }
        },
        {
            text: '激活',
            icon: 'fa-check',
            btnClass: 'btn-success',
            action: 'activate',
            show: function (item) { return item.status === 'inactive'; },
            iconOnly: true  // 只显示图标
        }
    ];

    // 监听表格操作事件
    $scope.$on('tableAction', function (event, args) {
        var item = args.item;
        switch (args.action) {
            case 'view':
                console.log('查看:', item);
                // $state.go('view', {id: item.id});
                break;
            case 'edit':
                console.log('编辑:', item);
                // $state.go('edit', {id: item.id});
                break;
            case 'delete':
                if (confirm('确定要删除此项吗?')) {
                    console.log('删除:', item);
                    // 执行删除操作
                }
                break;
            case 'activate':
                console.log('激活:', item);
                // 执行激活操作
                break;
        }
    });

    // 分页变化回调
    $scope.onPageChange = function (page, size) {
        $scope.pageIndex = page;
        $scope.pageSize = size;
    };