RouterModule
@angular/forms
@angular/router
RouterLink
,.forRoot()
, and .forChild()
HttpModule
@angular/http
HttpClientModule
@angular/common/http
- Property - | ++ Property + | -- Description - | ++ Description + | -
---|---|---|---|
- declarations
- |
+
+ declarations
+ |
- + |
+ A list of [declarable](guide/ngmodule-faq#q-declarable) classes,
+ (*components*, *directives*, and *pipes*) that _belong to this module_.
- A list of [declarable](guide/ngmodule-faq#q-declarable) classes,
- (*components*, *directives*, and *pipes*) that _belong to this module_.
+
|
- Don't re-declare a class imported from another module.
+
+ providers
+ |
- |||
- |
- providers
- |
+ A list of dependency-injection providers.
- + Angular registers these providers with the NgModule's injector. + If it is the NgModule used for bootstrapping then it is the root injector. + These services become available for injection into any component, directive, pipe or service which is a child of this injector. - A list of dependency-injection providers. + A lazy-loaded module has its own injector which + is typically a child of the application root injector. - Angular registers these providers with the NgModule's injector. - If it is the NgModule used for bootstrapping that it is the root injector. + Lazy-loaded services are scoped to the lazy module's injector. + If a lazy-loaded module also provides the `UserService`, + any component created within that module's context (such as by router navigation) + gets the local instance of the service, not the instance in the root application injector. - These services become available for injection into any component, directive, pipe or service which is a child of this injector. + Components in external modules continue to receive the instance provided by their injectors. - A lazy-loaded module has its own injector which - is typically a child of the application root injector. + For more information on injector hierarchy and scoping, see [Providers](guide/providers). - Lazy-loaded services are scoped to the lazy module's injector. - If a lazy-loaded module also provides the `UserService`, - any component created within that module's context (such as by router navigation) - gets the local instance of the service, not the instance in the root application injector. + | - Components in external modules continue to receive the instance provided by their injectors. +|
+ imports
+ |
- - | ||
- imports
- |
+ Specifically, it is as if the list of modules whose exported components, directives, or pipes
+ are referenced by the component templates were declared in this module.
- + A component template can [reference](guide/ngmodule-faq#q-template-reference) another component, directive, or pipe + when the reference is declared in this module or if the imported module has exported it. + For example, a component can use the `NgIf` and `NgFor` directives only if the + module has imported the Angular `CommonModule` (perhaps indirectly by importing `BrowserModule`). + You can import many standard directives from the `CommonModule` + but some familiar directives belong to other modules. + For example, you can use `[(ngModel)]` only + after importing the Angular `FormsModule`. - A list of modules which should be folded into this module. Folded means it is - as if all of the imported NgModule properties were declared here. + | - Specifically, it is as if the list of modules whose exported components, directives, or pipes - are referenced by the component templates were declared in this module. +||
+ exports
+ |
- - | ||
- exports
- |
+ Exported declarations are the module's _public API_.
+ A component in another module can [use](guide/ngmodule-faq#q-template-reference) _this_
+ module's `UserComponent` if it imports this module and this module exports `UserComponent`.
- + Declarations are private by default. + If this module does _not_ export `UserComponent`, then only the components within _this_ + module can use `UserComponent`. + Importing a module does _not_ automatically re-export the imported module's imports. + Module 'B' can't use `ngIf` just because it imported module 'A' which imported `CommonModule`. + Module 'B' must import `CommonModule` itself. - A list of declarations—*component*, *directive*, and *pipe* classes—that - an importing module can use. + A module can list another module among its `exports`, in which case + all of that module's public components, directives, and pipes are exported. - Exported declarations are the module's _public API_. - A component in another module can [use](guide/ngmodule-faq#q-template-reference) _this_ module's `UserComponent` - if it imports this module and this module exports `UserComponent`. + [Re-export](guide/ngmodule-faq#q-reexport) makes module transitivity explicit. + If Module 'A' re-exports `CommonModule` and Module 'B' imports Module 'A', + Module 'B' components can use `ngIf` even though 'B' itself didn't import `CommonModule`. - Declarations are private by default. - If this module does _not_ export `UserComponent`, than only the components within where the `UserComponent` has been declared can use `UserComponent. + | - Importing a module does _not_ automatically re-export the imported module's imports. - Module 'B' can't use `ngIf` just because it imported module `A` which imported `CommonModule`. - Module 'B' must import `CommonModule` itself. +||
+ bootstrap
+ |
-
+ - | ||
- bootstrap
- |
+ Angular can launch with multiple bootstrap components,
+ each with its own location in the host web page.
- + A bootstrap component is automatically added to `entryComponents`. + | - A list of components that are automatically bootstrapped. +||
+ entryComponents
+ |
- A bootstrap component is automatically added to `entryComponents`.
+ - | + A list of components that can be dynamically loaded into the view. -||
- entryComponents
- |
+ While the bootstrapped and routed components are _entry components_,
+ you don't have to add them to a module's `entryComponents` list,
+ as they are added implicitly.
-
+ Angular automatically adds components in the module's `bootstrap` and route definitions into the `entryComponents` list.
+ That leaves only components bootstrapped using one of the imperative techniques, such as [`ViewComponentRef.createComponent()`](https://angular.io/api/core/ViewContainerRef#createComponent) as undiscoverable.
- A list of components that can be dynamically loaded into the view.
+ Dynamic component loading is not common in most apps beyond the router. If you need to dynamically load components, you must add these components to the `entryComponents` list yourself.
- By default, an Angular app always has at least one entry component, the root component, `AppComponent`. Its purpose is to serve as a point of entry into the app, that is, you bootstrap it to launch the app.
+ For more information, see [Entry Components](guide/entry-components).
- Routed components are also _entry components_ because they need to be loaded dynamically.
- The router creates them and drops them into the DOM near a ` |
- While the bootstrapped and routed components are _entry components_,
- you don't have to add them to a module's `entryComponents` list,
- as they are added implicitly.
-
- Angular automatically adds components in the module's `bootstrap` and route definitions into the `entryComponents` list.
-
-That leaves only components bootstrapped using one of the imperative techniques, such as [`ViewComponentRef.createComponent()`](https://angular.io/api/core/ViewContainerRef#createComponent) as undiscoverable.
-
- Dynamic component loading is not common in most apps beyond the router. If you need to dynamically load components, you must add these components to the `entryComponents` list yourself.
-
- For more information, see [Entry Components](guide/entry-components).
-
-
-
A quick look at an Angular "hello world" application.
diff --git a/aio/content/marketing/resources.json b/aio/content/marketing/resources.json index 6bdade4814296..dfe3e7e8729a4 100644 --- a/aio/content/marketing/resources.json +++ b/aio/content/marketing/resources.json @@ -10,6 +10,12 @@ "rev": true, "title": "Catalog of Angular Components & Libraries", "url": "https://github.com/brillout/awesome-angular-components" + }, + "angular-ru": { + "desc": "Angular-RU Community on GitHub is a single entry point for all resources, chats, podcasts and meetups for Angular in Russia.", + "rev": true, + "title": "Angular Conferences and Angular Camps in Moscow, Russia.", + "url": "https://angular-ru.github.io/" } } }, diff --git a/aio/content/marketing/test.html b/aio/content/marketing/test.html index 872c66c45a3f4..271bd9be111eb 100644 --- a/aio/content/marketing/test.html +++ b/aio/content/marketing/test.html @@ -110,13 +110,13 @@live-example with name
live-example with spacey name and plnkr
-live-example with spacey name and stackblitz
+live-example with name and plnkr but no download
-live-example with name and stackblitz but no download
+live-example embedded with name and plnkr
-live-example embedded with name and stackblitz
+More text follows ...
diff --git a/aio/content/navigation.json b/aio/content/navigation.json index 00944edb07099..670f203a52852 100644 --- a/aio/content/navigation.json +++ b/aio/content/navigation.json @@ -240,8 +240,8 @@ }, { "url": "guide/module-types", - "title": "Types of NgModules", - "tooltip": "Description of the different types of feature module." + "title": "Types of Feature Modules", + "tooltip": "Description of the different types of feature modules." }, { "url": "guide/entry-components", diff --git a/aio/e2e/app.e2e-spec.ts b/aio/e2e/app.e2e-spec.ts index fd4794c6e8226..788e5f65611ed 100644 --- a/aio/e2e/app.e2e-spec.ts +++ b/aio/e2e/app.e2e-spec.ts @@ -128,6 +128,20 @@ describe('site App', function() { }); describe('404 page', () => { + it('should add or remove the "noindex" meta tag depending upon the validity of the page', () => { + page.navigateTo(''); + expect(element(by.css('meta[name="googlebot"]')).isPresent()).toBeFalsy(); + expect(element(by.css('meta[name="robots"]')).isPresent()).toBeFalsy(); + + page.navigateTo('does/not/exist'); + expect(element(by.css('meta[name="googlebot"][content="noindex"]')).isPresent()).toBeTruthy(); + expect(element(by.css('meta[name="robots"][content="noindex"]')).isPresent()).toBeTruthy(); + + page.getTopMenuLink('features').click(); + expect(element(by.css('meta[name="googlebot"]')).isPresent()).toBeFalsy(); + expect(element(by.css('meta[name="robots"]')).isPresent()).toBeFalsy(); + }); + it('should search the index for words found in the url', () => { page.navigateTo('http/router'); const results = page.getSearchResults(); diff --git a/aio/firebase.json b/aio/firebase.json index a41d85931f784..87e6da0b6025f 100644 --- a/aio/firebase.json +++ b/aio/firebase.json @@ -49,6 +49,9 @@ // aot-compiler.md and metadata.md combined into aot-compiler.md - issue #19510 {"type": 301, "source": "/guide/metadata", "destination": "/guide/aot-compiler"}, + // ngmodule.md renamed to ngmodules.md + {"type": 301, "source": "/guide/ngmodule", "destination": "/guide/ngmodules"}, + // service-worker-getstart.md, service-worker-comm.md, service-worker-configref.md {"type": 301, "source": "/guide/service-worker-getstart", "destination": "/guide/service-worker-getting-started"}, {"type": 301, "source": "/guide/service-worker-comm", "destination": "/guide/service-worker-communications"}, diff --git a/aio/karma.conf.js b/aio/karma.conf.js index c2d83c7804636..032dd4145363f 100644 --- a/aio/karma.conf.js +++ b/aio/karma.conf.js @@ -30,8 +30,14 @@ module.exports = function (config) { colors: true, logLevel: config.LOG_INFO, autoWatch: true, - browsers: ['Chrome'], + browsers: ['CustomChrome'], browserNoActivityTimeout: 60000, - singleRun: false + singleRun: false, + customLaunchers: { + CustomChrome: { + base: 'Chrome', + flags: process.env.TRAVIS && ['--no-sandbox'] + } + } }); }; diff --git a/aio/ngsw-manifest.json b/aio/ngsw-manifest.json index e2a077482c712..c59ab0bdb9597 100644 --- a/aio/ngsw-manifest.json +++ b/aio/ngsw-manifest.json @@ -19,7 +19,7 @@ "routing": { "index": "/index.html", "routes": { - "^(?!/docs/ts/latest|/guide/(?:cli-quickstart|metadata|service-worker-(?:getstart|comm|configref))/?$|/styleguide).*/(?!e?plnkr)[^/.]*$": { + "^(?!/docs/.|(?:/guide/(?:cli-quickstart|metadata|ngmodule|service-worker-(?:getstart|comm|configref)|learning-angular)|/news/?)$|/testing|/api/(?:common/NgModel|platform-browser/AnimationDriver|testing|api)).*/(?!e?stackblitz|(?:NgFor|MaxLengthValidator)-|Control(?:Group)?|AnimationStateDeclarationMetadata|CORE_DIRECTIVES|PLATFORM_PIPES|DirectiveMetadata|HTTP_PROVIDERS)[^/.]*$": { "match": "regex" } } diff --git a/aio/package.json b/aio/package.json index 1f4514cd2c063..b32ad0a052f81 100644 --- a/aio/package.json +++ b/aio/package.json @@ -23,7 +23,7 @@ "preinstall": "node ../tools/yarn/check-yarn.js", "presetup": "yarn install --frozen-lockfile && yarn ~~check-env && yarn boilerplate:remove", "setup": "yarn aio-use-npm && yarn example-use-npm", - "postsetup": "yarn boilerplate:add && yarn build-ie-polyfills && yarn generate-plunkers && yarn generate-zips && yarn docs", + "postsetup": "yarn boilerplate:add && yarn build-ie-polyfills && yarn generate-stackblitz && yarn generate-zips && yarn docs", "presetup-local": "yarn presetup", "setup-local": "yarn aio-use-local && yarn example-use-local", "postsetup-local": "yarn postsetup", @@ -48,7 +48,7 @@ "boilerplate:add": "node ./tools/examples/example-boilerplate add", "boilerplate:remove": "node ./tools/examples/example-boilerplate remove", "boilerplate:test": "node tools/examples/test.js", - "generate-plunkers": "node ./tools/plunker-builder/generatePlunkers", + "generate-stackblitz": "node ./tools/stackblitz-builder/generateStackblitz", "generate-zips": "node ./tools/example-zipper/generateZips", "sw-manifest": "ngu-sw-manifest --dist dist --in ngsw-manifest.json --out dist/ngsw-manifest.json", "sw-copy": "cp node_modules/@angular/service-worker/bundles/worker-basic.min.js dist/", diff --git a/aio/protractor.conf.js b/aio/protractor.conf.js index 1cd695135f7e2..d112804b62c95 100644 --- a/aio/protractor.conf.js +++ b/aio/protractor.conf.js @@ -12,7 +12,8 @@ exports.config = { browserName: 'chrome', // For Travis chromeOptions: { - binary: process.env.CHROME_BIN + binary: process.env.CHROME_BIN, + args: ['--no-sandbox'] } }, directConnect: true, diff --git a/aio/scripts/_payload-limits.json b/aio/scripts/_payload-limits.json index 9f1df56be2d76..296081ad531fd 100755 --- a/aio/scripts/_payload-limits.json +++ b/aio/scripts/_payload-limits.json @@ -1,20 +1,12 @@ { "aio": { "master": { - "gzip7": { - "inline": 961, - "main": 116924, - "polyfills": 12962 - }, - "gzip9": { - "inline": 961, - "main": 116712, - "polyfills": 12958 - }, "uncompressed": { "inline": 1602, "main": 459119, - "polyfills": 40264 + "polyfills": 40264, + "embedded": 71711, + "prettify": 14888 } } } diff --git a/aio/scripts/test-pwa-score.js b/aio/scripts/test-pwa-score.js index d41db50d0e6e8..f78a48cbd1584 100644 --- a/aio/scripts/test-pwa-score.js +++ b/aio/scripts/test-pwa-score.js @@ -17,11 +17,15 @@ const printer = require('lighthouse/lighthouse-cli/printer'); const config = require('lighthouse/lighthouse-core/config/default.js'); // Constants +const CHROME_LAUNCH_OPTS = {}; +const SKIPPED_HTTPS_AUDITS = ['redirects-http']; const VIEWER_URL = 'https://googlechrome.github.io/lighthouse/viewer/'; -// Specify the path to Chrome on Travis + +// Specify the path and flags for Chrome on Travis if (process.env.TRAVIS) { process.env.LIGHTHOUSE_CHROMIUM_PATH = process.env.CHROME_BIN; + CHROME_LAUNCH_OPTS.chromeFlags = ['--no-sandbox']; } // Run @@ -54,18 +58,8 @@ function evaluateScore(expectedScore, actualScore) { } } -function skipHttpsAudits(config) { - const httpsAudits = [ - 'redirects-http' - ]; - - console.info(`Skipping HTTPS-related audits (${httpsAudits.join(', ')})...`); - - config.settings.skipAudits = httpsAudits; -} - function launchChromeAndRunLighthouse(url, flags, config) { - return chromeLauncher.launch().then(chrome => { + return chromeLauncher.launch(CHROME_LAUNCH_OPTS).then(chrome => { flags.port = chrome.port; return lighthouse(url, flags, config). then(results => chrome.kill().then(() => results)). @@ -108,3 +102,8 @@ function processResults(results, logFile) { return promise.then(() => Math.round(results.score)); } + +function skipHttpsAudits(config) { + console.info(`Skipping HTTPS-related audits (${SKIPPED_HTTPS_AUDITS.join(', ')})...`); + config.settings.skipAudits = SKIPPED_HTTPS_AUDITS; +} diff --git a/aio/src/app/embedded/embedded.module.ts b/aio/src/app/embedded/embedded.module.ts index ea13933b72852..bc0a886dec9e2 100644 --- a/aio/src/app/embedded/embedded.module.ts +++ b/aio/src/app/embedded/embedded.module.ts @@ -25,7 +25,7 @@ import { ContributorListComponent } from './contributor/contributor-list.compone import { ContributorComponent } from './contributor/contributor.component'; import { CurrentLocationComponent } from './current-location.component'; import { FileNotFoundSearchComponent } from './search/file-not-found-search.component'; -import { LiveExampleComponent, EmbeddedPlunkerComponent } from './live-example/live-example.component'; +import { LiveExampleComponent, EmbeddedStackblitzComponent } from './live-example/live-example.component'; import { ResourceListComponent } from './resource/resource-list.component'; import { ResourceService } from './resource/resource.service'; @@ -50,7 +50,7 @@ export const embeddedComponents: TypeYou can also download this example.
@@ -13,7 +12,7 @@ {{title}} - {{title}} + {{title}} / download example diff --git a/aio/src/app/embedded/live-example/live-example.component.spec.ts b/aio/src/app/embedded/live-example/live-example.component.spec.ts index 80bd4baff885c..9879f0e69ee0a 100644 --- a/aio/src/app/embedded/live-example/live-example.component.spec.ts +++ b/aio/src/app/embedded/live-example/live-example.component.spec.ts @@ -3,12 +3,11 @@ import { By } from '@angular/platform-browser'; import { Component, DebugElement } from '@angular/core'; import { Location } from '@angular/common'; -import { LiveExampleComponent, EmbeddedPlunkerComponent } from './live-example.component'; +import { LiveExampleComponent, EmbeddedStackblitzComponent } from './live-example.component'; const defaultTestPath = '/test'; describe('LiveExampleComponent', () => { - let hostComponent: HostComponent; let liveExampleDe: DebugElement; let liveExampleComponent: LiveExampleComponent; let fixture: ComponentFixture