Skip to content
This repository was archived by the owner on Feb 2, 2025. It is now read-only.

Commit ce87ea1

Browse files
committed
Implement the Angular renderer #955
1 parent d1168d4 commit ce87ea1

8 files changed

+222
-10
lines changed

demo/src/app/app.component.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ <h3>
4141
<li><a routerLink="/basic/zero-config">Zero configuration</a></li>
4242
<li><a routerLink="/basic/with-options">With options</a></li>
4343
<li><a routerLink="/basic/with-ajax">With ajax</a></li>
44+
<li><a routerLink="/basic/angular-way">Angular way</a></li>
4445
</ul>
4546
</div>
4647
</li>

demo/src/app/app.component.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
1-
import { Component, ElementRef } from '@angular/core';
1+
import { Component, ElementRef, OnInit } from '@angular/core';
2+
3+
declare var $: any;
24

35
@Component({
46
selector: 'app-root',
57
templateUrl: './app.component.html',
68
styleUrls: ['./app.component.css']
79
})
8-
export class AppComponent {
10+
export class AppComponent implements OnInit {
911
title = 'Angular DataTables examples';
12+
13+
ngOnInit(): void {
14+
$.fn.dataTable.ext.errMode = 'none';
15+
}
1016
}

demo/src/app/app.module.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { HttpModule } from '@angular/http';
55

66
import { HighlightJsModule, HighlightJsService } from 'angular2-highlight-js';
77

8-
import { DataTablesModule } from 'angular-datatables';
8+
import { DataTablesModule } from './angular-datatables';
99

1010
import { AppRoutingModule } from './app.routing';
1111

@@ -20,6 +20,8 @@ import { WithOptionsComponent } from './basic/with-options.component';
2020
import { WithOptionsSnippetComponent } from './basic/with-options-snippet.component';
2121
import { WithAjaxComponent } from './basic/with-ajax.component';
2222
import { WithAjaxSnippetComponent } from './basic/with-ajax-snippet.component';
23+
import { AngularWayComponent } from './basic/angular-way.component';
24+
import { AngularWaySnippetComponent } from './basic/angular-way-snippet.component';
2325

2426
// Advanced examples
2527
import {  DtInstanceComponent } from './advanced/dt-instance.component';
@@ -41,6 +43,8 @@ import { RowClickEventSnippetComponent } from './advanced/row-click-event-snippe
4143
WithOptionsSnippetComponent,
4244
WithAjaxComponent,
4345
WithAjaxSnippetComponent,
46+
AngularWayComponent,
47+
AngularWaySnippetComponent,
4448

4549
DtInstanceComponent,
4650
DtInstanceSnippetComponent,

demo/src/app/app.routing.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { GettingStartedComponent } from './getting-started.component';
77
import { ZeroConfigComponent } from './basic/zero-config.component';
88
import { WithOptionsComponent } from './basic/with-options.component';
99
import { WithAjaxComponent } from './basic/with-ajax.component';
10+
import { AngularWayComponent } from './basic/angular-way.component';
1011

1112
import { DtInstanceComponent } from './advanced/dt-instance.component';
1213
import { LoadDtOptionsWithPromiseComponent } from './advanced/load-dt-options-with-promise.component';
@@ -38,6 +39,10 @@ const routes: Routes = [
3839
path: 'basic/with-ajax',
3940
component: WithAjaxComponent
4041
},
42+
{
43+
path: 'basic/angular-way',
44+
component: AngularWayComponent
45+
},
4146
{
4247
path: 'advanced/dt-instance',
4348
component: DtInstanceComponent
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import { Component } from '@angular/core';
2+
3+
@Component({
4+
selector: 'app-angular-way-snippet',
5+
template: `
6+
<div id="html" class="col s12 m9 l12">
7+
<h4 class="header">HTML</h4>
8+
<section [innerHTML]="htmlSnippet" highlight-js-content=".xml"></section>
9+
</div>
10+
<div id="ts" class="col s12 m9 l12">
11+
<h4 class="header">Typescript</h4>
12+
<section [innerHTML]="tsSnippet" highlight-js-content=".typescript"></section>
13+
</div>
14+
`
15+
})
16+
export class AngularWaySnippetComponent {
17+
htmlSnippet = `
18+
<pre>
19+
<code class="xml highlight">&lt;table datatable [dtOptions]="dtOptions" [dtTrigger]="dtTrigger" class="row-border hover"&gt;
20+
&lt;thead&gt;
21+
&lt;tr&gt;
22+
&lt;th&gt;ID&lt;/th&gt;
23+
&lt;th&gt;First name&lt;/th&gt;
24+
&lt;th&gt;Last name&lt;/th&gt;
25+
&lt;/tr&gt;
26+
&lt;/thead&gt;
27+
&lt;tbody&gt;
28+
&lt;tr *ngFor="let person of persons"&gt;
29+
&lt;td&gt;{{ person.id }}&lt;/td&gt;
30+
&lt;td&gt;{{ person.firstName }}&lt;/td&gt;
31+
&lt;td&gt;{{ person.lastName }}&lt;/td&gt;
32+
&lt;/tr&gt;
33+
&lt;/tbody&gt;
34+
&lt;/table&gt;</code>
35+
</pre>
36+
`;
37+
38+
tsSnippet = `
39+
<pre>
40+
<code class="typescript highlight">import { Component, OnInit } from '@angular/core';
41+
import { Http, Response } from '@angular/http';
42+
import { Subject } from 'rxjs/Rx';
43+
44+
import 'rxjs/add/operator/map';
45+
46+
class Person {
47+
id: number;
48+
firstName: string;
49+
lastName: string;
50+
}
51+
52+
@Component({
53+
selector: 'app-angular-way',
54+
templateUrl: 'angular-way.component.html'
55+
})
56+
export class AngularWayComponent implements OnInit {
57+
dtOptions: any = {};
58+
persons: Person[] = [];
59+
// We use this trigger because fetching the list of persons can be quite long,
60+
// thus we ensure the data is fetched before rendering
61+
dtTrigger: Subject<any> = new Subject();
62+
63+
constructor(private http: Http) { }
64+
65+
ngOnInit(): void {
66+
this.dtOptions = {
67+
paginationType: 'full_numbers',
68+
displayLength: 2
69+
};
70+
this.http.get('data/data.json')
71+
.map(this.extractData)
72+
.subscribe(persons => {
73+
this.persons = persons;
74+
// Calling the DT trigger to manually render the table
75+
this.dtTrigger.next();
76+
});
77+
}
78+
79+
private extractData(res: Response) {
80+
const body = res.json();
81+
return body.data || {};
82+
}
83+
}</code>
84+
</pre>
85+
`;
86+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<div class="section banner">
2+
<div class="container">
3+
<div class="row">
4+
<div class="col s12 m9">
5+
<h1 class="header center-on-small-only">Angular way</h1>
6+
</div>
7+
</div>
8+
</div>
9+
</div>
10+
<div class="container">
11+
<div class="row">
12+
<div class="col s12 m9 l12">
13+
<div class="section">
14+
<p class="caption">
15+
You can use the angular directives to render the table. Angular-datatables provides a <code>dtTrigger</code> you can use to manually trigger the rendering of the table.
16+
</p>
17+
<div class="col s12 m9 l12 showcase-tabs">
18+
<ul class="anchor-links">
19+
<li class="col s3"><a class="waves-effect btn" href="#preview">Preview</a></li>
20+
<li class="col s3"><a class="waves-effect btn" href="#html">HTML</a></li>
21+
<li class="col s3"><a class="waves-effect btn" href="#ts">Typescript</a></li>
22+
</ul>
23+
</div>
24+
<div id="preview" class="col s12 m9 l12">
25+
<h4 class="header">Preview</h4>
26+
<table datatable [dtOptions]="dtOptions" [dtTrigger]="dtTrigger" class="row-border hover">
27+
<thead>
28+
<tr>
29+
<th>ID</th>
30+
<th>First name</th>
31+
<th>Last name</th>
32+
</tr>
33+
</thead>
34+
<tbody>
35+
<tr *ngFor="let person of persons">
36+
<td>{{ person.id }}</td>
37+
<td>{{ person.firstName }}</td>
38+
<td>{{ person.lastName }}</td>
39+
</tr>
40+
</tbody>
41+
</table>
42+
<app-angular-way-snippet></app-angular-way-snippet>
43+
</div>
44+
</div>
45+
</div>
46+
</div>
47+
</div>
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { Component, OnInit } from '@angular/core';
2+
import { Http, Response } from '@angular/http';
3+
import { Subject } from 'rxjs/Rx';
4+
5+
import 'rxjs/add/operator/map';
6+
7+
class Person {
8+
id: number;
9+
firstName: string;
10+
lastName: string;
11+
}
12+
13+
@Component({
14+
selector: 'app-angular-way',
15+
templateUrl: 'angular-way.component.html'
16+
})
17+
export class AngularWayComponent implements OnInit {
18+
dtOptions: any = {};
19+
persons: Person[] = [];
20+
// We use this trigger because fetching the list of persons can be quite long,
21+
// thus we ensure the data is fetched before rendering
22+
dtTrigger: Subject<any> = new Subject();
23+
24+
constructor(private http: Http) { }
25+
26+
ngOnInit(): void {
27+
this.dtOptions = {
28+
paginationType: 'full_numbers',
29+
displayLength: 2
30+
};
31+
this.http.get('data/data.json')
32+
.map(this.extractData)
33+
.subscribe(persons => {
34+
this.persons = persons;
35+
// Calling the DT trigger to manually render the table
36+
this.dtTrigger.next();
37+
});
38+
}
39+
40+
private extractData(res: Response) {
41+
const body = res.json();
42+
return body.data || {};
43+
}
44+
}

src/angular-datatables.directive.ts

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
* found in the LICENSE file at https://raw.githubusercontent.com/l-lin/angular-datatables/master/LICENSE
66
*/
77

8-
import { Directive, ElementRef, Inject, OnInit, Input, Component } from '@angular/core';
8+
import { Directive, ElementRef, Input, OnInit } from '@angular/core';
9+
import { Subject } from 'rxjs/Rx';
910
import 'jquery';
1011
import 'datatables.net';
1112
declare var $: any;
@@ -18,7 +19,14 @@ export class DataTableDirective implements OnInit {
1819
* The DataTable option you pass to configure your table.
1920
*/
2021
@Input()
21-
dtOptions: any;
22+
dtOptions: any = {};
23+
24+
/**
25+
* This trigger is used if one wants to trigger manually the DT rendering
26+
* Useful when rendering angular rendered DOM
27+
*/
28+
@Input()
29+
dtTrigger: Subject<any>;
2230

2331
/**
2432
* The DataTable instance built by the jQuery library [DataTables](datatables.net).
@@ -28,15 +36,26 @@ export class DataTableDirective implements OnInit {
2836
*/
2937
dtInstance: Promise<any>;
3038

31-
constructor(@Inject(ElementRef) private el: ElementRef) {
32-
this.dtOptions = {};
39+
constructor(private el: ElementRef) { }
40+
41+
ngOnInit(): void {
42+
if (this.dtTrigger) {
43+
this.dtTrigger.subscribe(() => {
44+
this.displayTable();
45+
});
46+
} else {
47+
this.displayTable();
48+
}
3349
}
3450

35-
ngOnInit() {
51+
private displayTable(): void {
3652
this.dtInstance = new Promise((resolve, reject) => {
3753
Promise.resolve(this.dtOptions).then(dtOptions => {
38-
const dt = $(this.el.nativeElement).DataTable(dtOptions);
39-
resolve(dt);
54+
// Using setTimeout as a "hack" to be "part" of NgZone
55+
setTimeout(() => {
56+
const dt = $(this.el.nativeElement).DataTable(dtOptions);
57+
resolve(dt);
58+
});
4059
});
4160
});
4261
}

0 commit comments

Comments
 (0)