我自己的Angular 2 Table组件 - 双向数据绑定

时间:2017-01-20 15:06:12

标签: javascript html angular

我看到对角度2的数据表的支持非常差。 DataTables对我不起作用(已知未解决的问题)因此我认为我会为自己写一些简单的东西。顺便说一句,我会学到一些有用的东西。我想以这种方式构建我的表:

<my-table> 
    <my-table-row *ngFor="let row of rows">
         <my-table-col>{{row.col1}}</my-table-col>
         <my-table-col>{{row.col2}}</my-table-col>
    </my-table-row>
</my-table>

所以我创建了一个带有简单滤镜输入的组件。现在,我想过滤我的桌子。 Angular应该以某种方式将my-table-col(s)中的数据分配给某个变量(也许2路数据绑定会有用吗?),然后我会使用keyup事件触发的一些函数进行过滤,数据应该自动更新但我做不知道该怎么做。

import { Component, Input, OnInit } from '@angular/core';
import { BrowserModule }  from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';

@Component({
    selector: 'my-table',
    template: `
    <div style="width: 100%">
        <div style="float: left; height: 50px; width: 100%">
            Search: <input type="text" [(ngModel)]="filterValue" style="height: 30px; border: 1px solid silver"/> {{filterValue}}
        </div>
        <div style="float: left; width: 100%">
            <table>
                <ng-content></ng-content>
            </table>
        </div>
    </div>
    `
})
export class MyTableComponent { 
    filterValue: string;
}  

@Component({
    selector: 'my-table-row',
    template: `
        <tr><ng-content></ng-content></tr>
    `
})
export class MyTableRowComponent { 
}   

@Component({
    selector: 'my-table-col',
    template: `
        <td><ng-content></ng-content></td>
    `
})
export class MyTableColComponent { 
}   

此致

2 个答案:

答案 0 :(得分:5)

更新Angular 5

ngOutletContext已重命名为ngTemplateOutletContext

另见https://github.com/angular/angular/blob/master/CHANGELOG.md#500-beta5-2017-08-29

<强>原始

对于您的示例,为行和列创建新组件似乎是不必要的。

使用像

这样的简单过滤管道
@Pipe({ name: 'filter' })
export class FilterPipe implements PipeTransform {
  transform(data: any[], filter:string) {
    console.log('filter', data, filter);
    if(!data || !filter) {
      return data;
    }
    return data.filter(row => row.some(col => col && col.indexOf(filter) >= 0));
  }
}

和像

这样的表组件
@Component({
    selector: 'my-table',
    template: `
<div style="width: 100%">
  <div style="float: left; height: 50px; width: 100%">
    Search: 
    <input type="text" 
        [(ngModel)]="filterValue" 
        name="filter"
        style="height: 30px; border: 1px solid silver"/> 
      {{filterValue}}
  </div>
  <div style="float: left; width: 100%">
    <table>
      <tr *ngFor="let row of data | filter:filterValue">
        <td *ngFor="let col of row let index=index">
          <template [ngTemplateOutlet]="templates && templates[index]" [ngOutletContext]="{$implicit: col}"></template>
        </td>
      </tr>
    </table>
  </div>
</div>
    `
})
export class MyTableComponent { 
  filterValue: string;
  @ContentChildren(TemplateRef) templateRefs:QueryList<TemplateRef>;
  @Input() data:any[];
  templates:TemplateRef[];

  ngAfterContentInit() {
    this.templates = this.templateRefs.toArray();
  }
} 

可以像

一样使用
@Component({
  selector: 'my-app',
  template: `
<my-table [data]="data">
  <template let-col>1: {{col}}</template>
  <template let-col>2: {{col}}</template>
  <template let-col>3: {{col}}</template>
</my-table>
  `,
})
export class App {
  data = [
    ['apple', 'orange', 'banana'],
    ['cat', 'dog', 'bird'],
    ['car', 'bicycle', 'airplane'],
  ];
}

其中行和列数据传递给输入,并且单元格的布局作为<template>元素传递(每列一个 - 一些额外的检查可能很有用,例如检查模板的数量是否为&gt; = data)中的列数。

答案 1 :(得分:0)

实际上,在不使用第三方包装器的情况下直接集成DataTabes非常容易。打字已在npm中提供。它为您提供了使用所需功能逐步扩展包装器的机会。