Skip to content

Commit 4b356f3

Browse files
committed
feature(angular2spa): Angular 2.0, Universal 2.0, TS 2.0
1 parent bbc95e0 commit 4b356f3

File tree

18 files changed

+274
-1167
lines changed

18 files changed

+274
-1167
lines changed

templates/Angular2Spa/ClientApp/boot-client.ts

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,30 @@
1+
// the polyfills must be the first thing imported
2+
import 'angular2-universal-polyfills';
3+
14
import 'es6-shim';
25
require('zone.js');
36
import 'bootstrap';
47
import 'reflect-metadata';
58
import './styles/site.css';
69

7-
import { bootstrap } from '@angular/platform-browser-dynamic';
8-
import { FormBuilder } from '@angular/common';
9-
import { provideRouter } from '@angular/router';
10-
import { HTTP_PROVIDERS } from '@angular/http';
11-
import { App } from './components/app/app';
12-
import { routes } from './routes';
13-
14-
bootstrap(App, [
15-
...HTTP_PROVIDERS,
16-
FormBuilder,
17-
provideRouter(routes)
18-
]);
10+
// Angular 2
11+
import { enableProdMode} from '@angular/core';
12+
import { platformUniversalDynamic } from 'angular2-universal';
13+
14+
// enable prod for faster renders
15+
enableProdMode();
16+
17+
import { MainModule } from './main.browser';
18+
19+
const platformRef = platformUniversalDynamic();
20+
21+
// on document ready bootstrap Angular 2
22+
document.addEventListener('DOMContentLoaded', () => {
23+
24+
platformRef.bootstrapModule(MainModule);
25+
26+
});
27+
1928

2029
// Basic hot reloading support. Automatically reloads and restarts the Angular 2 app each time
2130
// you modify source files. This will not preserve any application state other than the URL.
Lines changed: 69 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,76 @@
1-
import 'angular2-universal/polyfills';
2-
import * as ngCore from '@angular/core';
3-
import { APP_BASE_HREF } from '@angular/common';
4-
import { provideRouter } from '@angular/router';
5-
import * as ngUniversal from 'angular2-universal';
6-
import { BASE_URL, ORIGIN_URL, REQUEST_URL } from 'angular2-universal/common';
7-
import { App } from './components/app/app';
1+
// the polyfills must be the first thing imported in node.js
2+
import 'angular2-universal-polyfills';
3+
4+
// Angular 2
5+
import { enableProdMode } from '@angular/core';
6+
// Angular2 Universal
7+
import { platformNodeDynamic } from 'angular2-universal';
8+
9+
// Application imports
10+
import { MainModule } from './main.node';
11+
import { App } from './components';
812
import { routes } from './routes';
913

