Angular 2将click事件传递给可重用的通用组件

时间:2017-02-22 03:29:57

标签: javascript html angular typescript event-handling

我有几个组件使用基本相同的表,因此我正在抽象出该表。我已经解决了我的大部分动态表填充需求,但尚未找到以下解决方案。

在我的一个表实例中,行需要是可点击的。在原始表中,我只是在行中添加了一个click事件,并在我的typescript文件中调用了一个函数。

既然表是任何消费组件的子节点,我不确定如何动态添加此单击事件。这基本上是我想要实现的目标:

HTML:
<tr class="someClass" <!-- want click event here -->>
  <td *ngFor="let column of row;"><div [innerHtml]="column"></div></td>
</tr>

这是表的打字稿文件,其中所有数据都来自visibleData对象:

export class GenericTableComponent implements OnInit {
    @Input() visibleData;
    constructor() { }

    ngOnInit() {
    }
}

我在我的父HTML中实现通用表

Parent HTML:
<oma-generic-table [visibleData]="visibleData"></oma-generic-table>

这是父母准备数据的功能。我试图将click事件存储在一个字符串中并传递它,但到目前为止我尝试过的所有内容都失败了(数据绑定{{}},方括号等...)。

transformData(visibleData) {
    const ret: any = {};
    ret.headings = visibleData.headings;
    ret.action = '(click)="rowClicked([row.id])"';
    ret.checkbox = this.checkBox;                                                   //add if the table needs checkboxes
    ret.content = [];
    for (let i = 0; i < visibleData.content.length; i++) {
        ret.content.push(_.values(_.omit(visibleData.content[i], 'id')));
    }
    return ret;
}

但是,即使硬编码到子代中,click事件也无法识别父级中的函数,我收到以下错误:

EXCEPTION: Error in ./GenericTableComponent class GenericTableComponent - inline template:35:4 caused by: self.parentView.context.rowClicked is not a function
ORIGINAL EXCEPTION: self.parentView.context.rowClicked is not a function

我不确定这是否简单。我是Angular 2的新手,所以如果这个问题过于简单,我会道歉。在此先感谢您的帮助。

3 个答案:

答案 0 :(得分:5)

您的通用表可以发出父组件可以订阅的自定义事件:

@Component({
    selector: 'oma-generic-table',
    template: `
        <table>
            <tr *ngFor="let row of visibleData" class="someClass" (click)="selectRow(row)">
              <td *ngFor="let column of row;"><div [innerHtml]="column"></div></td>
            </tr>
        </table>
    `
})
export class OmaGenericTable {

    @Input() visibleData: VisibleDataRow[];

    @Output() select = new EventEmitter<VisibleDataRow>();

    selectRow(row: VisibleDataRow) {
        this.select.emit(row);
    }
}

然后在您的父组件中:

// in template
<oma-generic-table 
        [visibleData]="visibleData" 
        (select)="tableRowSelected($event)"
></oma-generic-table>

// in component
tableRowSelected(r: VisibleDataRow) {
    console.log(`Selected row ${r}`);
}

答案 1 :(得分:0)

据我所知,Angular2不会绑定到&#34;(点击)&#34;这样的事件。它可能看起来很丑,但我会将NgIf指令添加到click事件应该对其执行的行的表中,并将逻辑反向应用于不应受click事件影响的另一行。例如:

<tr *ngIf="!isClickable" class="someClass"> <tr *ngIf="isClickable" class="someClass" (click)="rowClicked()> <td *ngFor="let column of row;"><div [innerHtml]="column"></div></td> </tr>

然后,您可以从实例化表组件的任何位置将isClickable变量作为输入传递到表中,并对其进行操作。

答案 2 :(得分:0)

在HTML中使用

<tr *ngIf="!isClickable" class="someClass">
 <tr *ngIf="isClickable" class="someClass" #click>
  <td *ngFor="let column of row;"><div [innerHtml]="column"></div></td>
 </tr>

这是打字稿

export class GenericTableComponent implements OnInit {
    @Input() visibleData;
    @ViewChild('click') protected _click:ElementRef;

    constructor(enderer: Renderer) {
        renderer.listen(this._click.nativeElement, 'click', (event) => {
            // Do something with 'event'
        })
    }
}

希望能帮到你