2017-02-22 4 views
2

У меня есть несколько компонентов, которые используют в основном одну и ту же таблицу, поэтому я занимаюсь абстрагированием этой таблицы. Я решил большинство моих потребностей в динамических таблицах, но пока не нашел решения для следующего.Угловой 2, проходящий событие click для многократно используемого общего компонента

В одном из экземпляров моей таблицы строки должны быть интерактивными. В исходной таблице я просто добавил событие щелчка в строке и вызвал функцию в моем файле машинописных файлов.

Теперь, когда таблица является дочерним элементом любого компонента-потребителя, я не уверен, как динамически добавлять это событие click. Вот в основном то, что я пытаюсь достичь:

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; 
} 

Однако, даже если жестко закодирована в ребенок, событие щелчка не распознает функцию родителя, и я получаю следующее сообщение об ошибке:

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. Чтобы сделать функцию clickable необязательной, я рассматривал просто передачу строки «style =» cursor: pointer «» с любыми родителями, которые хотят сделать строки доступными для кликов. Это хакерский подход? Еще раз спасибо! –

+0

1. Поскольку вы не указали какие-либо строки в своем вопросе, я просто использовал VisibleDataRow для его представления. «visibleData» - это массив любых объектов, которые у вас могут быть. 2. Вы можете добавить еще один входной параметр [selectable] = "true", чтобы включить/отключить выбор строки таблицы. Внутри вашего OmaGenericTableComponent вы можете связать необходимый класс css на основе этого входного параметра, используя «@HostBinding (« class.selectable ») @Input() selectable: boolean;» декларация. –

0

Angular2, насколько я знаю, не будет привязан к событию «(щелчок)» таким образом. Это может показаться уродливым, но я бы добавил директиву 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 переменным в качестве входа в таблицу из любой точки мира, что вы экземпляр компоненты таблицы и действуют на него.

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

Надеется, что поможет вам

Смежные вопросы