docs(ngmodule): updates for clarity; breaks out CoreModule

This commit is contained in:
Ward Bell 2016-08-23 00:17:18 -07:00
parent 0a45a47c73
commit fc2815ff6d
29 changed files with 818 additions and 289 deletions

View File

@ -517,13 +517,15 @@ function installExampleAngular() {
var sources;
var template;
var libs = [
'core', 'common', 'compiler',
'core', 'common', 'compiler', 'compiler-cli',
'platform-browser', 'platform-browser-dynamic',
'forms', 'http', 'router', 'upgrade'];
// Like: "angular/core-builds" or "@angular/core"
sources = libs.map( lib => argv.build ? `angular/${lib}-builds` : `@angular/${lib}`);
if (argv.build) { sources.push('@angular/tsc-wrapped');} // tsc-wrapped needed for builds
sources.push('@angular/router-deprecated');
gutil.log(`Installing Angular npm packages from ${argv.build ? 'BUILD' : 'RELEASE'}`);

View File

@ -71,7 +71,7 @@
"protractor": "^3.0.0",
"q": "^1.4.1",
"tree-kill": "^1.0.0",
"tslint": "^3.2.2",
"tslint": "^3.15.1",
"yargs": "^4.7.1"
},
"dependencies": {

View File

@ -6,6 +6,7 @@ describe('NgModule', function () {
const gold = 'rgba(255, 215, 0, 1)';
const powderblue = 'rgba(176, 224, 230, 1)';
const lightgray = 'rgba(211, 211, 211, 1)';
const white = 'rgba(0, 0, 0, 0)';
function getCommonsSectionStruct() {
const buttons = element.all(by.css('nav a'));
@ -55,7 +56,7 @@ describe('NgModule', function () {
}
// tests
function appTitleTests(color: string) {
function appTitleTests(color: string, name?: string) {
return function() {
it('should have a gray header', function() {
const commons = getCommonsSectionStruct();
@ -64,16 +65,16 @@ describe('NgModule', function () {
it('should welcome us', function () {
const commons = getCommonsSectionStruct();
expect(commons.subtitle.getText()).toBe('Welcome, Sam Spade');
expect(commons.subtitle.getText()).toBe('Welcome, ' + (name || 'Sherlock Holmes'));
});
};
}
function contactTests(color: string) {
function contactTests(color: string, name?: string) {
return function() {
it('shows the contact\'s owner', function() {
const contacts = getContactSectionStruct();
expect(contacts.header.getText()).toBe('Contact of Sam Spade');
expect(contacts.header.getText()).toBe('Contact of ' + (name || 'Sherlock Holmes'));
});
it('can cycle between contacts', function () {
@ -114,9 +115,9 @@ describe('NgModule', function () {
browser.get('');
});
describe('app-title', appTitleTests(lightgray));
describe('app-title', appTitleTests(white, 'Miss Marple'));
describe('contact', contactTests(lightgray));
describe('contact', contactTests(lightgray, 'Miss Marple'));
describe('crisis center', function () {
beforeEach(function () {
@ -149,7 +150,7 @@ describe('NgModule', function () {
it('shows a list of heroes', function() {
const heroes = getHeroesSectionStruct();
expect(heroes.header.getText()).toBe('Heroes of Sam Spade');
expect(heroes.header.getText()).toBe('Heroes of Miss Marple');
expect(heroes.title.getText()).toBe('Hero List');
expect(heroes.items.count()).toBe(6);
expect(heroes.items.get(0).getText()).toBe('11 - Mr. Nice');

View File

@ -11,8 +11,6 @@ import { UserService } from './user.service';
/* Feature Modules */
import { ContactModule } from './contact/contact.module.3';
import { routing } from './app.routing.3';
@NgModule({
@ -23,9 +21,8 @@ import { routing } from './app.routing.3';
routing
],
// #enddocregion imports
declarations: [ AppComponent, HighlightDirective, TitleComponent ],
providers: [ UserService ],
declarations: [ AppComponent, HighlightDirective, TitleComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }

View File

@ -1,29 +1,40 @@
// #docplaster
// #docregion
// #docregion v4
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
/* App Root */
import { AppComponent } from './app.component';
/* Feature Modules */
import { ContactModule } from './contact/contact.module';
import { SharedModule } from './shared/shared.module';
import { CoreModule } from './core/core.module';
import { routing } from './app.routing';
@NgModule({
// #docregion import-for-root
imports: [
BrowserModule,
ContactModule,
routing,
SharedModule.forRoot()
// #enddocregion v4
// #enddocregion
// #enddocregion import-for-root
/*
// #docregion v4
CoreModule,
// #enddocregion v4
*/
// #docregion import-for-root
// #docregion
CoreModule.forRoot({userName: 'Miss Marple'}),
// #docregion v4
routing
],
// #enddocregion import-for-root
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
// #enddocregion v4
// #enddocregion

View File

@ -1,9 +1,9 @@
// Exact copy except import UserService from shared
// Exact copy except import UserService from core
// #docregion
import { Component, OnInit } from '@angular/core';
import { Contact, ContactService } from './contact.service';
import { UserService } from '../shared/user.service';
import { UserService } from '../core/user.service';
@Component({
selector: 'app-contact',

View File

@ -15,7 +15,6 @@ import { routing } from './contact.routing.3';
@NgModule({
imports: [ CommonModule, FormsModule, routing ],
declarations: [ ContactComponent, HighlightDirective, AwesomePipe ],
providers: [ ContactService ]
})
export class ContactModule { }

View File

@ -1,7 +1,7 @@
import { ModuleWithProviders } from '@angular/core';
import { RouterModule } from '@angular/router';
import { RouterModule } from '@angular/router';
import { ContactComponent } from './contact.component.3';
import { ContactComponent } from './contact.component.3';
export const routing: ModuleWithProviders = RouterModule.forChild([
{ path: 'contact', component: ContactComponent}

View File

@ -1,7 +1,7 @@
import { ModuleWithProviders } from '@angular/core';
import { RouterModule } from '@angular/router';
import { RouterModule } from '@angular/router';
import { ContactComponent } from './contact.component';
import { ContactComponent } from './contact.component';
// #docregion routing
export const routing: ModuleWithProviders = RouterModule.forChild([

View File

@ -0,0 +1,48 @@
/* tslint:disable:member-ordering no-unused-variable */
// #docplaster
// #docregion
// #docregion v4
import {
BaseException, ModuleWithProviders,
NgModule, Optional, SkipSelf } from '@angular/core';
import { CommonModule } from '@angular/common';
import { TitleComponent } from './title.component';
import { UserService } from './user.service';
// #enddocregion
import { UserServiceConfig } from './user.service';
// #docregion v4
@NgModule({
imports: [ CommonModule ],
declarations: [ TitleComponent ],
exports: [ TitleComponent ],
providers: [ UserService ]
})
export class CoreModule {
// #enddocregion v4
// #docregion ctor
constructor (@Optional() @SkipSelf() parentModule: CoreModule) {
if (parentModule) {
throw new BaseException(
'CoreModule is already loaded. Import it in the AppModule only');
}
}
// #enddocregion ctor
// #docregion for-root
static forRoot(config: UserServiceConfig): ModuleWithProviders {
return {
ngModule: CoreModule,
providers: [
{provide: UserServiceConfig, useValue: config }
]
};
}
// #enddocregion for-root
// #docregion v4
}
// #enddocregion v4
// #enddocregion

View File

@ -1,4 +1,4 @@
<!-- Exact copy from app.component.html -->
<!-- Exact copy from earlier app.component.html -->
<h1 highlight>{{title}} {{subtitle}}</h1>
<p *ngIf="user">
<i>Welcome, {{user}}</i>

View File

@ -1,10 +1,10 @@
// Exact copy of app/title.component.ts except import UserService from shared
import { Component, Input } from '@angular/core';
import { UserService } from './user.service';
import { UserService } from '../core/user.service';
@Component({
selector: 'app-title',
templateUrl: 'app/shared/title.component.html',
templateUrl: 'app/core/title.component.html',
})
export class TitleComponent {
@Input() subtitle = '';

View File

@ -0,0 +1,32 @@
// Crazy copy of the app/user.service
// Proves that UserService is an app-wide singleton and only instantiated once
// IFF shared.module follows the `forRoot` pattern
//
// If it didn't, a new instance of UserService would be created
// after each lazy load and the userName would double up.
import { Injectable, Optional } from '@angular/core';
let nextId = 1;
export class UserServiceConfig {
userName = 'Philip Marlowe';
}
@Injectable()
export class UserService {
id = nextId++;
private _userName = 'Sherlock Holmes';
// #docregion ctor
constructor(@Optional() config: UserServiceConfig) {
if (config) { this._userName = config.userName; }
}
// #enddocregion ctor
get userName() {
// Demo: add a suffix if this service has been created more than once
const suffix = this.id > 1 ? ` times ${this.id}` : '';
return this._userName + suffix;
}
}

View File

@ -1,5 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
template: `

View File

@ -1,6 +1,6 @@
import { ModuleWithProviders } from '@angular/core';
import { Routes,
RouterModule } from '@angular/router';
RouterModule } from '@angular/router';
import { CrisisListComponent } from './crisis-list.component';
import { CrisisDetailComponent } from './crisis-detail.component';

View File

@ -1,8 +1,8 @@
// Exact copy except import UserService from shared
// Exact copy except import UserService from core
import { Component } from '@angular/core';
import { HeroService } from './hero.service';
import { UserService } from '../shared/user.service';
import { UserService } from '../core/user.service';
@Component({
template: `

View File

@ -1,12 +1,12 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { HeroComponent } from './hero.component.3';
import { HeroDetailComponent } from './hero-detail.component';
import { HeroListComponent } from './hero-list.component';
import { HighlightDirective } from './highlight.directive';
import { routing } from './hero.routing.3';
import { HeroComponent } from './hero.component.3';
import { HeroDetailComponent } from './hero-detail.component';
import { HeroListComponent } from './hero-list.component';
import { HighlightDirective } from './highlight.directive';
import { routing } from './hero.routing.3';
// #docregion class
@NgModule({

View File

@ -1,11 +1,11 @@
import { NgModule } from '@angular/core';
import { NgModule } from '@angular/core';
import { SharedModule } from '../shared/shared.module';
import { SharedModule } from '../shared/shared.module';
import { HeroComponent } from './hero.component';
import { HeroDetailComponent } from './hero-detail.component';
import { HeroListComponent } from './hero-list.component';
import { routing } from './hero.routing';
import { HeroComponent } from './hero.component';
import { HeroDetailComponent } from './hero-detail.component';
import { HeroListComponent } from './hero-list.component';
import { routing } from './hero.routing';
/*
* TODO: Remove THE HeroService class and provider after

View File

@ -1,10 +1,10 @@
import { ModuleWithProviders } from '@angular/core';
import { Routes,
RouterModule } from '@angular/router';
RouterModule } from '@angular/router';
import { HeroComponent } from './hero.component.3';
import { HeroListComponent } from './hero-list.component';
import { HeroDetailComponent } from './hero-detail.component';
import { HeroComponent } from './hero.component.3';
import { HeroListComponent } from './hero-list.component';
import { HeroDetailComponent } from './hero-detail.component';
const routes: Routes = [
{ path: '',

View File

@ -1,10 +1,10 @@
import { ModuleWithProviders } from '@angular/core';
import { Routes,
RouterModule } from '@angular/router';
RouterModule } from '@angular/router';
import { HeroComponent } from './hero.component';
import { HeroListComponent } from './hero-list.component';
import { HeroDetailComponent } from './hero-detail.component';
import { HeroComponent } from './hero.component';
import { HeroListComponent } from './hero-list.component';
import { HeroDetailComponent } from './hero-detail.component';
const routes: Routes = [
{ path: '',

View File

@ -1,40 +1,18 @@
// #docregion
import { NgModule,
ModuleWithProviders } from '@angular/core';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { AwesomePipe } from './awesome.pipe';
import { HighlightDirective } from './highlight.directive';
import { TitleComponent } from './title.component';
import { UserService } from './user.service';
// #docregion shared-module
// #docregion module
@NgModule({
imports: [ CommonModule ],
declarations: [ AwesomePipe, HighlightDirective, TitleComponent ],
exports: [ AwesomePipe, HighlightDirective, TitleComponent,
declarations: [ AwesomePipe, HighlightDirective ],
exports: [ AwesomePipe, HighlightDirective,
CommonModule, FormsModule ]
})
export class SharedModule {
// #docregion for-root
static forRoot(): ModuleWithProviders {
return {
ngModule: SharedModule,
providers: [ UserService ]
};
}
// #enddocregion for-root
}
// #enddocregion shared-module
export class SharedModule { }
// #enddocregion module
// #enddocregion
// #docregion shared-root-module
@NgModule({
exports: [ SharedModule ],
providers: [ UserService ]
})
export class SharedRootModule { }
// #enddocregion shared-root-module

View File

@ -1,20 +0,0 @@
// Crazy copy of the app/user.service
// Proves that UserService is an app-wide singleton and only instantiated once
// IFF shared.module follows the `forRoot` pattern
//
// If it didn't, a new instance of UserService would be created
// after each lazy load and the userName would double up.
import { Injectable } from '@angular/core';
@Injectable()
export class UserService {
static userName = '';
constructor() {
UserService.userName += UserService.userName || 'Sam Spade';
}
get userName() { return UserService.userName; }
}

View File

@ -4,5 +4,5 @@ import { Injectable } from '@angular/core';
@Injectable()
/** Dummy version of an authenticated user service */
export class UserService {
userName = 'Sam Spade';
userName = 'Sherlock Holmes';
}

View File

@ -22,6 +22,10 @@
"!app/hero/hero.routing.3.ts",
"!app/hero/highlight.directive.ts",
"app/core/*.css",
"app/core/*.html",
"app/core/*.ts",
"app/shared/*.css",
"app/shared/*.html",
"app/shared/*.ts",

View File

@ -27,6 +27,7 @@
"dependencies": {
"@angular/common": "2.0.0-rc.5",
"@angular/compiler": "2.0.0-rc.5",
"@angular/compiler-cli": "0.5.0",
"@angular/core": "2.0.0-rc.5",
"@angular/forms": "0.3.0",
"@angular/http": "2.0.0-rc.5",
@ -47,7 +48,7 @@
"angular-cli": "^1.0.0-beta.5",
"angular2-template-loader": "^0.4.0",
"canonical-path": "0.0.2",
"concurrently": "^2.1.0",
"concurrently": "^2.2.0",
"css-loader": "^0.23.1",
"extract-text-webpack-plugin": "^1.0.1",
"file-loader": "^0.8.5",
@ -63,7 +64,7 @@
"karma-phantomjs-launcher": "^1.0.0",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^1.7.0",
"lite-server": "^2.2.0",
"lite-server": "^2.2.2",
"lodash": "^4.13.1",
"null-loader": "^0.1.1",
"phantomjs-prebuilt": "^2.1.7",
@ -73,9 +74,9 @@
"style-loader": "^0.13.1",
"ts-loader": "^0.8.2",
"ts-node": "^0.7.3",
"tslint": "^3.13.0",
"tslint": "^3.15.1",
"typescript": "^1.8.10",
"typings": "^1.0.4",
"typings": "^1.3.2",
"webpack": "^1.13.0",
"webpack-dev-server": "^1.14.1",
"webpack-merge": "^0.14.0"

View File

@ -13,28 +13,28 @@
"dependencies": {
"@angular/common": "2.0.0-rc.5",
"@angular/compiler": "2.0.0-rc.5",
"@angular/compiler-cli": "0.5.0",
"@angular/core": "2.0.0-rc.5",
"@angular/forms": "0.3.0",
"@angular/http": "2.0.0-rc.5",
"@angular/platform-browser": "2.0.0-rc.5",
"@angular/platform-browser-dynamic": "2.0.0-rc.5",
"@angular/router": "3.0.0-rc.1",
"@angular/router-deprecated": "2.0.0-rc.2",
"@angular/upgrade": "2.0.0-rc.5",
"systemjs": "0.19.27",
"core-js": "^2.4.0",
"reflect-metadata": "^0.1.3",
"rxjs": "5.0.0-beta.6",
"systemjs": "0.19.27",
"zone.js": "^0.6.12",
"angular2-in-memory-web-api": "0.0.15",
"angular2-in-memory-web-api": "0.0.17",
"bootstrap": "^3.3.6"
},
"devDependencies": {
"concurrently": "^2.0.0",
"lite-server": "^2.2.0",
"concurrently": "^2.2.0",
"lite-server": "^2.2.2",
"typescript": "^1.8.10",
"typings":"^1.0.4"
"typings":"^1.3.2"
}
}

View File

@ -40,7 +40,7 @@
// Bundled (~40 requests):
function packUmd(pkgName) {
packages['@angular/'+pkgName] = { main: 'bundles/' + pkgName + '.umd.js', defaultExtension: 'js' };
packages['@angular/'+pkgName] = { main: 'bundles/' + pkgName + '.umd.js' };
}
// Most environments should use UMD; some (Karma) need the individual index files

View File

@ -51,7 +51,7 @@
ngPackageNames.concat(['forms', 'router', 'router-deprecated']).forEach(function(pkgName) {
// Bundled (~40 requests):
packages['@angular/'+pkgName] = { main: '/bundles/' + pkgName + '.umd.js', defaultExtension: 'js' };
packages['@angular/'+pkgName] = { main: '/bundles/' + pkgName + '.umd.js' };
// Individual files (~300 requests):
//packages['@angular/'+pkgName] = { main: 'index.js', defaultExtension: 'js' };

File diff suppressed because it is too large Load Diff