docs(QuickStart): incorporate misko's suggestions/corrections
closes #502
This commit is contained in:
parent
8e8963270b
commit
bc74ee4ac3
|
@ -9,4 +9,6 @@ import {Component} from 'angular2/core';
|
||||||
template: '<h1>My First Angular 2 App</h1>'
|
template: '<h1>My First Angular 2 App</h1>'
|
||||||
})
|
})
|
||||||
// #enddocregion metadata
|
// #enddocregion metadata
|
||||||
|
// #docregion export
|
||||||
export class AppComponent { }
|
export class AppComponent { }
|
||||||
|
// #enddocregion export
|
|
@ -9,7 +9,7 @@
|
||||||
},
|
},
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"angular2": "2.0.0-alpha.52",
|
"angular2": "2.0.0-alpha.53",
|
||||||
"systemjs": "0.19.6",
|
"systemjs": "0.19.6",
|
||||||
"es6-promise": "^3.0.2",
|
"es6-promise": "^3.0.2",
|
||||||
"es6-shim": "^0.33.3",
|
"es6-shim": "^0.33.3",
|
||||||
|
|
|
@ -39,7 +39,7 @@ code-example(format="").
|
||||||
Let's follow a process that's closer to what we'd do in real life.
|
Let's follow a process that's closer to what we'd do in real life.
|
||||||
|
|
||||||
1. Set up our development environment
|
1. Set up our development environment
|
||||||
1. Write the Angular root component for our main app
|
1. Write the Angular root component for our app
|
||||||
1. Bootstrap it to take control of the main web page
|
1. Bootstrap it to take control of the main web page
|
||||||
1. Write the main page (`index.html`)
|
1. Write the main page (`index.html`)
|
||||||
|
|
||||||
|
@ -127,48 +127,53 @@ code-example(format="").
|
||||||
### Add the component file
|
### Add the component file
|
||||||
Now add a file named **app.component.ts** and paste the following lines:
|
Now add a file named **app.component.ts** and paste the following lines:
|
||||||
+makeExample('quickstart/ts/app/app.component.ts', null, 'app/app.component.ts')(format=".")
|
+makeExample('quickstart/ts/app/app.component.ts', null, 'app/app.component.ts')(format=".")
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
|
Let's review this file in detail, starting at the bottom where we define a class.
|
||||||
|
|
||||||
### The Component class
|
### The Component class
|
||||||
At the bottom of the file is an empty, do-nothing class named `AppComponent`.
|
At the bottom of the file is an empty, do-nothing class named `AppComponent`.
|
||||||
When we're ready to build a substantive application,
|
When we're ready to build a substantive application,
|
||||||
we can expand this class with properties and application logic.
|
we can expand this class with properties and application logic.
|
||||||
Our `AppComponent` class is empty because we don't need it to do anything in this QuickStart.
|
Our `AppComponent` class is empty because we don't need it to do anything in this QuickStart.
|
||||||
|
|
||||||
We do **export** the `AppComponent` class. Our component is a module.
|
|
||||||
Another part of the application will import our module and put it to work.
|
|
||||||
|
|
||||||
### Modules
|
### Modules
|
||||||
Angular apps are modular. They consist of many files each dedicated to a purpose.
|
Angular apps are modular. They consist of many files each dedicated to a purpose.
|
||||||
Our `app.component` file is both the home and the name of the module that
|
|
||||||
provides the application's root component — its top level component.
|
Most application files *export* one thing such as a component.
|
||||||
|
Our `app.component` file exports the `AppComponent`.
|
||||||
|
+makeExample('quickstart/ts/app/app.component.ts', 'export', 'app/component.ts (export)')(format=".")
|
||||||
|
:marked
|
||||||
|
The act of exporting turns the file into a module.
|
||||||
|
The name of the file (without extension) is usually the name of the module.
|
||||||
|
Accordingly, '*app.component*' is the name of our first module.
|
||||||
|
|
||||||
A more sophisticated application would have child components that descended from
|
A more sophisticated application would have child components that descended from
|
||||||
`AppComponent` in a visual tree.
|
`AppComponent` in a visual tree.
|
||||||
|
A more sophisticated app would have more files and modules, at least as many as it had components.
|
||||||
|
|
||||||
Quickstart isn't sophisticated; one component is all we need.
|
Quickstart isn't sophisticated; one component is all we need.
|
||||||
Yet modules play a fundamental organizational role in even this small app.
|
Yet modules play a fundamental organizational role in even this small app.
|
||||||
|
|
||||||
Modules rely on other modules. In TypeScript Angular apps, when we need something
|
Modules rely on other modules. In TypeScript Angular apps, when we need something
|
||||||
provided by another module, we import it.
|
provided by another module, we import it.
|
||||||
|
When another module needs to refer to `AppComponent`, it imports the `AppComponent` *symbol* like this:
|
||||||
Angular is a collection of library modules.
|
+makeExample('quickstart/ts/app/boot.ts', 'app-component','app/boot.ts (import)')(format=".")
|
||||||
Each library is a module made up of several, related feature modules.
|
|
||||||
|
|
||||||
The `angular2/core` library is the primary module and we need something from it.
|
|
||||||
We need the `Component`function.
|
|
||||||
|
|
||||||
When we want something from a module, we `import` it.
|
|
||||||
We begin by importing the `Component` symbol from Angular.
|
|
||||||
+makeExample('quickstart/ts/app/app.component.ts', 'import')(format=".")
|
|
||||||
:marked
|
:marked
|
||||||
Then we use it to define metadata about the `AppComponent`
|
Angular is also modular. It is a collection of library modules.
|
||||||
|
Each library is itself a module made up of several, related feature modules.
|
||||||
|
|
||||||
|
When we need something from Angular, we import it from an Angular library module.
|
||||||
|
We need something from Angular right now to help us define metadata about our component.
|
||||||
|
|
||||||
### Component Metadata
|
### Component Metadata
|
||||||
A class becomes an Angular component when we give it metadata.
|
A class becomes an Angular component when we give it metadata.
|
||||||
Angular needs the metadata to understand how to construct the view
|
Angular needs the metadata to understand how to construct the view
|
||||||
and how the component interacts with other parts of the application.
|
and how the component interacts with other parts of the application.
|
||||||
|
|
||||||
We define a component's metadata with the `Component` function.
|
We define a component's metadata with the Angular `Component` function.
|
||||||
|
We access that function by importing it from the primary Angular library,`angular2/core`.
|
||||||
|
+makeExample('quickstart/ts/app/app.component.ts', 'import', 'app/component.ts (import)')(format=".")
|
||||||
|
:marked
|
||||||
In TypeScript we apply that function to the class as a *decorator*
|
In TypeScript we apply that function to the class as a *decorator*
|
||||||
by prefixing it with the **@** symbol and invoking it
|
by prefixing it with the **@** symbol and invoking it
|
||||||
just above the component class:
|
just above the component class:
|
||||||
|
@ -178,7 +183,7 @@ code-example(format="").
|
||||||
The configuration object passed to the `@Component` method has two
|
The configuration object passed to the `@Component` method has two
|
||||||
fields, a `selector` and a `template`.
|
fields, a `selector` and a `template`.
|
||||||
|
|
||||||
The `selector` specifies a CSS selector for a host HTML element named `my-app`.
|
The `selector` specifies a simple CSS selector for a host HTML element named `my-app`.
|
||||||
Angular creates and displays an instance of our `AppComponent`
|
Angular creates and displays an instance of our `AppComponent`
|
||||||
wherever it encounters a `my-app` element in the host HTML.
|
wherever it encounters a `my-app` element in the host HTML.
|
||||||
|
|
||||||
|
@ -206,14 +211,8 @@ code-example(format="").
|
||||||
|
|
||||||
.l-sub-section
|
.l-sub-section
|
||||||
:marked
|
:marked
|
||||||
### bootstrapping is platform-specific
|
Learn why we import `bootstrap` from `angular2/platform/browser`
|
||||||
Note that `bootstrap` function comes from a *different library*, `angular2/platform/browser`.
|
and why we create a separate *boot.ts* file in the [appendex below](#boot).
|
||||||
Most Angular applications run only in a browser and we'll call the bootstrap function from
|
|
||||||
this library most of the time.
|
|
||||||
|
|
||||||
It is possible to load a component in a different enviroment such as we might do
|
|
||||||
if we wished to render the first page of our application on the server.
|
|
||||||
That would require a different kind of bootstrap function.
|
|
||||||
:marked
|
:marked
|
||||||
We've asked Angular to launch the app in a browser with our component at the root.
|
We've asked Angular to launch the app in a browser with our component at the root.
|
||||||
Where will Angular put it?
|
Where will Angular put it?
|
||||||
|
@ -232,7 +231,7 @@ code-example(format="").
|
||||||
cd ..
|
cd ..
|
||||||
:marked
|
:marked
|
||||||
Now create the`index.html` file and paste the following lines:
|
Now create the`index.html` file and paste the following lines:
|
||||||
+makeExample('quickstart/ts/index.html', null, 'index.html')
|
+makeExample('quickstart/ts/index.html', null, 'index.html')(format=".")
|
||||||
:marked
|
:marked
|
||||||
There are three noteworthy sections of HTML:
|
There are three noteworthy sections of HTML:
|
||||||
|
|
||||||
|
@ -311,7 +310,7 @@ code-example(format="").
|
||||||
quickstart/ts/app/boot.ts,
|
quickstart/ts/app/boot.ts,
|
||||||
quickstart/ts/index.html,
|
quickstart/ts/index.html,
|
||||||
quickstart/ts/package.1.json,
|
quickstart/ts/package.1.json,
|
||||||
quickstart/ts/tsconfig.json
|
quickstart/ts/tsconfig.1.json
|
||||||
`,null,
|
`,null,
|
||||||
`app/app.component.ts, app/boot.ts, index.html,package.json, tsconfig.json`)
|
`app/app.component.ts, app/boot.ts, index.html,package.json, tsconfig.json`)
|
||||||
:marked
|
:marked
|
||||||
|
@ -345,6 +344,20 @@ code-example(format="").
|
||||||
|
|
||||||
There is no essential material here. Continued reading is for the curious.
|
There is no essential material here. Continued reading is for the curious.
|
||||||
|
|
||||||
|
.l-main-section
|
||||||
|
:marked
|
||||||
|
<a id="es6support"></a>
|
||||||
|
### Appendix: Browser ES6 support
|
||||||
|
Angular 2 relies on some ES2015 features, most of them found in modern
|
||||||
|
browsers. Some browsers (including IE 11) require a shim to support the
|
||||||
|
the needed functionality.
|
||||||
|
Try loading the following shim *above* the other scripts in the `index.html`:
|
||||||
|
|
||||||
|
code-example(language="html" format=".").
|
||||||
|
<script src="node_modules/es6-shim/es6-shim.js"></script>
|
||||||
|
:marked
|
||||||
|
|
||||||
|
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
<a id="package-json"></a>
|
<a id="package-json"></a>
|
||||||
|
@ -387,6 +400,7 @@ code-example(format="").
|
||||||
a light-weight, static file server, written and maintained by [John Papa](http://johnpapa.net/)
|
a light-weight, static file server, written and maintained by [John Papa](http://johnpapa.net/)
|
||||||
with excellent support for Angular apps that use routing.
|
with excellent support for Angular apps that use routing.
|
||||||
|
|
||||||
|
|
||||||
<!-- Move this to the Style Guide when we have one -->
|
<!-- Move this to the Style Guide when we have one -->
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
|
@ -447,7 +461,7 @@ code-example(format="").
|
||||||
:marked
|
:marked
|
||||||
Learn more about SystemJS configuration [here](https://github.com/systemjs/systemjs/blob/master/docs/config-api.md).
|
Learn more about SystemJS configuration [here](https://github.com/systemjs/systemjs/blob/master/docs/config-api.md).
|
||||||
:marked
|
:marked
|
||||||
With those caustions in mind, what are we doing here?
|
With those cautions in mind, what are we doing here?
|
||||||
+makeExample('quickstart/ts/index.html', 'systemjs', 'index.html (System configuration')(format=".")
|
+makeExample('quickstart/ts/index.html', 'systemjs', 'index.html (System configuration')(format=".")
|
||||||
:marked
|
:marked
|
||||||
The `packages:` line tells SystemJS what to do when it sees a request for a
|
The `packages:` line tells SystemJS what to do when it sees a request for a
|
||||||
|
@ -492,12 +506,75 @@ code-example(format="").
|
||||||
|
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
<a id="es6support"></a>
|
<a id="boot"></a>
|
||||||
### Appendix: Browser ES6 support
|
### Appendix: ***boot.ts***
|
||||||
Angular 2 relies on some ES2015 features, most of them found in modern
|
|
||||||
browsers. Some browsers (including IE 11) require a shim to support the
|
|
||||||
the needed functionality.
|
|
||||||
Try loading the following shim *above* the other scripts in the `index.html`:
|
|
||||||
|
|
||||||
code-example(language="html" format=".").
|
#### Bootstrapping is platform-specific
|
||||||
<script src="node_modules/es6-shim/es6-shim.js"></script>
|
We import the `bootstrap` function from `angular2/platform/browser`,
|
||||||
|
not `angular2/core`. There's a good reason.
|
||||||
|
|
||||||
|
We only call "core" those capabilities that are the same across all platform targets.
|
||||||
|
True, most Angular applications run only in a browser and we'll call the bootstrap function from
|
||||||
|
this library most of the time. It's pretty "core" if we're always writing for a browser.
|
||||||
|
|
||||||
|
But it is possible to load a component in a different enviroment.
|
||||||
|
We might load it on a mobile device with [Apache Cordova](https://cordova.apache.org/)
|
||||||
|
We might wish to render the first page of our application on the server
|
||||||
|
to improve launch performance or facilitate
|
||||||
|
[SEO](http://static.googleusercontent.com/media/www.google.com/en//webmasters/docs/search-engine-optimization-starter-guide.pdf).
|
||||||
|
|
||||||
|
These targes require a different kind of bootstrap function that we'd import from a different library.
|
||||||
|
|
||||||
|
|
||||||
|
#### Why do we create a separate ***boot.ts*** file?
|
||||||
|
|
||||||
|
The *boot.ts* file is tiny. This is just a QuickStart.
|
||||||
|
We could have folded its few lines into the `app.component` file
|
||||||
|
and spared ourselves some complexity.
|
||||||
|
|
||||||
|
We didn't for what we believe to be good reasons:
|
||||||
|
1. Doing it right is easy
|
||||||
|
1. Testability
|
||||||
|
1. Reusability
|
||||||
|
1. Separation of concerns
|
||||||
|
1. We learned about import and export
|
||||||
|
|
||||||
|
#### It's easy
|
||||||
|
Sure it's an extra step and an extra file. How hard is that in the scheme of things?
|
||||||
|
|
||||||
|
We'll see that a separate `boot.ts` is beneficial for *most* apps
|
||||||
|
even if it isn't critical for the QuickStart.
|
||||||
|
Let's develop good habits now while the cost is low.
|
||||||
|
|
||||||
|
#### Testability
|
||||||
|
We should be thinking about testability from the beginning
|
||||||
|
even if we know we'll never test the QuickStart.
|
||||||
|
|
||||||
|
It is difficult to unit test a component when there is a call to `bootstrap` in the same file.
|
||||||
|
As soon as we load the component file to test the component,
|
||||||
|
the `bootstrap` function tries to load the application in the browser.
|
||||||
|
It throws an error because we're not expecting to run the entire application,
|
||||||
|
just test the component.
|
||||||
|
|
||||||
|
Relocating the `bootstrap` function to `boot.ts` eliminates this spurious error
|
||||||
|
and leaves us with a clean component module file.
|
||||||
|
|
||||||
|
#### Reusability
|
||||||
|
We refactor, rename, and relocate files as our application evolves.
|
||||||
|
We can't do any of those things while the file calls `bootstrap`.
|
||||||
|
we can't move it.
|
||||||
|
We can't reuse the component in another application.
|
||||||
|
We can't pre-render the component on the server for better performance.
|
||||||
|
|
||||||
|
#### Separation of concerns
|
||||||
|
A component's responsibility is to present and manage a view.
|
||||||
|
|
||||||
|
Launching the application has nothing to do with view management.
|
||||||
|
That's a separate concern. The friction we're encountering in testing and reuse
|
||||||
|
stems from this unnecessary mix of responsibilities.
|
||||||
|
|
||||||
|
#### Import/Export
|
||||||
|
|
||||||
|
While writing a separate `boot.ts` file we learned an essential Angular skill:
|
||||||
|
how to export from one module and import into another.
|
||||||
|
We'll do a lot of that as we learn more Angular.
|
|
@ -40,22 +40,22 @@ var _rxData = [
|
||||||
{
|
{
|
||||||
pattern: 'script',
|
pattern: 'script',
|
||||||
from: 'node_modules/angular2/bundles/angular2.dev.js',
|
from: 'node_modules/angular2/bundles/angular2.dev.js',
|
||||||
to: 'https://code.angularjs.org/2.0.0-alpha.52/angular2.dev.js'
|
to: 'https://code.angularjs.org/2.0.0-alpha.53/angular2.dev.js'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: 'script',
|
pattern: 'script',
|
||||||
from: 'node_modules/angular2/bundles/router.dev.js',
|
from: 'node_modules/angular2/bundles/router.dev.js',
|
||||||
to: 'https://code.angularjs.org/2.0.0-alpha.52/router.dev.js'
|
to: 'https://code.angularjs.org/2.0.0-alpha.53/router.dev.js'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: 'script',
|
pattern: 'script',
|
||||||
from: 'node_modules/angular2/bundles/http.dev.js',
|
from: 'node_modules/angular2/bundles/http.dev.js',
|
||||||
to: 'https://code.angularjs.org/2.0.0-alpha.52/http.dev.js'
|
to: 'https://code.angularjs.org/2.0.0-alpha.53/http.dev.js'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: 'script',
|
pattern: 'script',
|
||||||
from: 'node_modules/angular2/bundles/testing.js',
|
from: 'node_modules/angular2/bundles/testing.js',
|
||||||
to: 'https://code.angularjs.org/2.0.0-alpha.52/testing.js'
|
to: 'https://code.angularjs.org/2.0.0-alpha.53/testing.js'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: 'link',
|
pattern: 'link',
|
||||||
|
|
|
@ -95,7 +95,14 @@ function initConfigAndCollectFileNames(configFileName) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// var defaultExcludes = [ '!**/node_modules/**','!**/typings/**','!**/tsconfig.json', '!**/*plnkr.json', '!**/*plnkr.html', '!**/*plnkr.no-link.html' ];
|
// var defaultExcludes = [ '!**/node_modules/**','!**/typings/**','!**/tsconfig.json', '!**/*plnkr.json', '!**/*plnkr.html', '!**/*plnkr.no-link.html' ];
|
||||||
var defaultExcludes = [ '!**/typings/**','!**/tsconfig.json', '!**/*plnkr.json', '!**/*plnkr.html', '!**/*plnkr.no-link.html', '!**/package.json', '!**/example-config.json' ];
|
var defaultExcludes = [
|
||||||
|
'!**/typings/**',
|
||||||
|
'!**/tsconfig.json',
|
||||||
|
'!**/*plnkr.*',
|
||||||
|
'!**/package.json',
|
||||||
|
'!**/example-config.json',
|
||||||
|
'!**/*.spec.*'
|
||||||
|
];
|
||||||
Array.prototype.push.apply(gpaths, defaultExcludes);
|
Array.prototype.push.apply(gpaths, defaultExcludes);
|
||||||
|
|
||||||
config.fileNames = globby.sync(gpaths, { ignore: ["**/node_modules/**"] });
|
config.fileNames = globby.sync(gpaths, { ignore: ["**/node_modules/**"] });
|
||||||
|
|
Loading…
Reference in New Issue