docs(cb-set-document-title): new "Set Title" cookbook chapter

closes #1069
This commit is contained in:
Ben Nadel 2016-04-10 09:14:24 -04:00 committed by Ward Bell
parent 634e50aaca
commit c9d405062d
15 changed files with 267 additions and 6 deletions

View File

@ -0,0 +1,27 @@
// gulp run-e2e-tests --filter=cb-set-document-title
describe('Set Document Title', function () {
beforeAll(function () {
browser.get('');
});
it('should set the document title', function () {
var titles = [
'Good morning!',
'Good afternoon!',
'Good evening!'
];
element.all( by.css( 'ul li a' ) ).each(
function iterator( element, i ) {
element.click();
expect( browser.getTitle() ).toEqual( titles[ i ] );
}
);
});
});

View File

@ -0,0 +1,2 @@
**/*.js
npm-debug.log

View File

@ -0,0 +1,29 @@
// #docplaster
// #docregion
// Import the native Angular services.
import { Component } from 'angular2/core';
import { Title } from 'angular2/platform/browser';
@Component({
selector: 'my-app',
template:
`<p>
Select a title to set on the current HTML document:
</p>
<ul>
<li><a (click)="setTitle( 'Good morning!' )">Good morning</a>.</li>
<li><a (click)="setTitle( 'Good afternoon!' )">Good afternoon</a>.</li>
<li><a (click)="setTitle( 'Good evening!' )">Good evening</a>.</li>
</ul>
`
})
// #docregion class
export class AppComponent {
public constructor(private _titleService: Title ) { }
public setTitle( newTitle: string) {
this._titleService.setTitle( newTitle );
}
}
// #enddocregion class

View File

@ -0,0 +1,20 @@
// #docregion
import { bootstrap } from 'angular2/platform/browser';
import { AppComponent } from './app.component';
// While Angular supplies a Title service for setting the HTML document title
// it doesn't include this service as part of the default Browser platform providers.
// As such, if we want to inject it into the components within our application,
// we have to explicitly provide the Angular service in our top component.
// #docregion bootstrap-title
import { Title } from 'angular2/platform/browser';
bootstrap(AppComponent, [ Title ])
// #enddocregion bootstrap-title
.then(
() => window.console.info( 'Angular finished bootstrapping your application!' ),
(error) => {
console.warn( 'Angular was not able to bootstrap your application.' );
console.error( error );
}
);

View File

@ -0,0 +1,63 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<base href="/">
<title>
Setting The Document Title Using The Title Service
</title>
<!-- #docregion style -->
<link rel="stylesheet" type="text/css" href="styles.css">
<link rel="stylesheet" type="text/css" href="sample.css">
<!-- #enddocregion style -->
<!-- IE required polyfills, in this exact order -->
<script src="node_modules/es6-shim/es6-shim.min.js"></script>
<script src="node_modules/systemjs/dist/system-polyfills.js"></script>
<script src="node_modules/angular2/es6/dev/src/testing/shims_for_IE.js"></script>
<script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="node_modules/rxjs/bundles/Rx.js"></script>
<script src="node_modules/angular2/bundles/angular2.dev.js"></script>
<script>
// Configure our module loader.
System.config({
packages: {
app: {
format: "register",
defaultExtension: "js"
}
}
});
// Load the root module (which will, in turn, bootstrap the Angular 2 application).
System
.import( "app/main" )
.then(
function handleSuccess() {
console.info( "System.js loaded your application module." );
},
function handleError( error ) {
console.warn( "System.js could not load your application module." );
console.error( error );
}
);
</script>
</head>
<body>
<h1>
Setting The Document Title Using The Title Service
</h1>
<my-app>
Loading app...
</my-app>
</body>
</html>

View File

@ -0,0 +1,9 @@
{
"description": "Set The Document Title In Angular 2",
"files": [
"!**/*.d.ts",
"!**/*.js",
"!**/*.[1].*"
],
"tags": [ "cookbook" ]
}

View File

@ -0,0 +1,4 @@
a {
color: #607D8B ;
text-decoration: underline ;
}

View File

