npm install -g angular-cli
ng new my-shiny-app cd my-shiny-app
ng serve
ng generate component my-shiny-component ng g component my-shiny-component
ng g class my-shiny-class ng g service my-shiny-service
ng new myApp --mobile
The --mobile flag has been disabled temporarily while we await an update
of angular-universal for supporting NgModule. Sorry for the inconvenience.
<html>
<body>
<app-root-component>
<h1>Loading...</h1>
</app-root-component>
</body>
</html>
<html>
<body>
<app-root-component>
<style>...</style>
<div class="md-header">
<h3>Proper Application Shell</h3>
</div>
<div class="md-progress-bar"></div>
<div class="signup-form">...</div>
</app-root-component>
</body>
</html>
import { UniversalModule } from 'angular2-universal';
@NgModule({
bootstrap: [AppComponent],
imports: [
AppModule,
UniversalModule.withConfig({
...
}),
})
export class AppShellModule {}
platformUniversalDynamic()
.serializeModule(ShellModule)
.then(html => console.log(html));
# Install app-shell utility from github.com/angular/mobile-toolkit
$ npm install --save @angular/app-shell
// App code
import {AppShellModule} from '@angular/app-shell';
// In NgModule used for Universal prerendering:
AppShellModule.prerender()
// At runtime:
AppShellModule.runtime()
@Component({
selector: 'app-root-component',
template: `
<!-- Only show loading indicator in the shell -->
<loading-indicator *shellRender>
</loading-indicator>
<!-- Hide a dynamic view until runtime -->
<dynamic-view *shellNoRender>
</dynamic-view>
`
})
export class AppRootComponent {}
# First, install the Angular Service Worker
$ npm install --save @angular/service-worker
<script type="text/javascript">
// Require worker-basic.min.js copied to deploy directory from
// node_modules/@angular/service-worker/bundles
// Feature detection guards against older browsers that don't
// support service workers.
if (navigator.serviceWorker) {
navigator.serviceWorker.register('/worker-basic.min.js');
}
</script>
ngsw-manifest.json:
{
"static": {
"urls": {
"/index.html": "ae543...",
"/app.js": "9ff18...",
"/logo.png": "0e33a...",
...
}
}
}
import AngularSWPlugin from '@angular/service-worker/webpack';
webpack({
entry: 'index.html',
output: {...},
plugins: [
...,
new AngularSWPlugin()
]
});
{
...,
"dynamic": {
"match": [{
"url": "/api",
"prefix": true,
"strategy": "fastest"
"invalidate": [...]
}]
}
}
Скоро
manifest.webapp
{
"name": "Hello Mobile",
"short_name": "Hello Mobile",
"icons": [
{
"src": "/android-chrome-36x36.png",
"sizes": "36x36",
"type": "image/png",
"density": 0.75
},
...
],
"theme_color": "#000000",
"background_color": "#e0e0e0",
"start_url": "/index.html",
"display": "standalone",
"orientation": "portrait"
}
Backend
Push Service
Service worker
ngsw-manifest.json:
{
...,
"push": {
"showNotifications": true
}
}
manifest.webapp
{
...,
"gcm_sender_id": "12345"
}
# web-push package nicely handles details of pushing data
$ npm install --save web-push
const webPush = require('web-push');
webPush.setGCMAPIKey(...);
let payload = {
notification: {
title: 'Hello from the server', body: '...', icon: '/icon.png'
}
};
webPush.sendNotification({
payload: new Buffer(JSON.stringify(payload)), …
});
// Configure app to include module from @angular/service-worker
import {ServiceWorkerModule} from '@angular/service-worker';
// Inject an API for communicating with the Angular service worker
export class PushService {
constructor(worker: NgServiceWorker) {
worker.registerForPush().subscribe(endpoint => {
// Send endpoint data to the server to complete registration
};
worker.push.subscribe(payload => {
// Process payload
});
}
}