10-
const bootloader = ngUniversal.bootloader({
11-
async: true,
12-
preboot: false,
13-
platformProviders: [
14-
ngCore.provide(APP_BASE_HREF, { useValue: '/' }),
15-
]
16-
});
17-
18-
export default function (params: any): Promise<{ html: string, globals?: any }> {
19-
const config: ngUniversal.AppConfig = {
20-
directives: [App],
21-
providers: [
22-
ngCore.provide(ORIGIN_URL, { useValue: params.origin }),
23-
ngCore.provide(REQUEST_URL, { useValue: params.url }),
24-
...ngUniversal.NODE_HTTP_PROVIDERS,
25-
provideRouter(routes),
26-
...ngUniversal.NODE_LOCATION_PROVIDERS,
27-
],
28-
// TODO: Render just the <app> component instead of wrapping it inside an extra HTML document
29-
// Waiting on https://github.com/angular/universal/issues/347
30-
template: '<!DOCTYPE html>\n<html><head></head><body><app></app></body></html>'
14+
// enable prod for faster renders
15+
enableProdMode();
16+
17+
declare var Zone: any;
18+
19+
export default function (params: any) : Promise<{ html: string, globals?: any }> {
20+
21+
const doc = `
22+
<!DOCTYPE html>\n
23+
<html>
24+
<head></head>
25+
<body>
26+
<app></app>
27+
</body>
28+
</html>
29+
`;
30+
31+
// hold platform reference
32+
var platformRef = platformNodeDynamic();
33+
34+
var platformConfig = {
35+
ngModule: MainModule,
36+
document: doc,
37+
preboot: false,
38+
baseUrl: '/',
39+
requestUrl: params.url,
40+
originUrl: params.origin
3141
};
3242

33-
return bootloader.serializeApplication(config).then(html => {
43+
// defaults
44+
var cancel = false;
45+
46+
const _config = Object.assign({
47+
get cancel() { return cancel; },
48+
cancelHandler() { return Zone.current.get('cancel') }
49+
}, platformConfig);
50+
51+
// for each user
52+
const zone = Zone.current.fork({
53+
name: 'UNIVERSAL request',
54+
properties: _config
55+
});
56+
57+
58+
return Promise.resolve(
59+
zone.run(() => {
60+
return platformRef.serializeModule(Zone.current.get('ngModule'))
61+
})
62+
).then(html => {
63+
64+
if (typeof html !== 'string' ) {
65+
return { html : doc };
66+
}
3467
return { html };
68+
69+
}).catch(err => {
70+
71+
console.log(err);
72+
return { html : doc };
73+
3574
});
75+
3676
}
Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
import * as ng from '@angular/core';
2-
import { ROUTER_DIRECTIVES } from '@angular/router';
1+
import { Component } from '@angular/core';
32
import { NavMenu } from '../nav-menu/nav-menu';
43

5-
@ng.Component({
4+
@Component({
65
selector: 'app',
7-
template: require('./app.html'),
8-
directives: [...ROUTER_DIRECTIVES, NavMenu]
6+
template: require('./app.html')
97
})
108
export class App {
119
}

templates/Angular2Spa/ClientApp/components/counter/counter.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import * as ng from '@angular/core';
1+
import { Component } from '@angular/core';
22

3-
@ng.Component({
3+
@Component({
44
selector: 'counter',
55
template: require('./counter.html')
66
})

templates/Angular2Spa/ClientApp/components/fetch-data/fetch-data.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import * as ng from '@angular/core';
1+
import { Component } from '@angular/core';
22
import { Http } from '@angular/http';
33

4-
@ng.Component({
4+
@Component({
55
selector: 'fetch-data',
66
template: require('./fetch-data.html')
77
})

templates/Angular2Spa/ClientApp/components/home/home.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import * as ng from '@angular/core';
1+
import { Component }from '@angular/core';
22

3-
@ng.Component({
3+
@Component({
44
selector: 'home',
55
template: require('./home.html')
66
})
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Here we can create "Barrels" so that it's easier to import everything
2+
// within /components
3+
4+
export * from './app/app';
5+
export * from './counter/counter';
6+
export * from './fetch-data/fetch-data';
7+
export * from './home/home';
8+
export * from './nav-menu/nav-menu';
Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
import * as ng from '@angular/core';
2-
import { ROUTER_DIRECTIVES } from '@angular/router';
1+
import { Component } from '@angular/core';
32

4-
@ng.Component({
3+
@Component({
54
selector: 'nav-menu',
6-
template: require('./nav-menu.html'),
7-
directives: [...ROUTER_DIRECTIVES]
5+
template: require('./nav-menu.html')
86
})
97
export class NavMenu {
108
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { NgModule } from '@angular/core';
2+
import { FormsModule } from '@angular/forms';
3+
import { RouterModule } from '@angular/router';
4+
import { UniversalModule } from 'angular2-universal';
5+
6+
import {
7+
App,
8+
Counter,
9+
FetchData,
10+
Home,
11+
NavMenu
12+
} from './components';
13+
14+
import { routes } from './routes';
15+
16+
/* NOTE :
17+
18+
This file and `main.node.ts` are identical, at the moment(!)
19+
By splitting these, you're able to create logic, imports, etc
20+
that are "Platform" specific.
21+
22+
If you want your code to be completely Universal and don't need that
23+
You can also just have 1 file, that is imported into both
24+
* boot-client
25+
* boot-server
26+
27+
*/
28+
29+
// ** Top-level NgModule "container" **
30+
@NgModule({
31+
32+
// Root App Component
33+
bootstrap: [ App ],
34+
35+
// Our Components
36+
declarations: [
37+
App, Counter, FetchData, Home, NavMenu
38+
],
39+
40+
imports: [
41+
42+
// * NOTE: Needs to be your first import (!)
43+
UniversalModule,
44+
// * ^ BrowserModule, HttpModule, and JsonpModule are included here
45+
46+
// Your other imports can go here :
47+
FormsModule,
48+
49+
// App Routing
50+
RouterModule.forRoot(routes)
51+
]
52+
})
53+
export class MainModule {
54+
55+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { NgModule } from '@angular/core';
2+
import { FormsModule } from '@angular/forms';
3+
import { RouterModule } from '@angular/router';
4+
import { UniversalModule } from 'angular2-universal';
5+
6+
import {
7+
App,
8+
Counter,
9+
FetchData,
10+
Home,
11+
NavMenu
12+
} from './components';
13+
14+
import { routes } from './routes';
15+
16+
/* NOTE :
17+
18+
This file and `main.browser.ts` are identical, at the moment(!)
19+
By splitting these, you're able to create logic, imports, etc
20+
that are "Platform" specific.
21+
22+
If you want your code to be completely Universal and don't need that
23+
You can also just have 1 file, that is imported into both
24+
* boot-client
25+
* boot-server
26+
27+
*/
28+
29+
// ** Top-level NgModule "container" **
30+
@NgModule({
31+
32+
// Root App Component
33+
bootstrap: [ App ],
34+
35+
// Our Components
36+
declarations: [
37+
App, Counter, FetchData, Home, NavMenu
38+
],
39+
40+
imports: [
41+
42+
// * NOTE: Needs to be your first import (!)
43+
UniversalModule,
44+
// ^ NodeModule, NodeHttpModule, NodeJsonpModule are included for server
45+
46+
// Your other imports can go here:
47+
FormsModule,
48+
49+
// App Routing
50+
RouterModule.forRoot(routes)
51+
]
52+
})
53+
export class MainModule {
54+
55+
}

0 commit comments

Comments
 (0)