This problem exists when using typescript 1.8, ng2 beta 10, and both primeNG 0.7 and 0.8.2.
The problem I am experiencing seems to have something to do with the zones that ng2 uses. Each of my components have a constructor and ngOnInit defined. Both are called automatically when the page with the component is loaded.
However, when the link is clicked that routes to the datatabledemo component the behaviour is different. First the constructor is called normally. But ngOnInit is not called autoomatically, therefore the table is never rendered.
After messing around with it for quite a while I added a button in to the datatabledemo template, and when the button click event is fired then, and only then, is ngOnInit called.
The problem seems to be something with the zones the app is executing in. Any component that does not use primeNG components fires off both the constructor and ngOnInit in the zone called 'root'. However, while the datatabledemo constructor runs in the zone 'root' I have noticed (through the commented out alerts), that when the button is clicked and an event is fired the ngOnInit function finally executes, but it does so in zone 'angular'.
After some exhaustive googling I have found this solution:
http://stackoverflow.com/questions/3569 ... h-angular2
Where if in the constructor of datatabledemo I call the cars service with an explicit call to zone.run the data is retrieved properly and immediately rendered:
Code: Select all
this.zone.run(() => this.carService.getCarsSmall().then(cars => this.cars = cars));
This solution is not ideal, because this code should really be inside ngOnInit. And it also does not explain *why* ngOnInit is not being called automatically.
One more thing to note: once the button is clicked I am getting the table rendered exactly as expected. I am also not getting any errors, 404 or otherwise, in the console during execution. So I am confident that all of my resources are being found properly and everything like that. I do not think it is an issue with the way I have the code set up or anything.
As I mentioned, this might not even be a primeNG issue, but it only manifests itself when using prime components.
Any help you can provide would be appreciated.
The base html:
Code: Select all
<h3>
Angular 2 Examples
</h3>
<!-- load angular 2 components -->
<script src="lib/es6-shim/es6-shim.min.js"></script>
<script src="lib/angular2/ts/src/testing/shims_for_IE.js"></script>
<script src="lib/angular2/bundles/angular2-polyfills.js"></script>
<script src="lib/systemjs/dist/system-polyfills.js"></script>
<script src="lib/systemjs/dist/system.js"></script>
<script src="lib/rxjs/bundles/rx.js"></script>
<script src="lib/angular2/bundles/angular2.dev.js"></script>
<script src="lib/angular2/bundles/router.dev.js"></script>
<script src="lib/angular2/bundles/http.dev.js"></script>
<!-- load PrimeUI components -->
<script src="lib/primeui/primeui-ng-all.min.js"></script>
<!-- configure SystemJS -->
<script>
System.config({
packages: {
app: {
defaultExtension : 'js'
},
services: {
defaultExtension: 'js'
},
models: {
defaultExtension: 'js'
},
components: {
defaultExtension: 'js'
},
interfaces: {
defaultExtension: 'js'
},
primeng: {
defaultExtension: 'js'
},
examples: {
defaultExtension: 'js'
},
primengEx: {
defaultExtension: 'js'
},
datatable: {
defaultExtension: 'js'
},
demo: {
defaultExtension: 'js'
}
},
map: {
'primeng': 'lib/primeng'
}
});
System.import('./app/examples/boot')
.then(null, console.error.bind(console));
</script>
boot.ts
Code: Select all
///<reference path="../../lib/zone.js/dist/zone.js.d.ts"/>
///<reference path="../../lib/angular2/typings/browser.d.ts"/>
import {bootstrap} from 'angular2/platform/browser';
import {provide} from 'angular2/core';
import {HTTP_PROVIDERS} from 'angular2/http';
import {Ng2ExamplesComponent} from './ng2examplesComponent';
import {ROUTER_PROVIDERS, LocationStrategy, HashLocationStrategy} from 'angular2/router';
import 'rxjs/Rx';
bootstrap(Ng2ExamplesComponent, [ROUTER_PROVIDERS, provide(LocationStrategy, { useClass: HashLocationStrategy })]);
Code: Select all
import {Component, Inject, Directive, ViewChild, Output, OnInit} from 'angular2/core';
import {RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
import {DataTableDemoComponent} from './datatable/demo/datatable/datatabledemo';
@Component({
selector: 'angular2-examples',
templateUrl: 'app/examples/ng2ExamplesTemplate.html',
directives: [ROUTER_DIRECTIVES]
})
@RouteConfig([
{ path: '/datatabledemo', name: 'DataTableDemo', component: DataTableDemoComponent}
])
export class Ng2ExamplesComponent implements OnInit {
Text: string; // = "Angular 2 example success!";
constructor() {
//alert("Ng2 Ex constr zone: " + Zone.current.name);
}
ngOnInit() {
//alert("Ng2 Ex init zone: " + Zone.current.name);
this.Text = "Angular 2 example success!";
}
}
Code: Select all
<base href="NG2Examples/">
<div>
{{Text}}
</div>
<span>Demos</span>
<div>
<a class="SubMenuLink" [routerLink]="['DataTableDemo']" >Data Table Demo</a>
</div>
<div>
<router-outlet></router-outlet>
</div>
Code: Select all
import {Component, OnInit, NgZone, Inject} from 'angular2/core';
import {HTTP_PROVIDERS} from 'angular2/http';
import {ROUTER_DIRECTIVES} from 'angular2/router';
import {DataTable} from '../../../../../lib/primeng/components/datatable/datatable';
import {Car} from '../domain/car';
import {Column} from '../../../../../lib/primeng/components/column/column';
import {CarService} from '../service/carservice';
@Component({
templateUrl: '/app/examples/datatable/demo/datatable/datatabledemo.html',
directives: [DataTable, Column, ROUTER_DIRECTIVES],
providers: [HTTP_PROVIDERS, CarService, CarModel]
})
export class DataTableDemoComponent implements OnInit {
message: string = "Force Bindings";
cars: Array<Carl>;
cols: any[];
constructor( private carService : CarService, private zone: NgZone) {
//this.zone.run(() => this.carService.getCarsSmall().then(cars => this.cars = cars));
}
ngOnInit() {
this.carService.getCarsSmall().then(cars => this.cars = cars);
//alert("Dtd.ts ngInit zone: " + Zone.current.name);
this.cols = [
{ field: 'vin', header: 'Vin' },
{ field: 'year', header: 'Year' },
{ field: 'brand', header: 'Brand' },
{ field: 'color', header: 'Color' }
];
}
onClickDemo() {
var x = 0;
x++;
}
}
Code: Select all
<div>
<button (click)="onClickDemo()">Something</button>
<div>{{message}}</div>
<h3>Basic</h3>
<p-dataTable [value]="cars">
<p-column field="vin" header="Vin"></p-column>
<p-column field="year" header="Year"></p-column>
<p-column field="brand" header="Brand"></p-column>
<p-column field="color" header="Color"></p-column>
</p-dataTable>
<h3>Dynamic Columns</h3>
<p-dataTable [value]="cars">
<p-column *ngFor="#col of cols" [field]="col.field" [header]="col.header"></p-column>
</p-dataTable>
</div>
Code: Select all
export interface Car {
vin;
year;
brand;
color;
}
Code: Select all
import {Injectable, Inject} from 'angular2/core';
import {Http, Response} from 'angular2/http';
import {Car} from '../domain/car';
@Injectable()
export class CarService {
http: Http;
constructor( @Inject(Http) http) {
this.http = http;
}
getCarsSmall() {
alert("Car srv zone: " + Zone.current.name);
return this.http.get('../app/examples/datatable/resources/data/cars-small.json')
.toPromise()
.then(res => <Car[]>res.json().data)
.then(data => { return data; });
}
getCarsMedium() {
return this.http.get('showcase/resources/data/cars-medium.json')
.toPromise()
.then(res => <Car[]>res.json().data)
.then(data => { return data; });
}
getCarsLarge() {
return this.http.get('showcase/resources/data/cars-large.json')
.toPromise()
.then(res => <Car[]>res.json().data)
.then(data => { return data; });
}
}
Code: Select all
{
"data": [
{
"brand": "VW",
"year": 2012,
"color": "White",
"vin": "dsad231ff"
},
{
"brand": "Audi",
"year": 2011,
"color": "Black",
"vin": "gwregre345"
},
{
"brand": "Renault",
"year": 2005,
"color": "Gray",
"vin": "h354htr"
},
{
"brand": "BMW",
"year": 2003,
"color": "Blue",
"vin": "j6w54qgh"
},
{
"brand": "Mercedes",
"year": 1995,
"color": "White",
"vin": "hrtwy34"
},
{
"brand": "Volvo",
"year": 2005,
"color": "Black",
"vin": "jejtyj"
},
{
"brand": "Honda",
"year": 2012,
"color": "Yellow",
"vin": "g43gr"
},
{
"brand": "Jaguar",
"year": 2013,
"color": "White",
"vin": "greg34"
},
{
"brand": "Ford",
"year": 2000,
"color": "Black",
"vin": "h54hw5"
},
{
"brand": "Fiat",
"year": 2013,
"color": "Red",
"vin": "245t2s"
}
]
}