You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ng2-smart-table中条件显示Start/End按钮并绑定点击事件?

解决ng2-smart-table动态显示Start/End按钮的问题

我来帮你搞定这个动态按钮的问题!你当前的代码里有个关键问题:ng2-smart-table的valuePrepareFunction返回的HTML字符串不会被Angular编译,所以你写的*ngIf和(click)绑定都不会生效。下面给你两种可行的解决办法:

方案一:纯HTML字符串+手动绑定点击事件(快速实现)

这种方式不需要创建新组件,直接通过HTML字符串生成按钮,再手动监听点击事件处理逻辑:

1. 修改tableSettings配置

tableSettings = {
  actions: false,
  columns: {
    code: { title: 'Code' },
    first_name: { title: 'First Name' },
    last_name: { title: 'Last Name' },
    email_id: { title: 'Email' },
    start_time: { 
      title: 'Start Time', 
      type: 'date', 
      valuePrepareFunction: (date) => this.renderDateTime(date) 
    },
    end_time: { 
      title: 'End Time', 
      type: 'date', 
      valuePrepareFunction: (date) => this.renderDateTime(date) 
    },
    start: {
      title: 'Start/End',
      type: 'html',
      valuePrepareFunction: (cell, row) => {
        // 替换成你的判断条件,比如根据start_time是否为空判断显示哪个按钮
        const showStartBtn = !row.start_time; 
        const btnText = showStartBtn ? 'Start' : 'End';
        // 给按钮添加自定义属性,存储行ID和操作类型,方便后续处理
        return `<button class="action-btn" data-row-id="${row.id}" data-action="${btnText.toLowerCase()}">${btnText}</button>`;
      }
    }
  }
};

2. 在组件中监听点击事件

给表格添加模板引用变量#smartTable,然后在组件初始化后监听按钮点击:

import { AfterViewInit, ElementRef, ViewChild } from '@angular/core';

export class YourComponent implements AfterViewInit {
  @ViewChild('smartTable') smartTable!: ElementRef;

  ngAfterViewInit(): void {
    // 监听表格内的按钮点击
    this.smartTable.nativeElement.addEventListener('click', (event: Event) => {
      const target = event.target as HTMLButtonElement;
      if (target.classList.contains('action-btn')) {
        const rowId = target.getAttribute('data-row-id');
        const action = target.getAttribute('data-action');
        
        if (action === 'start') {
          this.startTest(rowId);
        } else if (action === 'end') {
          this.endTest(rowId);
        }
      }
    });
  }

  startTest(rowId: string): void {
    // 根据rowId处理Start操作逻辑
    console.log('执行Start操作,行ID:', rowId);
  }

  endTest(rowId: string): void {
    // 根据rowId处理End操作逻辑
    console.log('执行End操作,行ID:', rowId);
  }
}

方案二:自定义组件(推荐,符合Angular最佳实践)

这种方式通过创建独立的按钮组件,利用ng2-smart-table的自定义列特性,更易维护和扩展:

1. 创建自定义按钮组件

// action-button.component.ts
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { Row } from 'ng2-smart-table';

@Component({
  selector: 'app-action-button',
  template: `
    <button class="action-btn" (click)="handleClick()">
      {{ showStartBtn ? 'Start' : 'End' }}
    </button>
  `
})
export class ActionButtonComponent {
  @Input() row!: Row;
  @Output() onStart = new EventEmitter<any>();
  @Output() onEnd = new EventEmitter<any>();

  // 根据行数据判断显示哪个按钮
  get showStartBtn(): boolean {
    return !this.row.data.start_time; // 替换成你的实际判断条件
  }

  handleClick(): void {
    if (this.showStartBtn) {
      this.onStart.emit(this.row.data);
    } else {
      this.onEnd.emit(this.row.data);
    }
  }
}

2. 在主组件中配置tableSettings

import { ActionButtonComponent } from './action-button.component';

tableSettings = {
  actions: false,
  columns: {
    // 其他列保持不变...
    start: {
      title: 'Start/End',
      type: 'custom',
      renderComponent: ActionButtonComponent,
      // 初始化组件时绑定事件
      onComponentInitFunction: (instance: ActionButtonComponent) => {
        instance.onStart.subscribe(rowData => {
          this.startTest(rowData);
        });
        instance.onEnd.subscribe(rowData => {
          this.endTest(rowData);
        });
      }
    }
  }
};

3. 主组件中的操作方法

startTest(rowData: any): void {
  // 直接拿到行数据,处理Start逻辑
  console.log('开始测试:', rowData);
}

endTest(rowData: any): void {
  // 处理End逻辑
  console.log('结束测试:', rowData);
}

注意:记得在你的模块中声明ActionButtonComponent,如果是独立组件要在imports中添加该组件。

内容的提问来源于stack exchange,提问作者Naveen Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:48:52