@ -29,6 +29,11 @@
"hide": true
},
"set-document-title": {
"title": "Set the Document Title",
"intro": "Setting the document or window title using the Title service."
},
"ts-to-js": {
"title": "TypeScript to JavaScript",
"intro": "Convert Angular 2 TypeScript examples into ES5 JavaScript",

View File

@ -0,0 +1 @@
!= partial("../../../_includes/_ts-temp")

View File

@ -26,6 +26,11 @@
"intro": "Render dynamic forms with NgFormModel"
},
"set-document-title": {
"title": "Set the Document Title",
"intro": "Setting the document or window title using the Title service."
},
"ts-to-js": {
"title": "TypeScript to JavaScript",
"intro": "Convert Angular 2 TypeScript examples into ES5 JavaScript"

View File

@ -0,0 +1 @@
!= partial("../../../_includes/_ts-temp")

View File

@ -26,6 +26,11 @@
"intro": "Render dynamic forms with NgFormModel"
},
"set-document-title": {
"title": "Set the Document Title",
"intro": "Setting the document or window title using the Title service."
},
"ts-to-js": {
"title": "TypeScript to JavaScript",
"intro": "Convert Angular 2 TypeScript examples into ES5 JavaScript"

View File

@ -0,0 +1,90 @@
include ../_util-fns
a(id='top')
:marked
Our app should be able to make the browser title bar say whatever we want it to say.
This cookbook explains how to do it.
:marked
**See the [live example](/resources/live-examples/cb-set-document-title/ts/plnkr.html)**.
.l-sub-section
img(src='/resources/images/devguide/plunker-separate-window-button.png' alt="pop out the window" align="right" style="margin-right:-20px")
:marked
To see the browser Title bar changes,
pop out the preview window by clicking the blue 'X' button in the upper right corner.
:marked
## The problem with *&lt;title&gt;*
The obvious approach is to bind a property of the component to the HTML `<title>` like this:
code-example(format='')
&lt;title&gt;{{This_Does_Not_Work}}&lt;/title&gt;
:marked
Sorry but that won't work.
The root component of our application is an element contained within the `<body>` tag.
The HTML `<title>` is in the document `<head>`, outside the body, making it inaccessible to Angular data binding.
We could grab the browser `document` object and set the title manually.
That's dirty and undermines our chances of running the app outside of a browser someday.
.l-sub-section
:marked
That's a major Angular architectural goal. It may not seem important to us right now.
But why squander that future just to set the title bar?
:marked
## Use the *Title* service
Fortunately, Angular 2 bridges the gap by providing a `Title` service as part of the *Browser platform*.
The [Title](../api//platform/browser/Title-class.html) service is a simple class that provides an API
for getting and setting the current HTML document title:
* `getTitle() : string` &mdash; Gets the title of the current HTML document.
* `setTitle( newTitle : string )` &mdash; Sets the title of the current HTML document.
While this class is part of the Browser platform package, it is *not part of the default Browser
platform providers* that Angular loads automatically.
This means as we bootstrap our application using the Browser platform `boostrap()`
function, we'll also have to include `Title` service explicitly as one of the bootstrap providers:
+makeExample( "cb-set-document-title/ts/app/main.ts", "bootstrap-title", "app/main.ts (provide Title service)" )(format='.')
:marked
Once we've explicitly provided the `Title` service we can then inject the `Title` service into any of our
custom application components and services.
Let's inject the `Title` service into the root `AppComponent` and expose a bindable `setTitle` method that calls it:
+makeExample( "cb-set-document-title/ts/app/app.component.ts", "class", "app/app.component.ts (class)" )(format='.')
:marked
We bind that method to three anchor tags and, voilà!
figure.image-display
img(src="/resources/images/cookbooks/set-document-title/set-title-anim.gif" alt="Set title")
:marked
Here's the complete solution
+makeTabs(
`cb-set-document-title/ts/app/main.ts,
cb-set-document-title/ts/app/app.component.ts`,
'',
'app/main.ts, app/app.component.ts' )
//
Todo: tie this back to the router so we can see how to use this Title service to (re)set the title
that appears in the window navigation history and shows up in the back/forward buttons
during routing.
See https://github.com/angular/angular/issues/7630#issuecomment-198328802
.l-main-section
:marked
## Why we provide the *Title* service in *bootstrap*
We generally recommended providing application-wide services in the root application component, `AppComponent`.
Here we recommend registering the title service during bootstrapping,
a location we reserve for configuring the runtime Angular enviroment.
That's exactly what we're doing.
The `Title` service is part of the Angular *browser platform*.
If we bootstrap our application into a different platform,
we'll have to provide a different `Title` service that understands the concept of a "document title" for that specific platform.
Ideally the application itself neither knows nor cares about the runtime environment.
:marked
[Back to top](#top)

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB