2017-02-22 84 views
2

我有幾個組件使用基本相同的表,因此我正在抽取該表的過程中。我解決了大部分動態表人口需求,但尚未找到解決方案。Angular 2將點擊事件傳遞給可重用的通用組件

在我的一個表格實例中,行需要可點擊。在原始表中,我只是在該行中添加了一個單擊事件,並讓它在我的打字稿文件中調用了一個函數。

既然表是任何耗費組件的孩子,我不知道如何動態添加此點擊事件。這裏是一個基本上就是我想實現:

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> 

這裏是一個在父母準備數據的函數。我試圖將點擊事件存儲在一個字符串中並傳遞給它,但是我迄今嘗試過的所有內容都失敗了(與{{}},方括號等進行數據綁定)。

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的新手,所以如果這個問題很簡單,我很抱歉。預先感謝您的幫助。

回答

4

您的通用表可以發出自定義事件到父組件可以訂閱:

@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}`); 
} 
+0

謝謝你這個優雅的解決方案。我有幾個問題。 1.「VisibleDataRow」在哪裏聲明?傳入的對象是一個複雜的對象,其中包含表標題和行數組以及其他一些屬性。我不確定VisibleDataRow代表什麼或者我的初始解釋是否不足。道歉,如果它是誤導。 2.爲了使可點擊的功能可選,我正在考慮只與任何希望使行可點擊的父母傳遞'style =「遊標:指針」'字符串。這是一個hacky的方法嗎?再次感謝! –

+0

1.由於您沒有在您的問題中指定任何類型的行,我只是使用VisibleDataRow來表示它。 「visibleData」是您可能擁有的任何類型對象的數組。 2.您可以添加另一個輸入參數[selectable] =「true」以啓用/禁用表格行選擇。在你的OmaGenericTableComponent的內部,你可以通過使用「@HostBinding('class.selectable')@Input()selectable:boolean;」來綁定必要的基於這個輸入參數的css類。宣言。 –

0

據我所知,Angular2不會綁定到「(click)」事件。它可能看起來很醜陋,但我會將NgIf指令添加到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變量作爲輸入到你的餐桌。

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' 
     }) 
    } 
} 

希望能夠幫助您

相關問題