docs(cb-set-document-title): new "Set Title" cookbook chapter
closes #1069
This commit is contained in:
parent
634e50aaca
commit
c9d405062d
|
@ -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 ] );
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
|
@ -0,0 +1,2 @@
|
||||||
|
**/*.js
|
||||||
|
npm-debug.log
|
|
@ -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
|
|
@ -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 );
|
||||||
|
}
|
||||||
|
);
|
|
@ -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>
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"description": "Set The Document Title In Angular 2",
|
||||||
|
"files": [
|
||||||
|
"!**/*.d.ts",
|
||||||
|
"!**/*.js",
|
||||||
|
"!**/*.[1].*"
|
||||||
|
],
|
||||||
|
"tags": [ "cookbook" ]
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
a {
|
||||||
|
color: #607D8B ;
|
||||||
|
text-decoration: underline ;
|
||||||
|
}
|
|
@ -4,14 +4,14 @@
|
||||||
"navTitle": "Overview",
|
"navTitle": "Overview",
|
||||||
"intro": "A collection of recipes for common Angular application scenarios"
|
"intro": "A collection of recipes for common Angular application scenarios"
|
||||||
},
|
},
|
||||||
|
|
||||||
"a1-a2-quick-reference": {
|
"a1-a2-quick-reference": {
|
||||||
"title": "Angular 1 to 2 Quick Reference",
|
"title": "Angular 1 to 2 Quick Reference",
|
||||||
"navTitle": "Angular 1 to 2 Quick Ref",
|
"navTitle": "Angular 1 to 2 Quick Ref",
|
||||||
"intro": "Learn how Angular 1 concepts and techniques map to Angular 2",
|
"intro": "Learn how Angular 1 concepts and techniques map to Angular 2",
|
||||||
"hide": true
|
"hide": true
|
||||||
},
|
},
|
||||||
|
|
||||||
"component-communication": {
|
"component-communication": {
|
||||||
"title": "Component Interaction",
|
"title": "Component Interaction",
|
||||||
"intro": "Share information between different directives and components"
|
"intro": "Share information between different directives and components"
|
||||||
|
@ -22,16 +22,21 @@
|
||||||
"intro": "Techniques for Dependency Injection",
|
"intro": "Techniques for Dependency Injection",
|
||||||
"hide": true
|
"hide": true
|
||||||
},
|
},
|
||||||
|
|
||||||
"dynamic-forms": {
|
"dynamic-forms": {
|
||||||
"title": "Dynamic Form",
|
"title": "Dynamic Form",
|
||||||
"intro": "Render dynamic forms with NgFormModel",
|
"intro": "Render dynamic forms with NgFormModel",
|
||||||
"hide": true
|
"hide": true
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"set-document-title": {
|
||||||
|
"title": "Set the Document Title",
|
||||||
|
"intro": "Setting the document or window title using the Title service."
|
||||||
|
},
|
||||||
|
|
||||||
"ts-to-js": {
|
"ts-to-js": {
|
||||||
"title": "TypeScript to JavaScript",
|
"title": "TypeScript to JavaScript",
|
||||||
"intro": "Convert Angular 2 TypeScript examples into ES5 JavaScript",
|
"intro": "Convert Angular 2 TypeScript examples into ES5 JavaScript",
|
||||||
"hide": true
|
"hide": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
!= partial("../../../_includes/_ts-temp")
|
|
@ -26,6 +26,11 @@
|
||||||
"intro": "Render dynamic forms with NgFormModel"
|
"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": {
|
"ts-to-js": {
|
||||||
"title": "TypeScript to JavaScript",
|
"title": "TypeScript to JavaScript",
|
||||||
"intro": "Convert Angular 2 TypeScript examples into ES5 JavaScript"
|
"intro": "Convert Angular 2 TypeScript examples into ES5 JavaScript"
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
!= partial("../../../_includes/_ts-temp")
|
|
@ -4,13 +4,13 @@
|
||||||
"navTitle": "Overview",
|
"navTitle": "Overview",
|
||||||
"description": "A collection of recipes for common Angular application scenarios"
|
"description": "A collection of recipes for common Angular application scenarios"
|
||||||
},
|
},
|
||||||
|
|
||||||
"a1-a2-quick-reference": {
|
"a1-a2-quick-reference": {
|
||||||
"title": "Angular 1 to 2 Quick Reference",
|
"title": "Angular 1 to 2 Quick Reference",
|
||||||
"navTitle": "Angular 1 to 2 Quick Ref",
|
"navTitle": "Angular 1 to 2 Quick Ref",
|
||||||
"intro": "Learn how Angular 1 concepts and techniques map to Angular 2"
|
"intro": "Learn how Angular 1 concepts and techniques map to Angular 2"
|
||||||
},
|
},
|
||||||
|
|
||||||
"component-communication": {
|
"component-communication": {
|
||||||
"title": "Component Interaction",
|
"title": "Component Interaction",
|
||||||
"intro": "Share information between different directives and components"
|
"intro": "Share information between different directives and components"
|
||||||
|
@ -26,6 +26,11 @@
|
||||||
"intro": "Render dynamic forms with NgFormModel"
|
"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": {
|
"ts-to-js": {
|
||||||
"title": "TypeScript to JavaScript",
|
"title": "TypeScript to JavaScript",
|
||||||
"intro": "Convert Angular 2 TypeScript examples into ES5 JavaScript"
|
"intro": "Convert Angular 2 TypeScript examples into ES5 JavaScript"
|
||||||
|
|
|
@ -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 *<title>*
|
||||||
|
|
||||||
|
The obvious approach is to bind a property of the component to the HTML `<title>` like this:
|
||||||
|
code-example(format='')
|
||||||
|
<title>{{This_Does_Not_Work}}</title>
|
||||||
|
: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` — Gets the title of the current HTML document.
|
||||||
|
* `setTitle( newTitle : string )` — 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 |
Loading…
Reference in New Issue