mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
Compare commits
140 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9517ae3f23 | |||
| 0ee9ea8148 | |||
| 65ee5431b8 | |||
| 0047eb3cf8 | |||
| cb10bac906 | |||
| 058a07148c | |||
| 3351380e0a | |||
| 8f9ba8eca6 | |||
| 1d9b2c1590 | |||
| 20654c95d8 | |||
| d3a9211c35 | |||
| e7d153cd91 | |||
| 9bcaeac03d | |||
| e330cc9b31 | |||
| 06a355a5fe | |||
| ef1910fa25 | |||
| 6a41e52c2f | |||
| b62d4e09dd | |||
| 24063b0852 | |||
| a208a850cc | |||
| 2dc774bc2f | |||
| 00eeebf43f | |||
| 6a11c9abcf | |||
| b823049f89 | |||
| cafd4f58c9 | |||
| 4cf9f00df7 | |||
| da44b474ec | |||
| 0e61225244 | |||
| e706f46a16 | |||
| 5dab521c72 | |||
| bf12f52a71 | |||
| 0957d3659f | |||
| 1b8d7eb9d0 | |||
| 97ce82377b | |||
| f5b44f8762 | |||
| 726ec8891e | |||
| abdf25c679 | |||
| de124856f6 | |||
| 63275ae82c | |||
| 156103c4c3 | |||
| 44150ecacc | |||
| f8a63e9d49 | |||
| d88f18e76b | |||
| 813726480e | |||
| 77efc27cff | |||
| 22739293a4 | |||
| 6cdbccafa1 | |||
| cda577d340 | |||
| 7d6238e789 | |||
| 95e68c4f27 | |||
| 67c4ab616d | |||
| a01a9d221e | |||
| 2b7041ec00 | |||
| 97ec6e4849 | |||
| 2abdf5c75c | |||
| a87e90071c | |||
| defa62722a | |||
| 33e0f2bd56 | |||
| da3e280403 | |||
| 2fab148cb5 | |||
| 72fc6aa318 | |||
| 3c785e5c46 | |||
| 56612982c7 | |||
| 760557b526 | |||
| c08fbb485c | |||
| 811f9dacbd | |||
| fc912f4128 | |||
| c655cc5ea0 | |||
| 37710b9be3 | |||
| 3124e4257d | |||
| 6635e552f8 | |||
| 7654a81493 | |||
| dfe4200c2e | |||
| 761b8fe4b4 | |||
| 3bf6a9908c | |||
| 6298b3e11b | |||
| b3b80d4e4a | |||
| 4bb38c9ffd | |||
| 72c0ba6f7a | |||
| 566206b519 | |||
| c35298dfa3 | |||
| 1b79810c16 | |||
| d1c954e25c | |||
| 69e439420d | |||
| 69fd94220e | |||
| 5f6808d30b | |||
| 556e9f2aee | |||
| e995d851cf | |||
| 106734a06a | |||
| a8a27efb77 | |||
| 4212d62a8d | |||
| b41204c0ad | |||
| aa3aafb7df | |||
| 1477fb761d | |||
| d2aa3eef15 | |||
| fbb1eb1a73 | |||
| fbbd23ef12 | |||
| 899bf3b997 | |||
| 59680c2644 | |||
| 34092a5052 | |||
| b8e47e277e | |||
| 2731a4b633 | |||
| 3e134e441f | |||
| 2c5ad5cbe8 | |||
| 106df618bc | |||
| d1c542b5c3 | |||
| 2047d632d8 | |||
| 4468ac2999 | |||
| 5578e23e54 | |||
| ad2b50bc81 | |||
| 524415ef8a | |||
| 8e0b01eec3 | |||
| 0a00b7db93 | |||
| 6675b6fb35 | |||
| 9c595b0fe5 | |||
| c8464eded1 | |||
| 861fa84566 | |||
| d5f696c187 | |||
| 76f363381f | |||
| 63bf613785 | |||
| 798aae45a8 | |||
| e2e3862548 | |||
| b1ae2396e1 | |||
| 32bf23a489 | |||
| 873bdf0345 | |||
| 30a7351933 | |||
| 968b2bbfc6 | |||
| 17f6b78969 | |||
| f4ed12211e | |||
| c6c7e9a4e3 | |||
| 76cabb21f6 | |||
| 0664d750b6 | |||
| a5c4adcdf0 | |||
| bbda311f32 | |||
| f675dbffac | |||
| b12b648517 | |||
| 71c5e75d9c | |||
| 7a9bc9958a | |||
| ebd94ef41b | |||
| 1ec5f869e0 |
+1
-1
@@ -1,3 +1,3 @@
|
||||
3.6.0
|
||||
4.0.0
|
||||
# [NB: this comment has to be after the first line, see https://github.com/bazelbuild/bazelisk/issues/117]
|
||||
# When updating the Bazel version you also need to update the RBE toolchains version in package.bzl
|
||||
|
||||
+1
-1
@@ -107,7 +107,7 @@ echo "export CI_SECRET_PAYLOAD_FIREBASE_TOKEN=\"${CI_SECRET_PAYLOAD_FIREBASE_TOK
|
||||
####################################################################################################
|
||||
####################################################################################################
|
||||
## Source `$BASH_ENV` to make the variables available immediately. ##
|
||||
## ***NOTE: This must remain the the last action in this script*** ##
|
||||
## ***NOTE: This must remain the last action in this script*** ##
|
||||
####################################################################################################
|
||||
####################################################################################################
|
||||
source $BASH_ENV;
|
||||
|
||||
@@ -4,6 +4,7 @@ import {ReleaseConfig} from '../dev-infra/release/config';
|
||||
|
||||
/** Configuration for the `ng-dev release` command. */
|
||||
export const release: ReleaseConfig = {
|
||||
publishRegistry: 'https://wombat-dressing-room.appspot.com',
|
||||
npmPackages: [
|
||||
'@angular/animations',
|
||||
'@angular/bazel',
|
||||
@@ -32,4 +33,5 @@ export const release: ReleaseConfig = {
|
||||
generateReleaseNotesForHead: async () => {
|
||||
exec('yarn -s gulp changelog', {cwd: join(__dirname, '../')});
|
||||
},
|
||||
releasePrLabels: ['comp: build & ci', 'action: merge', 'PullApprove: disable'],
|
||||
};
|
||||
|
||||
+3
-1
@@ -479,6 +479,7 @@ groups:
|
||||
users:
|
||||
- alxhub
|
||||
- IgorMinar
|
||||
- petebacondarwin
|
||||
|
||||
|
||||
# =========================================================
|
||||
@@ -802,7 +803,6 @@ groups:
|
||||
])
|
||||
reviewers:
|
||||
users:
|
||||
- ayazhafiz
|
||||
- kyliau
|
||||
- atscott
|
||||
|
||||
@@ -950,6 +950,7 @@ groups:
|
||||
users:
|
||||
- aikidave
|
||||
- IgorMinar
|
||||
- mgechev
|
||||
- StephenFluin
|
||||
|
||||
# =========================================================
|
||||
@@ -1231,6 +1232,7 @@ groups:
|
||||
'goldens/public-api/**',
|
||||
'CHANGELOG.md',
|
||||
'docs/NAMING.md',
|
||||
'aio/content/errors/*.md',
|
||||
'aio/content/guide/glossary.md',
|
||||
'aio/content/guide/styleguide.md',
|
||||
'aio/content/examples/styleguide/**',
|
||||
|
||||
@@ -46679,7 +46679,7 @@ function mkdirfix (name, opts, cb) {
|
||||
/* 194 */
|
||||
/***/ (function(module, exports) {
|
||||
|
||||
module.exports = {"name":"yarn","installationMethod":"unknown","version":"1.22.5","license":"BSD-2-Clause","preferGlobal":true,"description":"📦🐈 Fast, reliable, and secure dependency management.","dependencies":{"@zkochan/cmd-shim":"^3.1.0","babel-runtime":"^6.26.0","bytes":"^3.0.0","camelcase":"^4.0.0","chalk":"^2.1.0","cli-table3":"^0.4.0","commander":"^2.9.0","death":"^1.0.0","debug":"^3.0.0","deep-equal":"^1.0.1","detect-indent":"^5.0.0","dnscache":"^1.0.1","glob":"^7.1.1","gunzip-maybe":"^1.4.0","hash-for-dep":"^1.2.3","imports-loader":"^0.8.0","ini":"^1.3.4","inquirer":"^6.2.0","invariant":"^2.2.0","is-builtin-module":"^2.0.0","is-ci":"^1.0.10","is-webpack-bundle":"^1.0.0","js-yaml":"^3.13.1","leven":"^2.0.0","loud-rejection":"^1.2.0","micromatch":"^2.3.11","mkdirp":"^0.5.1","node-emoji":"^1.6.1","normalize-url":"^2.0.0","npm-logical-tree":"^1.2.1","object-path":"^0.11.2","proper-lockfile":"^2.0.0","puka":"^1.0.0","read":"^1.0.7","request":"^2.87.0","request-capture-har":"^1.2.2","rimraf":"^2.5.0","semver":"^5.1.0","ssri":"^5.3.0","strip-ansi":"^4.0.0","strip-bom":"^3.0.0","tar-fs":"^1.16.0","tar-stream":"^1.6.1","uuid":"^3.0.1","v8-compile-cache":"^2.0.0","validate-npm-package-license":"^3.0.4","yn":"^2.0.0"},"devDependencies":{"babel-core":"^6.26.0","babel-eslint":"^7.2.3","babel-loader":"^6.2.5","babel-plugin-array-includes":"^2.0.3","babel-plugin-inline-import":"^3.0.0","babel-plugin-transform-builtin-extend":"^1.1.2","babel-plugin-transform-inline-imports-commonjs":"^1.0.0","babel-plugin-transform-runtime":"^6.4.3","babel-preset-env":"^1.6.0","babel-preset-flow":"^6.23.0","babel-preset-stage-0":"^6.0.0","babylon":"^6.5.0","commitizen":"^2.9.6","cz-conventional-changelog":"^2.0.0","eslint":"^4.3.0","eslint-config-fb-strict":"^22.0.0","eslint-plugin-babel":"^5.0.0","eslint-plugin-flowtype":"^2.35.0","eslint-plugin-jasmine":"^2.6.2","eslint-plugin-jest":"^21.0.0","eslint-plugin-jsx-a11y":"^6.0.2","eslint-plugin-prefer-object-spread":"^1.2.1","eslint-plugin-prettier":"^2.1.2","eslint-plugin-react":"^7.1.0","eslint-plugin-relay":"^0.0.28","eslint-plugin-yarn-internal":"file:scripts/eslint-rules","execa":"^0.11.0","fancy-log":"^1.3.2","flow-bin":"^0.66.0","git-release-notes":"^3.0.0","gulp":"^4.0.0","gulp-babel":"^7.0.0","gulp-if":"^2.0.1","gulp-newer":"^1.0.0","gulp-plumber":"^1.0.1","gulp-sourcemaps":"^2.2.0","jest":"^22.4.4","jsinspect":"^0.12.6","minimatch":"^3.0.4","mock-stdin":"^0.3.0","prettier":"^1.5.2","string-replace-loader":"^2.1.1","temp":"^0.8.3","webpack":"^2.1.0-beta.25","yargs":"^6.3.0"},"resolutions":{"sshpk":"^1.14.2"},"engines":{"node":">=4.0.0"},"repository":"yarnpkg/yarn","bin":{"yarn":"./bin/yarn.js","yarnpkg":"./bin/yarn.js"},"scripts":{"build":"gulp build","build-bundle":"node ./scripts/build-webpack.js","build-chocolatey":"powershell ./scripts/build-chocolatey.ps1","build-deb":"./scripts/build-deb.sh","build-dist":"bash ./scripts/build-dist.sh","build-win-installer":"scripts\\build-windows-installer.bat","changelog":"git-release-notes $(git describe --tags --abbrev=0 $(git describe --tags --abbrev=0)^)..$(git describe --tags --abbrev=0) scripts/changelog.md","dupe-check":"yarn jsinspect ./src","lint":"eslint . && flow check","pkg-tests":"yarn --cwd packages/pkg-tests jest yarn.test.js","prettier":"eslint src __tests__ --fix","release-branch":"./scripts/release-branch.sh","test":"yarn lint && yarn test-only","test-only":"node --max_old_space_size=4096 node_modules/jest/bin/jest.js --verbose","test-only-debug":"node --inspect-brk --max_old_space_size=4096 node_modules/jest/bin/jest.js --runInBand --verbose","test-coverage":"node --max_old_space_size=4096 node_modules/jest/bin/jest.js --coverage --verbose","watch":"gulp watch","commit":"git-cz"},"jest":{"collectCoverageFrom":["src/**/*.js"],"testEnvironment":"node","modulePathIgnorePatterns":["__tests__/fixtures/","packages/pkg-tests/pkg-tests-fixtures","dist/"],"testPathIgnorePatterns":["__tests__/(fixtures|__mocks__)/","updates/","_(temp|mock|install|init|helpers).js$","packages/pkg-tests"]},"config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}}}
|
||||
module.exports = {"name":"yarn","installationMethod":"unknown","version":"1.22.10","license":"BSD-2-Clause","preferGlobal":true,"description":"📦🐈 Fast, reliable, and secure dependency management.","dependencies":{"@zkochan/cmd-shim":"^3.1.0","babel-runtime":"^6.26.0","bytes":"^3.0.0","camelcase":"^4.0.0","chalk":"^2.1.0","cli-table3":"^0.4.0","commander":"^2.9.0","death":"^1.0.0","debug":"^3.0.0","deep-equal":"^1.0.1","detect-indent":"^5.0.0","dnscache":"^1.0.1","glob":"^7.1.1","gunzip-maybe":"^1.4.0","hash-for-dep":"^1.2.3","imports-loader":"^0.8.0","ini":"^1.3.4","inquirer":"^6.2.0","invariant":"^2.2.0","is-builtin-module":"^2.0.0","is-ci":"^1.0.10","is-webpack-bundle":"^1.0.0","js-yaml":"^3.13.1","leven":"^2.0.0","loud-rejection":"^1.2.0","micromatch":"^2.3.11","mkdirp":"^0.5.1","node-emoji":"^1.6.1","normalize-url":"^2.0.0","npm-logical-tree":"^1.2.1","object-path":"^0.11.2","proper-lockfile":"^2.0.0","puka":"^1.0.0","read":"^1.0.7","request":"^2.87.0","request-capture-har":"^1.2.2","rimraf":"^2.5.0","semver":"^5.1.0","ssri":"^5.3.0","strip-ansi":"^4.0.0","strip-bom":"^3.0.0","tar-fs":"^1.16.0","tar-stream":"^1.6.1","uuid":"^3.0.1","v8-compile-cache":"^2.0.0","validate-npm-package-license":"^3.0.4","yn":"^2.0.0"},"devDependencies":{"babel-core":"^6.26.0","babel-eslint":"^7.2.3","babel-loader":"^6.2.5","babel-plugin-array-includes":"^2.0.3","babel-plugin-inline-import":"^3.0.0","babel-plugin-transform-builtin-extend":"^1.1.2","babel-plugin-transform-inline-imports-commonjs":"^1.0.0","babel-plugin-transform-runtime":"^6.4.3","babel-preset-env":"^1.6.0","babel-preset-flow":"^6.23.0","babel-preset-stage-0":"^6.0.0","babylon":"^6.5.0","commitizen":"^2.9.6","cz-conventional-changelog":"^2.0.0","eslint":"^4.3.0","eslint-config-fb-strict":"^22.0.0","eslint-plugin-babel":"^5.0.0","eslint-plugin-flowtype":"^2.35.0","eslint-plugin-jasmine":"^2.6.2","eslint-plugin-jest":"^21.0.0","eslint-plugin-jsx-a11y":"^6.0.2","eslint-plugin-prefer-object-spread":"^1.2.1","eslint-plugin-prettier":"^2.1.2","eslint-plugin-react":"^7.1.0","eslint-plugin-relay":"^0.0.28","eslint-plugin-yarn-internal":"file:scripts/eslint-rules","execa":"^0.11.0","fancy-log":"^1.3.2","flow-bin":"^0.66.0","git-release-notes":"^3.0.0","gulp":"^4.0.0","gulp-babel":"^7.0.0","gulp-if":"^2.0.1","gulp-newer":"^1.0.0","gulp-plumber":"^1.0.1","gulp-sourcemaps":"^2.2.0","jest":"^22.4.4","jsinspect":"^0.12.6","minimatch":"^3.0.4","mock-stdin":"^0.3.0","prettier":"^1.5.2","string-replace-loader":"^2.1.1","temp":"^0.8.3","webpack":"^2.1.0-beta.25","yargs":"^6.3.0"},"resolutions":{"sshpk":"^1.14.2"},"engines":{"node":">=4.0.0"},"repository":"yarnpkg/yarn","bin":{"yarn":"./bin/yarn.js","yarnpkg":"./bin/yarn.js"},"scripts":{"build":"gulp build","build-bundle":"node ./scripts/build-webpack.js","build-chocolatey":"powershell ./scripts/build-chocolatey.ps1","build-deb":"./scripts/build-deb.sh","build-dist":"bash ./scripts/build-dist.sh","build-win-installer":"scripts\\build-windows-installer.bat","changelog":"git-release-notes $(git describe --tags --abbrev=0 $(git describe --tags --abbrev=0)^)..$(git describe --tags --abbrev=0) scripts/changelog.md","dupe-check":"yarn jsinspect ./src","lint":"eslint . && flow check","pkg-tests":"yarn --cwd packages/pkg-tests jest yarn.test.js","prettier":"eslint src __tests__ --fix","release-branch":"./scripts/release-branch.sh","test":"yarn lint && yarn test-only","test-only":"node --max_old_space_size=4096 node_modules/jest/bin/jest.js --verbose","test-only-debug":"node --inspect-brk --max_old_space_size=4096 node_modules/jest/bin/jest.js --runInBand --verbose","test-coverage":"node --max_old_space_size=4096 node_modules/jest/bin/jest.js --coverage --verbose","watch":"gulp watch","commit":"git-cz"},"jest":{"collectCoverageFrom":["src/**/*.js"],"testEnvironment":"node","modulePathIgnorePatterns":["__tests__/fixtures/","packages/pkg-tests/pkg-tests-fixtures","dist/"],"testPathIgnorePatterns":["__tests__/(fixtures|__mocks__)/","updates/","_(temp|mock|install|init|helpers).js$","packages/pkg-tests"]},"config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}}}
|
||||
|
||||
/***/ }),
|
||||
/* 195 */
|
||||
@@ -97014,7 +97014,7 @@ let run = exports.run = (() => {
|
||||
if (!(yield (_fs || _load_fs()).exists(lockfilePath))) {
|
||||
yield (_fs || _load_fs()).writeFile(lockfilePath, '');
|
||||
}
|
||||
yield (_child || _load_child()).spawn((_constants || _load_constants()).NODE_BIN_PATH, [process.argv[1], 'policies', 'set-version', installVersion], {
|
||||
yield (_child || _load_child()).spawn((_constants || _load_constants()).NODE_BIN_PATH, [process.argv[1], 'policies', 'set-version', installVersion, '--silent'], {
|
||||
stdio: 'inherit',
|
||||
cwd: config.cwd
|
||||
});
|
||||
@@ -2,4 +2,4 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
yarn-path ".yarn/releases/yarn-1.22.5.js"
|
||||
yarn-path ".yarn/releases/yarn-1.22.10.cjs"
|
||||
|
||||
+169
-144
@@ -1,3 +1,172 @@
|
||||
<a name="11.1.2"></a>
|
||||
## 11.1.2 (2021-02-03)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **common:** parse `YYYY-MM` strings as UTC dates ([#40620](https://github.com/angular/angular/issues/40620)) ([cafd4f5](https://github.com/angular/angular/commit/cafd4f5)), closes [#33944](https://github.com/angular/angular/issues/33944)
|
||||
* **common:** parse `YYYY` strings as UTC dates ([#40629](https://github.com/angular/angular/issues/40629)) ([b823049](https://github.com/angular/angular/commit/b823049)), closes [#33944](https://github.com/angular/angular/issues/33944) [#40620](https://github.com/angular/angular/issues/40620)
|
||||
* **compiler:** Don't set expression text to synthetic `$implicit` when empty ([#40583](https://github.com/angular/angular/issues/40583)) ([5dab521](https://github.com/angular/angular/commit/5dab521))
|
||||
* **compiler:** exclude trailing whitespace from element source spans ([#40513](https://github.com/angular/angular/issues/40513)) ([726ec88](https://github.com/angular/angular/commit/726ec88)), closes [#39148](https://github.com/angular/angular/issues/39148)
|
||||
* **compiler-cli:** preserve user line endings in diagnostic template parse ([#40597](https://github.com/angular/angular/issues/40597)) ([00eeebf](https://github.com/angular/angular/commit/00eeebf))
|
||||
* **core:** ensure the type `T` of `EventEmitter<T>` can be inferred ([#40644](https://github.com/angular/angular/issues/40644)) ([8f9ba8e](https://github.com/angular/angular/commit/8f9ba8e)), closes [#40637](https://github.com/angular/angular/issues/40637)
|
||||
* **core:** remove duplicated EMPTY_ARRAY constant ([#40587](https://github.com/angular/angular/issues/40587)) ([abdf25c](https://github.com/angular/angular/commit/abdf25c))
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **language-service:** update NgCompiler via resource-only path when able ([#40680](https://github.com/angular/angular/issues/40680)) ([0047eb3](https://github.com/angular/angular/commit/0047eb3))
|
||||
|
||||
|
||||
|
||||
<a name="11.1.1"></a>
|
||||
## 11.1.1 (2021-01-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **compiler-cli:** handle pseudo cycles in inline source-maps ([#40435](https://github.com/angular/angular/issues/40435)) ([566206b](https://github.com/angular/angular/commit/566206b)), closes [#40408](https://github.com/angular/angular/issues/40408)
|
||||
* **compiler-cli:** use `Map` rather than `object` for map of partial linkers ([#40563](https://github.com/angular/angular/issues/40563)) ([33e0f2b](https://github.com/angular/angular/commit/33e0f2b))
|
||||
* **core:** fix possible XSS attack in development through SSR ([#40525](https://github.com/angular/angular/issues/40525)) ([97ec6e4](https://github.com/angular/angular/commit/97ec6e4))
|
||||
* **core:** improve injector debug information in `ngDevMode` ([#40476](https://github.com/angular/angular/issues/40476)) ([4bb38c9](https://github.com/angular/angular/commit/4bb38c9))
|
||||
* **forms:** allow `patchValue()` method of `FormGroup` and `FormArray` classes to skip `null` values ([#40534](https://github.com/angular/angular/issues/40534)) ([2fab148](https://github.com/angular/angular/commit/2fab148)), closes [#36672](https://github.com/angular/angular/issues/36672) [#21021](https://github.com/angular/angular/issues/21021)
|
||||
* **forms:** properly cleanup in cases when FormControlName has no CVA ([#40526](https://github.com/angular/angular/issues/40526)) ([72fc6aa](https://github.com/angular/angular/commit/72fc6aa)), closes [#39235](https://github.com/angular/angular/issues/39235) [#40521](https://github.com/angular/angular/issues/40521)
|
||||
* **language-service:** implement realpath to resolve symlinks ([#40593](https://github.com/angular/angular/issues/40593)) ([77efc27](https://github.com/angular/angular/commit/77efc27))
|
||||
* **language-service:** recognize incomplete pipe bindings with whitespace ([#40346](https://github.com/angular/angular/issues/40346)) ([d88f18e](https://github.com/angular/angular/commit/d88f18e))
|
||||
* **localize:** include meaning in generated ARB files ([#40546](https://github.com/angular/angular/issues/40546)) ([5661298](https://github.com/angular/angular/commit/5661298)), closes [#40506](https://github.com/angular/angular/issues/40506)
|
||||
* **router:** always stringify matrix parameters ([#25095](https://github.com/angular/angular/issues/25095)) ([a8a27ef](https://github.com/angular/angular/commit/a8a27ef)), closes [#23165](https://github.com/angular/angular/issues/23165)
|
||||
* **router:** Fix occasional error when creating url tree in IE 11 and Edge ([#40488](https://github.com/angular/angular/issues/40488)) ([69fd942](https://github.com/angular/angular/commit/69fd942))
|
||||
* **service-worker:** handle error with console.error ([#40236](https://github.com/angular/angular/issues/40236)) ([37710b9](https://github.com/angular/angular/commit/37710b9))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **language-service:** Add diagnostics to suggest turning on strict mode ([#40568](https://github.com/angular/angular/issues/40568)) ([defa627](https://github.com/angular/angular/commit/defa627))
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **compiler-cli:** introduce fast path for resource-only updates ([#40561](https://github.com/angular/angular/issues/40561)) ([156103c](https://github.com/angular/angular/commit/156103c))
|
||||
* **core:** simplify bloom bucket computation ([#40489](https://github.com/angular/angular/issues/40489)) ([106734a](https://github.com/angular/angular/commit/106734a))
|
||||
|
||||
|
||||
|
||||
<a name="11.1.0"></a>
|
||||
# 11.1.0 (2021-01-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **animations:** getAnimationStyle causes exceptions in older browsers ([#29709](https://github.com/angular/angular/issues/29709)) ([66d863f](https://github.com/angular/angular/commit/66d863f))
|
||||
* **animations:** replace copy of query selector node-list from "spread" to "for" ([#39646](https://github.com/angular/angular/issues/39646)) ([bfa197f](https://github.com/angular/angular/commit/bfa197f)), closes [#38551](https://github.com/angular/angular/issues/38551)
|
||||
* **common:** add `HttpParamsOptions` to the public api ([#35829](https://github.com/angular/angular/issues/35829)) ([b33b89d](https://github.com/angular/angular/commit/b33b89d)), closes [#20276](https://github.com/angular/angular/issues/20276)
|
||||
* **common:** Prefer to use pageXOffset / pageYOffset instance of scrollX / scrollY ([#28262](https://github.com/angular/angular/issues/28262)) ([b1d300d](https://github.com/angular/angular/commit/b1d300d))
|
||||
* **compiler:** correct the `KeySpan` for animation events and properties ([#40347](https://github.com/angular/angular/issues/40347)) ([524415e](https://github.com/angular/angular/commit/524415e))
|
||||
* **compiler:** incorrectly interpreting some HostBinding names ([#40233](https://github.com/angular/angular/issues/40233)) ([1045465](https://github.com/angular/angular/commit/1045465)), closes [#40220](https://github.com/angular/angular/issues/40220) [#40230](https://github.com/angular/angular/issues/40230) [#18698](https://github.com/angular/angular/issues/18698)
|
||||
* **compiler:** recover event parse when animation event name is empty ([#39925](https://github.com/angular/angular/issues/39925)) ([15b15be](https://github.com/angular/angular/commit/15b15be))
|
||||
* **compiler:** avoid duplicate i18n blocks for i18n attrs on elements with structural directives ([#40077](https://github.com/angular/angular/issues/40077)) ([caa4666](https://github.com/angular/angular/commit/caa4666)), closes [#39942](https://github.com/angular/angular/issues/39942)
|
||||
* **compiler:** handle strings inside bindings that contain binding characters ([#39826](https://github.com/angular/angular/issues/39826)) ([dc6d40e](https://github.com/angular/angular/commit/dc6d40e)), closes [#39601](https://github.com/angular/angular/issues/39601)
|
||||
* **compiler:** disallow i18n of security-sensitive attributes ([#39554](https://github.com/angular/angular/issues/39554)) ([c8a99ef](https://github.com/angular/angular/commit/c8a99ef))
|
||||
* **compiler:** ensure that placeholders have the correct sourceSpan ([#39717](https://github.com/angular/angular/issues/39717)) ([0462a61](https://github.com/angular/angular/commit/0462a61)), closes [#39671](https://github.com/angular/angular/issues/39671)
|
||||
* **compiler:** only promote Trusted Types to constants when necessary ([#39554](https://github.com/angular/angular/issues/39554)) ([4916870](https://github.com/angular/angular/commit/4916870))
|
||||
* **compiler:** report better error on interpolation in an expression ([#30300](https://github.com/angular/angular/issues/30300)) ([94e790d](https://github.com/angular/angular/commit/94e790d))
|
||||
* **compiler-cli:** do not duplicate repeated source-files in rendered source-maps ([#40237](https://github.com/angular/angular/issues/40237)) ([3158858](https://github.com/angular/angular/commit/3158858))
|
||||
* **compiler-cli:** remove classes in .d.ts files from provider checks ([#40118](https://github.com/angular/angular/issues/40118)) ([973bb40](https://github.com/angular/angular/commit/973bb40))
|
||||
* **animations:** implement getPosition in browser animation builder ([#39983](https://github.com/angular/angular/issues/39983)) ([ca08625](https://github.com/angular/angular/commit/ca08625))
|
||||
* **compiler-cli:** correct incremental behavior even with broken imports ([#39923](https://github.com/angular/angular/issues/39923)) ([c7c5b2f](https://github.com/angular/angular/commit/c7c5b2f))
|
||||
* **compiler-cli:** remove the concept of an errored trait ([#39923](https://github.com/angular/angular/issues/39923)) ([6d42954](https://github.com/angular/angular/commit/6d42954))
|
||||
* **compiler-cli:** track poisoned scopes with a flag ([#39923](https://github.com/angular/angular/issues/39923)) ([0823622](https://github.com/angular/angular/commit/0823622))
|
||||
* **compiler-cli:** report error when a reference target is missing instead of crashing ([#39805](https://github.com/angular/angular/issues/39805)) ([453b32f](https://github.com/angular/angular/commit/453b32f)), closes [#38618](https://github.com/angular/angular/issues/38618) [#39744](https://github.com/angular/angular/issues/39744)
|
||||
* **core:** fix possible XSS attack in development through SSR. ([#40136](https://github.com/angular/angular/issues/40136)) ([47d9b6d](https://github.com/angular/angular/commit/47d9b6d))
|
||||
* **core:** set `ngDevMode` to `false` when calling `enableProdMode()` ([#40124](https://github.com/angular/angular/issues/40124)) ([70b4816](https://github.com/angular/angular/commit/70b4816))
|
||||
* **core:** Allow passing AbstractType to the inject function ([#37958](https://github.com/angular/angular/issues/37958)) ([a1b6ad0](https://github.com/angular/angular/commit/a1b6ad0))
|
||||
* **core:** Ensure OnPush ancestors are marked dirty when events occur ([#39833](https://github.com/angular/angular/issues/39833)) ([68d4a74](https://github.com/angular/angular/commit/68d4a74)), closes [#39832](https://github.com/angular/angular/issues/39832)
|
||||
* **core:** meta addTag() adds incorrect attribute for httpEquiv ([#32531](https://github.com/angular/angular/issues/32531)) ([ff0a90e](https://github.com/angular/angular/commit/ff0a90e))
|
||||
* **core:** migration error if program contains files outside of the project ([#39790](https://github.com/angular/angular/issues/39790)) ([1a26f6d](https://github.com/angular/angular/commit/1a26f6d)), closes [#39778](https://github.com/angular/angular/issues/39778)
|
||||
* **core:** not invoking object's toString when rendering to the DOM ([#39843](https://github.com/angular/angular/issues/39843)) ([11cd37f](https://github.com/angular/angular/commit/11cd37f)), closes [#38839](https://github.com/angular/angular/issues/38839)
|
||||
* **core:** remove duplicated noop function ([#39761](https://github.com/angular/angular/issues/39761)) ([066126a](https://github.com/angular/angular/commit/066126a))
|
||||
* **core:** support `Attribute` DI decorator in `deps` section of a token ([#37085](https://github.com/angular/angular/issues/37085)) ([f5cbf0b](https://github.com/angular/angular/commit/f5cbf0b)), closes [#36479](https://github.com/angular/angular/issues/36479)
|
||||
* **core:** remove application from the testability registry when the root view is removed ([#39876](https://github.com/angular/angular/issues/39876)) ([df27027](https://github.com/angular/angular/commit/df27027)), closes [#22106](https://github.com/angular/angular/issues/22106)
|
||||
* **core:** Support extending differs from root `NgModule` ([#39981](https://github.com/angular/angular/issues/39981)) ([5fc4508](https://github.com/angular/angular/commit/5fc4508)), closes [#25015](https://github.com/angular/angular/issues/25015) [#11309](https://github.com/angular/angular/issues/11309) [#18554](https://github.com/angular/angular/issues/18554)
|
||||
* **core:** unsubscribe from the `onError` when the root view is removed ([#39940](https://github.com/angular/angular/issues/39940)) ([5a3a154](https://github.com/angular/angular/commit/5a3a154))
|
||||
* **core:** `QueryList` should not fire changes if the underlying list did not change. ([#40091](https://github.com/angular/angular/issues/40091)) ([76f3633](https://github.com/angular/angular/commit/76f3633))
|
||||
* **core:** fix fakeAsync() error messages ([#40442](https://github.com/angular/angular/issues/40442)) ([ad2b50b](https://github.com/angular/angular/commit/ad2b50b))
|
||||
* **forms:** error if control is removed as a result of another one being reset ([#40462](https://github.com/angular/angular/issues/40462)) ([2c5ad5c](https://github.com/angular/angular/commit/2c5ad5c)), closes [#33401](https://github.com/angular/angular/issues/33401)
|
||||
* **forms:** clean up connection between FormControl/FormGroup and corresponding directive instances ([#39235](https://github.com/angular/angular/issues/39235)) ([a384961](https://github.com/angular/angular/commit/a384961)), closes [#20007](https://github.com/angular/angular/issues/20007) [#37431](https://github.com/angular/angular/issues/37431) [#39590](https://github.com/angular/angular/issues/39590)
|
||||
* **language-service:** fix go to definition for template variables and references ([#40455](https://github.com/angular/angular/issues/40455)) ([#40491](https://github.com/angular/angular/issues/40491)) ([3e134e4](https://github.com/angular/angular/commit/3e134e4))
|
||||
* **language-service:** Paths on Windows should be normalized ([#40492](https://github.com/angular/angular/issues/40492)) ([b8e47e2](https://github.com/angular/angular/commit/b8e47e2)), closes [/github.com/angular/vscode-ng-language-service/blob/9fca9c66510974c26d5c21b31adb9fa39ac0a38a/server/src/session.ts#L594](https://github.com//github.com/angular/vscode-ng-language-service/blob/9fca9c66510974c26d5c21b31adb9fa39ac0a38a/server/src/session.ts/issues/L594)
|
||||
* **language-service:** report non-template diagnostics ([#40331](https://github.com/angular/angular/issues/40331)) ([4db89f4](https://github.com/angular/angular/commit/4db89f4))
|
||||
* **language-service:** diagnostic and definition should work for absolute url ([#40406](https://github.com/angular/angular/issues/40406)) ([625d2c2](https://github.com/angular/angular/commit/625d2c2))
|
||||
* **language-service:** reinstate overridden compiler option after change ([#40364](https://github.com/angular/angular/issues/40364)) ([811cacc](https://github.com/angular/angular/commit/811cacc))
|
||||
* **language-service:** Support 'find references' for two-way bindings ([#40185](https://github.com/angular/angular/issues/40185)) ([ebb7ac5](https://github.com/angular/angular/commit/ebb7ac5))
|
||||
* **language-service:** Support 'go to definition' for two-way bindings ([#40185](https://github.com/angular/angular/issues/40185)) ([a9d8c22](https://github.com/angular/angular/commit/a9d8c22))
|
||||
* **language-service:** Support completions of two-way bindings ([#40185](https://github.com/angular/angular/issues/40185)) ([7d74853](https://github.com/angular/angular/commit/7d74853))
|
||||
* **language-service:** Do not include $event parameter in reference results ([#40158](https://github.com/angular/angular/issues/40158)) ([d466db8](https://github.com/angular/angular/commit/d466db8)), closes [#40157](https://github.com/angular/angular/issues/40157)
|
||||
* **language-service:** include compilerOptions.rootDir in rootDirs ([#40243](https://github.com/angular/angular/issues/40243)) ([a62416c](https://github.com/angular/angular/commit/a62416c)), closes [angular/vscode-ng-language-service#1039](https://github.com/angular/vscode-ng-language-service/issues/1039)
|
||||
* **language-service:** LSParseConfigHost.resolve should not concat abs paths ([#40242](https://github.com/angular/angular/issues/40242)) ([0264f76](https://github.com/angular/angular/commit/0264f76))
|
||||
* **language-service:** return all typecheck files via getExternalFiles ([#40162](https://github.com/angular/angular/issues/40162)) ([183fb7e](https://github.com/angular/angular/commit/183fb7e))
|
||||
* **language-service:** shorthand syntax with variables ([#40239](https://github.com/angular/angular/issues/40239)) ([12cb39c](https://github.com/angular/angular/commit/12cb39c))
|
||||
* **language-service:** force compileNonExportedClasses: false in LS ([#40092](https://github.com/angular/angular/issues/40092)) ([028e4f7](https://github.com/angular/angular/commit/028e4f7))
|
||||
* **language-service:** Prevent matching nodes after finding a keySpan ([#40047](https://github.com/angular/angular/issues/40047)) ([1bf1b68](https://github.com/angular/angular/commit/1bf1b68))
|
||||
* **language-service:** do not return external template that does not exist ([#39898](https://github.com/angular/angular/issues/39898)) ([2b84882](https://github.com/angular/angular/commit/2b84882))
|
||||
* **language-service:** do not treat file URIs as general URLs ([#39917](https://github.com/angular/angular/issues/39917)) ([3b70098](https://github.com/angular/angular/commit/3b70098))
|
||||
* **localize:** ensure extracted messages are serialized in a consistent order ([#40192](https://github.com/angular/angular/issues/40192)) ([212245f](https://github.com/angular/angular/commit/212245f)), closes [#39262](https://github.com/angular/angular/issues/39262)
|
||||
* **ngcc:** copy (and update) source-maps for unmodified source files ([#40429](https://github.com/angular/angular/issues/40429)) ([e2e3862](https://github.com/angular/angular/commit/e2e3862)), closes [#40358](https://github.com/angular/angular/issues/40358)
|
||||
* **service-worker:** handle error with ErrorHandler ([#39990](https://github.com/angular/angular/issues/39990)) ([74e42cf](https://github.com/angular/angular/commit/74e42cf)), closes [#39913](https://github.com/angular/angular/issues/39913)
|
||||
* **router:** correctly handle string command in outlets ([#39728](https://github.com/angular/angular/issues/39728)) ([c33a823](https://github.com/angular/angular/commit/c33a823)), closes [#18928](https://github.com/angular/angular/issues/18928)
|
||||
* **router:** lazy loaded modules without RouterModule.forChild() won't cause an infinite loop ([#36605](https://github.com/angular/angular/issues/36605)) ([6675b6f](https://github.com/angular/angular/commit/6675b6f)), closes [#29164](https://github.com/angular/angular/issues/29164)
|
||||
* **router:** remove duplicated getOutlet function ([#39764](https://github.com/angular/angular/issues/39764)) ([5fa7673](https://github.com/angular/angular/commit/5fa7673))
|
||||
* **service-worker:** correctly handle failed cache-busted request ([#39786](https://github.com/angular/angular/issues/39786)) ([6046419](https://github.com/angular/angular/commit/6046419)), closes [#39775](https://github.com/angular/angular/issues/39775) [#39775](https://github.com/angular/angular/issues/39775)
|
||||
* **upgrade:** avoid memory leak when removing downgraded components ([#39965](https://github.com/angular/angular/issues/39965)) ([6dc43a4](https://github.com/angular/angular/commit/6dc43a4)), closes [#26209](https://github.com/angular/angular/issues/26209) [#39911](https://github.com/angular/angular/issues/39911) [#39921](https://github.com/angular/angular/issues/39921)
|
||||
* **upgrade:** fix HMR for hybrid applications ([#40045](https://github.com/angular/angular/issues/40045)) ([b4b21bd](https://github.com/angular/angular/commit/b4b21bd)), closes [#39935](https://github.com/angular/angular/issues/39935)
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **animations:** use `ngDevMode` to tree-shake warning ([#39964](https://github.com/angular/angular/issues/39964)) ([9ebe423](https://github.com/angular/angular/commit/9ebe423))
|
||||
* **common:** use `ngDevMode` to tree-shake warnings ([#39964](https://github.com/angular/angular/issues/39964)) ([f022efa](https://github.com/angular/angular/commit/f022efa))
|
||||
* **core:** use `ngDevMode` to tree-shake `checkNoChanges` ([#39964](https://github.com/angular/angular/issues/39964)) ([e1fe9ec](https://github.com/angular/angular/commit/e1fe9ec))
|
||||
* **core:** use `ngDevMode` to tree-shake warnings ([#39959](https://github.com/angular/angular/issues/39959)) ([8b0cccc](https://github.com/angular/angular/commit/8b0cccc))
|
||||
* **core:** make DI decorators tree-shakable when used for `useFactory` deps config ([#40145](https://github.com/angular/angular/issues/40145)) ([0664d75](https://github.com/angular/angular/commit/0664d75)), closes [#40143](https://github.com/angular/angular/issues/40143)
|
||||
* **forms:** use `ngDevMode` to tree-shake `_ngModelWarning` ([#39964](https://github.com/angular/angular/issues/39964)) ([7954c8d](https://github.com/angular/angular/commit/7954c8d))
|
||||
* **ngcc:** do not copy files that have been processed ([#40429](https://github.com/angular/angular/issues/40429)) ([798aae4](https://github.com/angular/angular/commit/798aae4))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **common:** allow any Subscribable in async pipe ([#39627](https://github.com/angular/angular/issues/39627)) ([c7f4abf](https://github.com/angular/angular/commit/c7f4abf))
|
||||
* **compiler:** recover expression parsing in more malformed pipe cases ([#39437](https://github.com/angular/angular/issues/39437)) ([e336572](https://github.com/angular/angular/commit/e336572))
|
||||
* **compiler:** support recovery of malformed property writes ([#39103](https://github.com/angular/angular/issues/39103)) ([e44e10b](https://github.com/angular/angular/commit/e44e10b))
|
||||
* **compiler:** add schema for Trusted Types sinks ([#39554](https://github.com/angular/angular/issues/39554)) ([358c50e](https://github.com/angular/angular/commit/358c50e))
|
||||
* **compiler:** support error reporting in I18nMetaVisitor ([#39554](https://github.com/angular/angular/issues/39554)) ([bb70a9b](https://github.com/angular/angular/commit/bb70a9b))
|
||||
* **compiler:** support tagged template literals in code generator ([#39122](https://github.com/angular/angular/issues/39122)) ([ef89274](https://github.com/angular/angular/commit/ef89274))
|
||||
* **compiler:** allow trailing comma in array literal ([#22277](https://github.com/angular/angular/issues/22277)) ([8d613c1](https://github.com/angular/angular/commit/8d613c1)), closes [#20773](https://github.com/angular/angular/issues/20773)
|
||||
* **compiler-cli:** implement partial directive declaration linking ([#39518](https://github.com/angular/angular/issues/39518)) ([87e9cd6](https://github.com/angular/angular/commit/87e9cd6))
|
||||
* **compiler-cli:** partial compilation of directives ([#39518](https://github.com/angular/angular/issues/39518)) ([8c0a92b](https://github.com/angular/angular/commit/8c0a92b))
|
||||
* **compiler-cli:** add support for using TypeScript 4.1 ([#39571](https://github.com/angular/angular/issues/39571)) ([a7e7c21](https://github.com/angular/angular/commit/a7e7c21))
|
||||
* **compiler-cli:** support for partial compilation of components ([#39707](https://github.com/angular/angular/issues/39707)) ([e75244e](https://github.com/angular/angular/commit/e75244e))
|
||||
* **compiler-cli:** expose function to allow short-circuiting of linking ([#40137](https://github.com/angular/angular/issues/40137)) ([7dcf286](https://github.com/angular/angular/commit/7dcf286))
|
||||
* **compiler-cli:** JIT compilation of component declarations ([#40127](https://github.com/angular/angular/issues/40127)) ([d4327d5](https://github.com/angular/angular/commit/d4327d5))
|
||||
* **compiler-cli:** JIT compilation of directive declarations ([#40101](https://github.com/angular/angular/issues/40101)) ([9186f1f](https://github.com/angular/angular/commit/9186f1f))
|
||||
* **core:** add shouldCoalesceRunChangeDetection option to coalesce change detections in the same event loop. ([#39422](https://github.com/angular/angular/issues/39422)) ([5e92d64](https://github.com/angular/angular/commit/5e92d64)), closes [#39348](https://github.com/angular/angular/issues/39348) [#39348](https://github.com/angular/angular/issues/39348)
|
||||
* **core:** adds get method to QueryList ([#36907](https://github.com/angular/angular/issues/36907)) ([a965589](https://github.com/angular/angular/commit/a965589)), closes [#29467](https://github.com/angular/angular/issues/29467)
|
||||
* **core:** Add schematic to fix invalid `Route` configs ([#40067](https://github.com/angular/angular/issues/40067)) ([805b4f9](https://github.com/angular/angular/commit/805b4f9))
|
||||
* **language-service:** log Angular compiler options ([#40364](https://github.com/angular/angular/issues/40364)) ([6a9e328](https://github.com/angular/angular/commit/6a9e328))
|
||||
* **language-service:** autocomplete pipe binding expressions ([#40032](https://github.com/angular/angular/issues/40032)) ([cbb6eae](https://github.com/angular/angular/commit/cbb6eae))
|
||||
* **language-service:** autocompletion of element tags ([#40032](https://github.com/angular/angular/issues/40032)) ([e42250f](https://github.com/angular/angular/commit/e42250f))
|
||||
* **language-service:** autocompletion within expression contexts ([#39727](https://github.com/angular/angular/issues/39727)) ([93a8326](https://github.com/angular/angular/commit/93a8326))
|
||||
* **language-service:** complete attributes on elements ([#40032](https://github.com/angular/angular/issues/40032)) ([66378ed](https://github.com/angular/angular/commit/66378ed))
|
||||
* **language-service:** completions for structural directives ([#40032](https://github.com/angular/angular/issues/40032)) ([2a74431](https://github.com/angular/angular/commit/2a74431))
|
||||
* **language-service:** enable get references for directive and component from template ([#40054](https://github.com/angular/angular/issues/40054)) ([973f797](https://github.com/angular/angular/commit/973f797))
|
||||
* **language-service:** Add "find references" capability to Ivy integrated LS ([#39768](https://github.com/angular/angular/issues/39768)) ([06a782a](https://github.com/angular/angular/commit/06a782a))
|
||||
* **language-service:** implement autocompletion for global properties (Ivy) ([#39250](https://github.com/angular/angular/issues/39250)) ([28a0bcb](https://github.com/angular/angular/commit/28a0bcb))
|
||||
* **language-service:** Implement go to definition for style and template urls ([#39202](https://github.com/angular/angular/issues/39202)) ([563fb6c](https://github.com/angular/angular/commit/563fb6c))
|
||||
* **localize:** support Application Resource Bundle (ARB) translation file format ([#36795](https://github.com/angular/angular/issues/36795)) ([5684ac5](https://github.com/angular/angular/commit/5684ac5))
|
||||
* **platform-browser:** add doubletap HammerJS support ([#26362](https://github.com/angular/angular/issues/26362)) ([b5c0f9d](https://github.com/angular/angular/commit/b5c0f9d)), closes [#23954](https://github.com/angular/angular/issues/23954)
|
||||
* **router:** add `relativeTo` as an input to `routerLink` ([#39720](https://github.com/angular/angular/issues/39720)) ([112324a](https://github.com/angular/angular/commit/112324a)), closes [#13523](https://github.com/angular/angular/issues/13523)
|
||||
|
||||
|
||||
|
||||
<a name="11.0.9"></a>
|
||||
## 11.0.9 (2021-01-13)
|
||||
|
||||
@@ -36,30 +205,6 @@
|
||||
|
||||
|
||||
|
||||
<a name="11.1.0-next.4"></a>
|
||||
# 11.1.0-next.4 (2021-01-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **forms:** clean up connection between FormControl/FormGroup and corresponding directive instances ([#39235](https://github.com/angular/angular/issues/39235)) ([a384961](https://github.com/angular/angular/commit/a384961)), closes [#20007](https://github.com/angular/angular/issues/20007) [#37431](https://github.com/angular/angular/issues/37431) [#39590](https://github.com/angular/angular/issues/39590)
|
||||
* **language-service:** Do not include $event parameter in reference results ([#40158](https://github.com/angular/angular/issues/40158)) ([d466db8](https://github.com/angular/angular/commit/d466db8)), closes [#40157](https://github.com/angular/angular/issues/40157)
|
||||
* **language-service:** include compilerOptions.rootDir in rootDirs ([#40243](https://github.com/angular/angular/issues/40243)) ([a62416c](https://github.com/angular/angular/commit/a62416c)), closes [angular/vscode-ng-language-service#1039](https://github.com/angular/vscode-ng-language-service/issues/1039)
|
||||
* **language-service:** LSParseConfigHost.resolve should not concat abs paths ([#40242](https://github.com/angular/angular/issues/40242)) ([0264f76](https://github.com/angular/angular/commit/0264f76))
|
||||
* **language-service:** return all typecheck files via getExternalFiles ([#40162](https://github.com/angular/angular/issues/40162)) ([183fb7e](https://github.com/angular/angular/commit/183fb7e))
|
||||
* **language-service:** shorthand syntax with variables ([#40239](https://github.com/angular/angular/issues/40239)) ([12cb39c](https://github.com/angular/angular/commit/12cb39c))
|
||||
* **localize:** ensure extracted messages are serialized in a consistent order ([#40192](https://github.com/angular/angular/issues/40192)) ([212245f](https://github.com/angular/angular/commit/212245f)), closes [#39262](https://github.com/angular/angular/issues/39262)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **compiler-cli:** expose function to allow short-circuiting of linking ([#40137](https://github.com/angular/angular/issues/40137)) ([7dcf286](https://github.com/angular/angular/commit/7dcf286))
|
||||
* **compiler-cli:** JIT compilation of component declarations ([#40127](https://github.com/angular/angular/issues/40127)) ([d4327d5](https://github.com/angular/angular/commit/d4327d5))
|
||||
* **compiler-cli:** JIT compilation of directive declarations ([#40101](https://github.com/angular/angular/issues/40101)) ([9186f1f](https://github.com/angular/angular/commit/9186f1f))
|
||||
* **core:** Add schematic to fix invalid `Route` configs ([#40067](https://github.com/angular/angular/issues/40067)) ([805b4f9](https://github.com/angular/angular/commit/805b4f9))
|
||||
|
||||
|
||||
|
||||
<a name="11.0.6"></a>
|
||||
## 11.0.6 (2021-01-06)
|
||||
|
||||
@@ -91,32 +236,6 @@
|
||||
* **core:** set `ngDevMode` to `false` when calling `enableProdMode()` ([#40124](https://github.com/angular/angular/issues/40124)) ([922f492](https://github.com/angular/angular/commit/922f492))
|
||||
* **upgrade:** fix HMR for hybrid applications ([#40045](https://github.com/angular/angular/issues/40045)) ([c4c7509](https://github.com/angular/angular/commit/c4c7509)), closes [#39935](https://github.com/angular/angular/issues/39935)
|
||||
|
||||
<a name="11.1.0-next.3"></a>
|
||||
# 11.1.0-next.3 (2020-12-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **compiler:** avoid duplicate i18n blocks for i18n attrs on elements with structural directives ([#40077](https://github.com/angular/angular/issues/40077)) ([caa4666](https://github.com/angular/angular/commit/caa4666)), closes [#39942](https://github.com/angular/angular/issues/39942)
|
||||
* **compiler:** handle strings inside bindings that contain binding characters ([#39826](https://github.com/angular/angular/issues/39826)) ([dc6d40e](https://github.com/angular/angular/commit/dc6d40e)), closes [#39601](https://github.com/angular/angular/issues/39601)
|
||||
* **compiler-cli:** remove classes in .d.ts files from provider checks ([#40118](https://github.com/angular/angular/issues/40118)) ([973bb40](https://github.com/angular/angular/commit/973bb40))
|
||||
* **core:** fix possible XSS attack in development through SSR. ([#40136](https://github.com/angular/angular/issues/40136)) ([47d9b6d](https://github.com/angular/angular/commit/47d9b6d))
|
||||
* **core:** set `ngDevMode` to `false` when calling `enableProdMode()` ([#40124](https://github.com/angular/angular/issues/40124)) ([70b4816](https://github.com/angular/angular/commit/70b4816))
|
||||
* **language-service:** force compileNonExportedClasses: false in LS ([#40092](https://github.com/angular/angular/issues/40092)) ([028e4f7](https://github.com/angular/angular/commit/028e4f7))
|
||||
* **language-service:** Prevent matching nodes after finding a keySpan ([#40047](https://github.com/angular/angular/issues/40047)) ([1bf1b68](https://github.com/angular/angular/commit/1bf1b68))
|
||||
* **upgrade:** fix HMR for hybrid applications ([#40045](https://github.com/angular/angular/issues/40045)) ([b4b21bd](https://github.com/angular/angular/commit/b4b21bd)), closes [#39935](https://github.com/angular/angular/issues/39935)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **language-service:** autocomplete pipe binding expressions ([#40032](https://github.com/angular/angular/issues/40032)) ([cbb6eae](https://github.com/angular/angular/commit/cbb6eae))
|
||||
* **language-service:** autocompletion of element tags ([#40032](https://github.com/angular/angular/issues/40032)) ([e42250f](https://github.com/angular/angular/commit/e42250f))
|
||||
* **language-service:** autocompletion within expression contexts ([#39727](https://github.com/angular/angular/issues/39727)) ([93a8326](https://github.com/angular/angular/commit/93a8326))
|
||||
* **language-service:** complete attributes on elements ([#40032](https://github.com/angular/angular/issues/40032)) ([66378ed](https://github.com/angular/angular/commit/66378ed))
|
||||
* **language-service:** completions for structural directives ([#40032](https://github.com/angular/angular/issues/40032)) ([2a74431](https://github.com/angular/angular/commit/2a74431))
|
||||
* **language-service:** enable get references for directive and component from template ([#40054](https://github.com/angular/angular/issues/40054)) ([973f797](https://github.com/angular/angular/commit/973f797))
|
||||
* **router:** add `relativeTo` as an input to `routerLink` ([#39720](https://github.com/angular/angular/issues/39720)) ([112324a](https://github.com/angular/angular/commit/112324a)), closes [#13523](https://github.com/angular/angular/issues/13523)
|
||||
|
||||
|
||||
|
||||
<a name="11.0.4"></a>
|
||||
@@ -147,43 +266,6 @@
|
||||
|
||||
|
||||
|
||||
<a name="11.1.0-next.2"></a>
|
||||
# 11.1.0-next.2 (2020-12-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **animations:** implement getPosition in browser animation builder ([#39983](https://github.com/angular/angular/issues/39983)) ([ca08625](https://github.com/angular/angular/commit/ca08625))
|
||||
* **compiler-cli:** correct incremental behavior even with broken imports ([#39923](https://github.com/angular/angular/issues/39923)) ([c7c5b2f](https://github.com/angular/angular/commit/c7c5b2f))
|
||||
* **compiler-cli:** remove the concept of an errored trait ([#39923](https://github.com/angular/angular/issues/39923)) ([6d42954](https://github.com/angular/angular/commit/6d42954))
|
||||
* **compiler-cli:** track poisoned scopes with a flag ([#39923](https://github.com/angular/angular/issues/39923)) ([0823622](https://github.com/angular/angular/commit/0823622))
|
||||
* **core:** remove application from the testability registry when the root view is removed ([#39876](https://github.com/angular/angular/issues/39876)) ([df27027](https://github.com/angular/angular/commit/df27027)), closes [#22106](https://github.com/angular/angular/issues/22106)
|
||||
* **core:** Support extending differs from root `NgModule` ([#39981](https://github.com/angular/angular/issues/39981)) ([5fc4508](https://github.com/angular/angular/commit/5fc4508)), closes [#25015](https://github.com/angular/angular/issues/25015) [#11309](https://github.com/angular/angular/issues/11309) [#18554](https://github.com/angular/angular/issues/18554)
|
||||
* **core:** unsubscribe from the `onError` when the root view is removed ([#39940](https://github.com/angular/angular/issues/39940)) ([5a3a154](https://github.com/angular/angular/commit/5a3a154))
|
||||
* **language-service:** do not return external template that does not exist ([#39898](https://github.com/angular/angular/issues/39898)) ([2b84882](https://github.com/angular/angular/commit/2b84882))
|
||||
* **language-service:** do not treat file URIs as general URLs ([#39917](https://github.com/angular/angular/issues/39917)) ([3b70098](https://github.com/angular/angular/commit/3b70098))
|
||||
* **service-worker:** handle error with ErrorHandler ([#39990](https://github.com/angular/angular/issues/39990)) ([74e42cf](https://github.com/angular/angular/commit/74e42cf)), closes [#39913](https://github.com/angular/angular/issues/39913)
|
||||
* **upgrade:** avoid memory leak when removing downgraded components ([#39965](https://github.com/angular/angular/issues/39965)) ([6dc43a4](https://github.com/angular/angular/commit/6dc43a4)), closes [#26209](https://github.com/angular/angular/issues/26209) [#39911](https://github.com/angular/angular/issues/39911) [#39921](https://github.com/angular/angular/issues/39921)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **compiler:** allow trailing comma in array literal ([#22277](https://github.com/angular/angular/issues/22277)) ([8d613c1](https://github.com/angular/angular/commit/8d613c1)), closes [#20773](https://github.com/angular/angular/issues/20773)
|
||||
* **compiler:** support tagged template literals in code generator ([#39122](https://github.com/angular/angular/issues/39122)) ([ef89274](https://github.com/angular/angular/commit/ef89274))
|
||||
* **language-service:** Add "find references" capability to Ivy integrated LS ([#39768](https://github.com/angular/angular/issues/39768)) ([06a782a](https://github.com/angular/angular/commit/06a782a))
|
||||
* **language-service:** implement autocompletion for global properties (Ivy) ([#39250](https://github.com/angular/angular/issues/39250)) ([28a0bcb](https://github.com/angular/angular/commit/28a0bcb))
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **animations:** use `ngDevMode` to tree-shake warning ([#39964](https://github.com/angular/angular/issues/39964)) ([9ebe423](https://github.com/angular/angular/commit/9ebe423))
|
||||
* **common:** use `ngDevMode` to tree-shake warnings ([#39964](https://github.com/angular/angular/issues/39964)) ([f022efa](https://github.com/angular/angular/commit/f022efa))
|
||||
* **core:** use `ngDevMode` to tree-shake `checkNoChanges` ([#39964](https://github.com/angular/angular/issues/39964)) ([e1fe9ec](https://github.com/angular/angular/commit/e1fe9ec))
|
||||
* **core:** use `ngDevMode` to tree-shake warnings ([#39959](https://github.com/angular/angular/issues/39959)) ([8b0cccc](https://github.com/angular/angular/commit/8b0cccc))
|
||||
* **forms:** use `ngDevMode` to tree-shake `_ngModelWarning` ([#39964](https://github.com/angular/angular/issues/39964)) ([7954c8d](https://github.com/angular/angular/commit/7954c8d))
|
||||
|
||||
|
||||
|
||||
<a name="11.0.3"></a>
|
||||
## 11.0.3 (2020-12-02)
|
||||
|
||||
@@ -211,43 +293,6 @@
|
||||
* **forms:** Mark the {[key: string]: any} type for the options property of the FormBuilder.group method as deprecated. Using AbstractControlOptions gives the same functionality and is type-safe.
|
||||
|
||||
|
||||
<a name="11.1.0-next.1"></a>
|
||||
# 11.1.0-next.1 (2020-12-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **animations:** getAnimationStyle causes exceptions in older browsers ([#29709](https://github.com/angular/angular/issues/29709)) ([66d863f](https://github.com/angular/angular/commit/66d863f))
|
||||
* **animations:** replace copy of query selector node-list from "spread" to "for" ([#39646](https://github.com/angular/angular/issues/39646)) ([bfa197f](https://github.com/angular/angular/commit/bfa197f)), closes [#38551](https://github.com/angular/angular/issues/38551)
|
||||
* **common:** Prefer to use pageXOffset / pageYOffset instance of scrollX / scrollY ([#28262](https://github.com/angular/angular/issues/28262)) ([b1d300d](https://github.com/angular/angular/commit/b1d300d))
|
||||
* **compiler:** disallow i18n of security-sensitive attributes ([#39554](https://github.com/angular/angular/issues/39554)) ([c8a99ef](https://github.com/angular/angular/commit/c8a99ef))
|
||||
* **compiler:** ensure that placeholders have the correct sourceSpan ([#39717](https://github.com/angular/angular/issues/39717)) ([0462a61](https://github.com/angular/angular/commit/0462a61)), closes [#39671](https://github.com/angular/angular/issues/39671)
|
||||
* **compiler:** only promote Trusted Types to constants when necessary ([#39554](https://github.com/angular/angular/issues/39554)) ([4916870](https://github.com/angular/angular/commit/4916870))
|
||||
* **compiler:** report better error on interpolation in an expression ([#30300](https://github.com/angular/angular/issues/30300)) ([94e790d](https://github.com/angular/angular/commit/94e790d))
|
||||
* **compiler-cli:** report error when a reference target is missing instead of crashing ([#39805](https://github.com/angular/angular/issues/39805)) ([453b32f](https://github.com/angular/angular/commit/453b32f)), closes [#38618](https://github.com/angular/angular/issues/38618) [#39744](https://github.com/angular/angular/issues/39744)
|
||||
* **core:** Allow passing AbstractType to the inject function ([#37958](https://github.com/angular/angular/issues/37958)) ([a1b6ad0](https://github.com/angular/angular/commit/a1b6ad0))
|
||||
* **core:** Ensure OnPush ancestors are marked dirty when events occur ([#39833](https://github.com/angular/angular/issues/39833)) ([68d4a74](https://github.com/angular/angular/commit/68d4a74)), closes [#39832](https://github.com/angular/angular/issues/39832)
|
||||
* **core:** meta addTag() adds incorrect attribute for httpEquiv ([#32531](https://github.com/angular/angular/issues/32531)) ([ff0a90e](https://github.com/angular/angular/commit/ff0a90e))
|
||||
* **core:** migration error if program contains files outside of the project ([#39790](https://github.com/angular/angular/issues/39790)) ([1a26f6d](https://github.com/angular/angular/commit/1a26f6d)), closes [#39778](https://github.com/angular/angular/issues/39778)
|
||||
* **core:** not invoking object's toString when rendering to the DOM ([#39843](https://github.com/angular/angular/issues/39843)) ([11cd37f](https://github.com/angular/angular/commit/11cd37f)), closes [#38839](https://github.com/angular/angular/issues/38839)
|
||||
* **core:** remove duplicated noop function ([#39761](https://github.com/angular/angular/issues/39761)) ([066126a](https://github.com/angular/angular/commit/066126a))
|
||||
* **core:** support `Attribute` DI decorator in `deps` section of a token ([#37085](https://github.com/angular/angular/issues/37085)) ([f5cbf0b](https://github.com/angular/angular/commit/f5cbf0b)), closes [#36479](https://github.com/angular/angular/issues/36479)
|
||||
* **router:** correctly handle string command in outlets ([#39728](https://github.com/angular/angular/issues/39728)) ([c33a823](https://github.com/angular/angular/commit/c33a823)), closes [#18928](https://github.com/angular/angular/issues/18928)
|
||||
* **router:** remove duplicated getOutlet function ([#39764](https://github.com/angular/angular/issues/39764)) ([5fa7673](https://github.com/angular/angular/commit/5fa7673))
|
||||
* **service-worker:** correctly handle failed cache-busted request ([#39786](https://github.com/angular/angular/issues/39786)) ([6046419](https://github.com/angular/angular/commit/6046419)), closes [#39775](https://github.com/angular/angular/issues/39775) [#39775](https://github.com/angular/angular/issues/39775)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **common:** allow any Subscribable in async pipe ([#39627](https://github.com/angular/angular/issues/39627)) ([c7f4abf](https://github.com/angular/angular/commit/c7f4abf))
|
||||
* **compiler:** add schema for Trusted Types sinks ([#39554](https://github.com/angular/angular/issues/39554)) ([358c50e](https://github.com/angular/angular/commit/358c50e))
|
||||
* **compiler:** support error reporting in I18nMetaVisitor ([#39554](https://github.com/angular/angular/issues/39554)) ([bb70a9b](https://github.com/angular/angular/commit/bb70a9b))
|
||||
* **compiler-cli:** add support for using TypeScript 4.1 ([#39571](https://github.com/angular/angular/issues/39571)) ([a7e7c21](https://github.com/angular/angular/commit/a7e7c21))
|
||||
* **compiler-cli:** support for partial compilation of components ([#39707](https://github.com/angular/angular/issues/39707)) ([e75244e](https://github.com/angular/angular/commit/e75244e))
|
||||
* **core:** adds get method to QueryList ([#36907](https://github.com/angular/angular/issues/36907)) ([a965589](https://github.com/angular/angular/commit/a965589)), closes [#29467](https://github.com/angular/angular/issues/29467)
|
||||
* **localize:** support Application Resource Bundle (ARB) translation file format ([#36795](https://github.com/angular/angular/issues/36795)) ([5684ac5](https://github.com/angular/angular/commit/5684ac5))
|
||||
* **platform-browser:** add doubletap HammerJS support ([#26362](https://github.com/angular/angular/issues/26362)) ([b5c0f9d](https://github.com/angular/angular/commit/b5c0f9d)), closes [#23954](https://github.com/angular/angular/issues/23954)
|
||||
|
||||
|
||||
<a name="11.0.2"></a>
|
||||
## 11.0.2 (2020-11-19)
|
||||
@@ -259,26 +304,6 @@
|
||||
|
||||
|
||||
|
||||
<a name="11.1.0-next.0"></a>
|
||||
# 11.1.0-next.0 (2020-11-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **common:** add `HttpParamsOptions` to the public api ([#35829](https://github.com/angular/angular/issues/35829)) ([b33b89d](https://github.com/angular/angular/commit/b33b89d)), closes [#20276](https://github.com/angular/angular/issues/20276)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **compiler:** recover expression parsing in more malformed pipe cases ([#39437](https://github.com/angular/angular/issues/39437)) ([e336572](https://github.com/angular/angular/commit/e336572))
|
||||
* **compiler:** support recovery of malformed property writes ([#39103](https://github.com/angular/angular/issues/39103)) ([e44e10b](https://github.com/angular/angular/commit/e44e10b))
|
||||
* **compiler-cli:** implement partial directive declaration linking ([#39518](https://github.com/angular/angular/issues/39518)) ([87e9cd6](https://github.com/angular/angular/commit/87e9cd6))
|
||||
* **compiler-cli:** partial compilation of directives ([#39518](https://github.com/angular/angular/issues/39518)) ([8c0a92b](https://github.com/angular/angular/commit/8c0a92b))
|
||||
* **core:** add shouldCoalesceRunChangeDetection option to coalesce change detections in the same event loop. ([#39422](https://github.com/angular/angular/issues/39422)) ([5e92d64](https://github.com/angular/angular/commit/5e92d64)), closes [#39348](https://github.com/angular/angular/issues/39348) [#39348](https://github.com/angular/angular/issues/39348)
|
||||
* **language-service:** Implement go to definition for style and template urls ([#39202](https://github.com/angular/angular/issues/39202)) ([563fb6c](https://github.com/angular/angular/commit/563fb6c))
|
||||
|
||||
|
||||
|
||||
<a name="11.0.1"></a>
|
||||
## 11.0.1 (2020-11-18)
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
# Fetch rules_nodejs so we can install our npm dependencies
|
||||
http_archive(
|
||||
name = "build_bazel_rules_nodejs",
|
||||
sha256 = "4952ef879704ab4ad6729a29007e7094aef213ea79e9f2e94cbe1c9a753e63ef",
|
||||
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/2.2.0/rules_nodejs-2.2.0.tar.gz"],
|
||||
sha256 = "9d93d4e1340c43dbf6b2fd66b683d89630a6310bf8be3bf40ec96685dcacc26c",
|
||||
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/2.3.3/rules_nodejs-2.3.3.tar.gz"],
|
||||
)
|
||||
|
||||
# Check the rules_nodejs version and download npm dependencies
|
||||
@@ -76,7 +76,7 @@ rbe_autoconfig(
|
||||
# Need to specify a base container digest in order to ensure that we can use the checked-in
|
||||
# platform configurations for the "ubuntu16_04" image. Otherwise the autoconfig rule would
|
||||
# need to pull the image and run it in order determine the toolchain configuration. See:
|
||||
# https://github.com/bazelbuild/bazel-toolchains/blob/3.6.0/configs/ubuntu16_04_clang/versions.bzl
|
||||
# https://github.com/bazelbuild/bazel-toolchains/blob/4.0.0/configs/ubuntu16_04_clang/versions.bzl
|
||||
base_container_digest = "sha256:f6568d8168b14aafd1b707019927a63c2d37113a03bcee188218f99bd0327ea1",
|
||||
# Note that if you change the `digest`, you might also need to update the
|
||||
# `base_container_digest` to make sure marketplace.gcr.io/google/rbe-ubuntu16-04-webtest:<digest>
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
@name Expression Changed After Checked
|
||||
@category runtime
|
||||
@videoUrl https://www.youtube.com/embed/O47uUnJjbJc
|
||||
@shortDescription Expression has changed after it was checked
|
||||
|
||||
@description
|
||||
Angular throws an `ExpressionChangedAfterItHasBeenCheckedError` when an expression value has been changed after change detection has completed. Angular only throws this error in development mode.
|
||||
|
||||
In dev mode, Angular performs an additional check after each change detection run, to ensure the bindings haven’t changed. This catches errors where the view is left in an inconsistent state. This can occur, for example, if a method or getter returns a different value each time it is called, or if a child component changes values on its parent. If either of these occur, this is a sign that change detection is not stabilized. Angular throws the error to ensure data is always reflected correctly in the view, which prevents erratic UI behavior or a possible infinite loop.
|
||||
|
||||
This error commonly occurs when you’ve added template expressions or begun to implement lifecycle hooks like `ngAfterViewInit` or `ngOnChanges`. It is also common when dealing with loading status and asynchronous operations, or a child component changes its parent bindings.
|
||||
|
||||
@debugging
|
||||
The [source maps](https://developer.mozilla.org/en-US/docs/Tools/Debugger/How_to/Use_a_source_map) generated by the CLI are very useful when debugging. Navigate up the call stack until you find a template expression where the value displayed in the error has changed.
|
||||
|
||||
Ensure that there are no changes to the bindings in the template after change detection is run. This often means refactoring to use the correct [component lifecycle hook](https://angular.io/guide/lifecycle-hooks) for your use case. If the issue exists within `ngAfterViewInit`, the recommended solution is to use a constructor or `ngOnInit` to set initial values, or use `ngAfterContentInit` for other value bindings.
|
||||
|
||||
If you are binding to methods in the view, ensure that the invocation does not update any of the other bindings in the template.
|
||||
|
||||
Read more about which solution is right for you in ['Everything you need to know about the "ExpressionChangedAfterItHasBeenCheckedError" error'](https://indepth.dev/everything-you-need-to-know-about-the-expressionchangedafterithasbeencheckederror-error/) and why this is useful at ['Angular Debugging "Expression has changed after it was checked": Simple Explanation (and Fix)'](https://blog.angular-university.io/angular-debugging/).
|
||||
@@ -0,0 +1,12 @@
|
||||
@name Circular Dependency in DI
|
||||
@category runtime
|
||||
@videoUrl https://www.youtube.com/embed/CpLOm4o_FzM
|
||||
@shortDescription Circular dependency in DI detected while instantiating a provider
|
||||
|
||||
@description
|
||||
A cyclic dependency exists when a [dependency of a service](https://angular.io/guide/hierarchical-dependency-injection) directly or indirectly depends on the service itself. For example, if `UserService` depends on `EmployeeService`, which also depends on `UserService`. Angular will have to instantiate `EmployeeService` to create `UserService`, which depends on `UserService`, itself.
|
||||
|
||||
@debugging
|
||||
Use the call stack to determine where the cyclical dependency exists. You will be able to see if any child dependencies rely on the original file by [mapping out](https://angular.io/guide/dependency-injection-in-action) the component, module, or service’s dependencies and identify the loop causing the problem.
|
||||
|
||||
Break this loop (or circle) of dependency to resolve this error. This most commonly means removing or refactoring the dependencies to not be reliant on one another.
|
||||
@@ -0,0 +1,20 @@
|
||||
@name No Provider Found
|
||||
@category runtime
|
||||
@videoUrl https://www.youtube.com/embed/lAlOryf1-WU
|
||||
@shortDescription No provider for {token} found!
|
||||
|
||||
@description
|
||||
You see this error when you try to inject a service but have not declared a corresponding provider. A provider is a mapping that supplies a value that you can inject into the constructor of a class in your application.
|
||||
|
||||
Read more on providers in our [Dependency Injection guide](https://angular.io/guide/dependency-injection).
|
||||
|
||||
@debugging
|
||||
Work backwards from the object where the error states that a [provider](https://angular.io/guide/architecture-services) is missing: `No provider for ${this}!`. This is commonly thrown in [services](https://angular.io/tutorial/toh-pt4), which require non-existing providers.
|
||||
|
||||
To fix the error ensure that your service is registered in the list of providers of an `NgModule` or has the `@Injectable` decorator with a `providedIn` property at top.
|
||||
|
||||
The most common solution is to add a provider in `@Injectable` using `providedIn`:
|
||||
|
||||
```typescript
|
||||
@Injectable({ providedIn: 'app' })
|
||||
```
|
||||
@@ -0,0 +1,21 @@
|
||||
@name Selector Collision
|
||||
@category runtime
|
||||
@videoUrl https://www.youtube.com/embed/z_3Z5mOm59I
|
||||
@shortDescription Multiple components match with the same tagname
|
||||
|
||||
@description
|
||||
Two or more components use the same [element selector](https://angular.io/guide/component-overview#specifying-a-components-css-selector). Because there can only be a single component associated with an element, selectors must be unique strings to prevent ambiguity for Angular.
|
||||
|
||||
@debugging
|
||||
Use the element name from the error message to search for places where you’re using the same [selector declaration](https://angular.io/guide/architecture-components) in your codebase:
|
||||
|
||||
```typescript
|
||||
@Component({
|
||||
selector: 'YOUR_STRING',
|
||||
...
|
||||
})
|
||||
```
|
||||
|
||||
Ensure that each component has a unique CSS selector. This will guarantee that Angular renders the component you expect.
|
||||
|
||||
If you’re having trouble finding multiple components with this selector tag name, check for components from imported component libraries, such as Angular Material. Make sure you're following the [best practices](https://angular.io/guide/styleguide#component-selectors) for your selectors to prevent collisions.
|
||||
@@ -0,0 +1,32 @@
|
||||
@name Export Not Found
|
||||
@category runtime
|
||||
@videoUrl https://www.youtube.com/embed/fUSAg4kp2WQ
|
||||
@shortDescription Export not found!
|
||||
|
||||
@description
|
||||
Angular can’t find a directive with `{{ PLACEHOLDER }}` export name. The export name is specified in the `exportAs` property of the directive decorator. This is common when using FormsModule or Material modules in templates, and you’ve forgotten to [import the corresponding modules](https://angular.io/guide/sharing-ngmodules).
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
This is the runtime equivalent of a common compiler error [NG8003: No directive found with export](errors/NG8003).
|
||||
|
||||
</div>
|
||||
|
||||
@debugging
|
||||
Use the export name to trace the templates or modules using this export.
|
||||
|
||||
Ensure that all dependencies are [properly imported and declared in your NgModules](https://angular.io/guide/sharing-ngmodules). For example, if the export not found is `ngForm`, we need to import `FormsModule` and declare it in the list of imports in `*.module.ts` to resolve the error.
|
||||
|
||||
```typescript
|
||||
import { FormsModule } from '@angular/forms';
|
||||
|
||||
@NgModule({
|
||||
...
|
||||
imports: [
|
||||
FormsModule,
|
||||
…
|
||||
```
|
||||
|
||||
If you recently added an import, you may need to restart your server to see these changes.
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
@name Pipe Not Found
|
||||
@category runtime
|
||||
@videoUrl https://www.youtube.com/embed/maI2u6Sxk9M
|
||||
@shortDescription Pipe not found!
|
||||
|
||||
@description
|
||||
Angular can't find a pipe with this name.
|
||||
The pipe referenced in the template has not been named or declared properly.
|
||||
A [pipe](guide/pipes) must be either declared or imported in the `NgModule` where it is used, and the name used in a template must match the name defined in the pipe decorator.
|
||||
|
||||
@debugging
|
||||
Use the pipe name to trace the templates or modules where this pipe is declared and used.
|
||||
|
||||
To resolve this error, ensure that:
|
||||
- A local custom pipe is uniquely named in the pipe's decorator, and declared in the `NgModule`, or
|
||||
- A pipe from another `NgModule` is added to the imports of the `NgModule` where it is used.
|
||||
|
||||
If you recently added an import or declaration, you may need to restart your server to see these changes.
|
||||
@@ -0,0 +1,29 @@
|
||||
@name Argument Not Literal
|
||||
@category compiler
|
||||
@shortDescription Decorator argument is not an object literal
|
||||
|
||||
@description
|
||||
To make the metadata extraction in the Angular compiler faster, the decorators `@NgModule`, `@Pipe`, `@Component`, `@Directive`, and `@Injectable` accept only object literals as arguments.
|
||||
|
||||
This is an [intentional change in Ivy](https://github.com/angular/angular/issues/30840#issuecomment-498869540), which enforces stricter argument requirements for decorators than View Engine. Ivy requires this approach because it compiles decorators by moving the expressions into other locations in the class output.
|
||||
|
||||
@debugging
|
||||
Move all declarations:
|
||||
|
||||
```typescript
|
||||
const moduleDefinition = {...}
|
||||
|
||||
@NgModule(moduleDefinition)
|
||||
export class AppModule {
|
||||
constructor() {}
|
||||
}
|
||||
```
|
||||
|
||||
into the decorator:
|
||||
|
||||
```typescript
|
||||
@NgModule({...})
|
||||
export class AppModule {
|
||||
constructor() {}
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,11 @@
|
||||
@name Missing Token
|
||||
@category compiler
|
||||
@shortDescription No suitable injection token for parameter
|
||||
|
||||
@description
|
||||
There is no injection token for a constructor parameter at compile time. [InjectionTokens](https://angular.io/api/core/InjectionToken) are tokens that can be used in a Dependency Injection Provider.
|
||||
|
||||
@debugging
|
||||
Look at the parameter that throws the error and all uses of the class. This error is commonly thrown when a constructor defines parameters with primitive types like `string`, `number`, `boolean`, and `Object`.
|
||||
|
||||
Use the [@Injectable](https://angular.io/api/core/Injectable) method or [@Inject](https://angular.io/api/core/Inject) decorator from `@angular/core` to ensure that the type you are injecting is reified (has a runtime representation). Make sure to add a provider to this decorator so that you do not throw [NG0201: No Provider Found](https://angular.io/errors/NG0201).
|
||||
@@ -0,0 +1,21 @@
|
||||
@name Invalid Element
|
||||
@category compiler
|
||||
@shortDescription Unknown HTML element or component
|
||||
|
||||
@description
|
||||
One or more elements cannot be resolved during compilation because the element is not defined by the HTML spec, or there is no component or directive with such element selector.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
This is the compiler equivalent of a common runtime error `NG0304: '${tagName}' is not a known element: …`.
|
||||
|
||||
</div>
|
||||
|
||||
@debugging
|
||||
Use the element name in the error to find the file(s) where the element is being used.
|
||||
|
||||
Check that the name and selector are correct. If the component is from a different module or import, check that the component is exported from its origin module and imported into the correct `*.modules.ts` file, and declared in the imports list.
|
||||
|
||||
When using custom elements or web components, ensure that you add [`CUSTOM_ELEMENTS_SCHEMA`](https://angular.io/api/core/CUSTOM_ELEMENTS_SCHEMA) to the app module.
|
||||
|
||||
If this does not resolve the error, check the imported libraries for any recent changes to the exports and properties you are using, and restart your server.
|
||||
@@ -0,0 +1,16 @@
|
||||
@name Invalid Attribute
|
||||
@category compiler
|
||||
@videoUrl https://www.youtube.com/embed/wfLkB3RsSJM
|
||||
@shortDescription Unknown attribute or input
|
||||
|
||||
@description
|
||||
An attribute or property cannot be resolved during compilation.
|
||||
|
||||
This error arises when attempting to bind to a property that does not exist. Any property binding must correspond to either:
|
||||
* A native property on the HTML element, or
|
||||
* An `@Input()` property of a component or directive applied to the element.
|
||||
|
||||
The runtime error for this is `NG0304: '${tagName}' is not a known element: …’`.
|
||||
|
||||
@debugging
|
||||
Look at documentation for the specific [binding syntax](https://angular.io/guide/binding-syntax) used. This is usually a typo or incorrect import. There may also be a missing direction with property selector ‘name’ or missing input.
|
||||
@@ -0,0 +1,31 @@
|
||||
@name Missing Reference Target
|
||||
@category compiler
|
||||
@videoUrl https://www.youtube.com/embed/fUSAg4kp2WQ
|
||||
@shortDescription No directive found with export
|
||||
|
||||
@description
|
||||
Angular can’t find a directive with `{{ PLACEHOLDER }}` export name. This is common with a missing import or a missing [`exportAs`](https://angular.io/api/core/Directive#exportAs) on a directive.
|
||||
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
This is the compiler equivalent of a common runtime error [NG0301: Export Not Found](errors/NG0301).
|
||||
|
||||
</div>
|
||||
|
||||
@debugging
|
||||
Use the string name of the export not found to trace the templates or modules using this export.
|
||||
|
||||
Ensure that all dependencies are properly imported and declared in our Modules. For example, if the export not found is `ngForm`, we will need to import `FormsModule` and declare it in our list of imports in `*.module.ts` to resolve the missing export error.
|
||||
|
||||
```typescript
|
||||
import { FormsModule } from '@angular/forms';
|
||||
|
||||
@NgModule({
|
||||
...
|
||||
imports: [
|
||||
FormsModule,
|
||||
…
|
||||
```
|
||||
|
||||
If you recently added an import, you will need to restart your server to see these changes.
|
||||
@@ -0,0 +1 @@
|
||||
# Errors List
|
||||
@@ -67,9 +67,7 @@
|
||||
<td>{{movie.hero}}</td>
|
||||
<td>{{movie.releaseDate | date}}</td>
|
||||
<td>{{movie.mpaa | uppercase}}</td>
|
||||
<!-- #docregion currency -->
|
||||
<td>{{movie.price | currency:'USD':true}}</td>
|
||||
<!-- #enddocregion currency -->
|
||||
<td>{{movie.starRating | number:'1.1-2'}}</td>
|
||||
<td>{{movie.approvalRating | percent: '1.0-0'}}</td>
|
||||
</tr>
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/* tslint:disable:no-unused-variable */
|
||||
// #docplaster
|
||||
// #docregion import
|
||||
import { Component } from '@angular/core';
|
||||
// #enddocregion import
|
||||
import { IMovie } from './movie';
|
||||
import { MovieService } from './movie.service';
|
||||
|
||||
|
||||
@@ -1,18 +1,6 @@
|
||||
// #docplaster
|
||||
// #docregion imports
|
||||
import { Component, HostBinding } from '@angular/core';
|
||||
import {
|
||||
trigger,
|
||||
state,
|
||||
style,
|
||||
animate,
|
||||
transition,
|
||||
// ...
|
||||
} from '@angular/animations';
|
||||
|
||||
// #enddocregion imports
|
||||
|
||||
// #docregion decorator, toggle-app-animations
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: 'app.component.html',
|
||||
@@ -21,15 +9,10 @@ import {
|
||||
// animation triggers go here
|
||||
]
|
||||
})
|
||||
// #enddocregion decorator
|
||||
export class AppComponent {
|
||||
@HostBinding('@.disabled')
|
||||
public animationsDisabled = false;
|
||||
// #enddocregion toggle-app-animations
|
||||
@HostBinding('@.disabled') public animationsDisabled = false;
|
||||
|
||||
toggleAnimations() {
|
||||
this.animationsDisabled = !this.animationsDisabled;
|
||||
}
|
||||
// #docregion toggle-app-animations
|
||||
}
|
||||
// #enddocregion toggle-app-animations
|
||||
|
||||
@@ -16,7 +16,6 @@ import { Hero } from './hero';
|
||||
|
||||
@Component({
|
||||
selector: 'app-hero-list-enter-leave',
|
||||
// #docregion template
|
||||
template: `
|
||||
<ul class="heroes">
|
||||
<li *ngFor="let hero of heroes"
|
||||
@@ -28,7 +27,6 @@ import { Hero } from './hero';
|
||||
</li>
|
||||
</ul>
|
||||
`,
|
||||
// #enddocregion template
|
||||
styleUrls: ['./hero-list-page.component.css'],
|
||||
// #docregion animationdef
|
||||
animations: [
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
<!-- #docplaster -->
|
||||
<nav>
|
||||
<button (click)="toggle()">Toggle Open/Close</button>
|
||||
</nav>
|
||||
|
||||
<!-- #docregion compare, trigger -->
|
||||
<div [@openClose]="isOpen ? 'open' : 'closed'"
|
||||
(@openClose.start)="onAnimationEvent($event)"
|
||||
(@openClose.done)="onAnimationEvent($event)"
|
||||
class="open-close-container">
|
||||
<p>The box is now {{ isOpen ? 'Open' : 'Closed' }}!</p>
|
||||
</div>
|
||||
<!-- #enddocregion compare, trigger -->
|
||||
|
||||
@@ -5,7 +5,7 @@ import { trigger, transition, state, animate, style, AnimationEvent } from '@ang
|
||||
// #docregion component, events1
|
||||
@Component({
|
||||
selector: 'app-open-close',
|
||||
// #docregion trigger, trigger-wildcard1, trigger-transition
|
||||
// #docregion trigger-wildcard1, trigger-transition
|
||||
animations: [
|
||||
trigger('openClose', [
|
||||
// #docregion state1
|
||||
@@ -33,7 +33,7 @@ import { trigger, transition, state, animate, style, AnimationEvent } from '@ang
|
||||
transition('closed => open', [
|
||||
animate('0.5s')
|
||||
]),
|
||||
// #enddocregion transition2, trigger, component
|
||||
// #enddocregion transition2, component
|
||||
// #docregion trigger-wildcard1
|
||||
transition('* => closed', [
|
||||
animate('1s')
|
||||
@@ -54,15 +54,14 @@ import { trigger, transition, state, animate, style, AnimationEvent } from '@ang
|
||||
),
|
||||
]),
|
||||
// #enddocregion transition4
|
||||
// #docregion transition3
|
||||
transition('* => *', [
|
||||
animate('1s')
|
||||
]),
|
||||
// #enddocregion transition3, trigger-transition
|
||||
// #docregion trigger, component, trigger-wildcard1, events1
|
||||
// #enddocregion trigger-transition
|
||||
// #docregion component, trigger-wildcard1, events1
|
||||
]),
|
||||
],
|
||||
// #enddocregion trigger, trigger-wildcard1
|
||||
// #enddocregion trigger-wildcard1
|
||||
templateUrl: 'open-close.component.html',
|
||||
styleUrls: ['open-close.component.css']
|
||||
})
|
||||
|
||||
@@ -9,6 +9,4 @@ import { Component } from '@angular/core';
|
||||
<app-sales-tax></app-sales-tax>
|
||||
`
|
||||
})
|
||||
// #docregion export
|
||||
export class AppComponent { }
|
||||
// #enddocregion export
|
||||
|
||||
@@ -22,13 +22,11 @@ import { Logger } from './logger.service';
|
||||
HeroListComponent,
|
||||
SalesTaxComponent
|
||||
],
|
||||
// #docregion providers
|
||||
providers: [
|
||||
BackendService,
|
||||
HeroService,
|
||||
Logger
|
||||
],
|
||||
// #enddocregion providers
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
// #docregion export
|
||||
|
||||
@@ -7,9 +7,7 @@ export class Logger {
|
||||
log(message: string) { console.log(message); }
|
||||
}
|
||||
|
||||
// #docregion import-core-component
|
||||
import { Component } from '@angular/core';
|
||||
// #enddocregion import-core-component
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
@@ -35,9 +33,7 @@ import { BrowserModule } from '@angular/platform-browser';
|
||||
exports: [ AppComponent ],
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
// #docregion export
|
||||
export class AppModule { }
|
||||
// #enddocregion export
|
||||
// #enddocregion module
|
||||
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
|
||||
<h1>Attribute, class, and style bindings</h1>
|
||||
<h2>Attribute binding</h2>
|
||||
<!-- #docregion attrib-binding-colspan -->
|
||||
<table border=1>
|
||||
<!-- #docregion colspan -->
|
||||
<!-- expression calculates colspan=2 -->
|
||||
@@ -18,7 +17,6 @@
|
||||
|
||||
<tr><td>Five</td><td>Six</td></tr>
|
||||
</table>
|
||||
<!-- #enddocregion attrib-binding-colspan -->
|
||||
|
||||
<div>
|
||||
<!-- #docregion attrib-binding-aria -->
|
||||
|
||||
@@ -14,19 +14,14 @@ export class HighlightDirective {
|
||||
constructor(private el: ElementRef) { }
|
||||
// #enddocregion ctor
|
||||
|
||||
// #docregion mouse-methods, host
|
||||
// #docregion mouse-methods
|
||||
@HostListener('mouseenter') onMouseEnter() {
|
||||
// #enddocregion host
|
||||
this.highlight('yellow');
|
||||
// #docregion host
|
||||
}
|
||||
|
||||
@HostListener('mouseleave') onMouseLeave() {
|
||||
// #enddocregion host
|
||||
this.highlight(null);
|
||||
// #docregion host
|
||||
}
|
||||
// #enddocregion host
|
||||
|
||||
private highlight(color: string) {
|
||||
this.el.nativeElement.style.backgroundColor = color;
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
// #docplaster
|
||||
// #docregion whole-ngmodule
|
||||
|
||||
// imports
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
@@ -32,5 +30,3 @@ import { ItemDirective } from './item.directive';
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
||||
|
||||
// #enddocregion whole-ngmodule
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { Hero } from './hero';
|
||||
|
||||
// #docregion styleurls
|
||||
@Component({
|
||||
selector: 'app-hero-details',
|
||||
template: `
|
||||
@@ -12,7 +11,5 @@ import { Hero } from './hero';
|
||||
styleUrls: ['./hero-details.component.css']
|
||||
})
|
||||
export class HeroDetailsComponent {
|
||||
// #enddocregion styleurls
|
||||
@Input() hero: Hero;
|
||||
// #docregion styleurls
|
||||
}
|
||||
|
||||
@@ -5,10 +5,8 @@ import { Component, ViewEncapsulation } from '@angular/core';
|
||||
// #docregion
|
||||
@Component({
|
||||
selector: 'app-quest-summary',
|
||||
// #docregion urls
|
||||
templateUrl: './quest-summary.component.html',
|
||||
styleUrls: ['./quest-summary.component.css']
|
||||
// #enddocregion urls
|
||||
})
|
||||
export class QuestSummaryComponent { }
|
||||
// #enddocregion
|
||||
|
||||
@@ -1,26 +1,18 @@
|
||||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
// #docregion import-services
|
||||
import { LoggerService } from './logger.service';
|
||||
import { UserContextService } from './user-context.service';
|
||||
import { UserService } from './user.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
})
|
||||
export class AppComponent {
|
||||
// #enddocregion import-services
|
||||
|
||||
private userId = 1;
|
||||
|
||||
// #docregion ctor
|
||||
constructor(logger: LoggerService, public userContext: UserContextService) {
|
||||
userContext.loadUser(this.userId);
|
||||
logger.logInfo('AppComponent initialized');
|
||||
}
|
||||
// #enddocregion ctor
|
||||
// #docregion import-services
|
||||
}
|
||||
// #enddocregion import-services
|
||||
|
||||
@@ -8,9 +8,7 @@ import { LoggerService } from './logger.service';
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
// #docregion date-logger-service-signature
|
||||
export class DateLoggerService extends LoggerService
|
||||
// #enddocregion date-logger-service-signature
|
||||
{
|
||||
logInfo(msg: any) { super.logInfo(stamp(msg)); }
|
||||
logDebug(msg: any) { super.logInfo(stamp(msg)); }
|
||||
|
||||
@@ -17,11 +17,9 @@ import { LoggerService } from './logger.service';
|
||||
})
|
||||
export class HeroBiosComponent {
|
||||
// #enddocregion simple
|
||||
// #docregion ctor
|
||||
constructor(logger: LoggerService) {
|
||||
logger.logInfo('Creating HeroBiosComponent');
|
||||
}
|
||||
// #enddocregion ctor
|
||||
// #docregion simple
|
||||
}
|
||||
// #enddocregion simple
|
||||
@@ -36,9 +34,7 @@ export class HeroBiosComponent {
|
||||
<app-hero-bio [heroId]="2"> <app-hero-contact></app-hero-contact> </app-hero-bio>
|
||||
<app-hero-bio [heroId]="3"> <app-hero-contact></app-hero-contact> </app-hero-bio>`,
|
||||
// #enddocregion template
|
||||
// #docregion class-provider
|
||||
providers: [HeroService]
|
||||
// #enddocregion class-provider
|
||||
})
|
||||
export class HeroBiosAndContactsComponent {
|
||||
constructor(logger: LoggerService) {
|
||||
|
||||
@@ -30,9 +30,7 @@ export class HeroContactComponent {
|
||||
this.hasLogger = true;
|
||||
loggerService.logInfo('HeroContactComponent can log!');
|
||||
}
|
||||
// #docregion ctor
|
||||
}
|
||||
// #enddocregion ctor
|
||||
|
||||
get phoneNumber() { return this.heroCache.hero.phone; }
|
||||
|
||||
|
||||
-2
@@ -48,13 +48,11 @@ const someHero = new Hero(42, 'Magma', 'Had a great month!', '555-555-5555');
|
||||
export class HeroOfTheMonthComponent {
|
||||
logs: string[] = [];
|
||||
|
||||
// #docregion ctor-signature
|
||||
constructor(
|
||||
logger: MinimalLogger,
|
||||
public heroOfTheMonth: Hero,
|
||||
@Inject(RUNNERS_UP) public runnersUp: string,
|
||||
@Inject(TITLE) public title: string)
|
||||
// #enddocregion ctor-signature
|
||||
{
|
||||
this.logs = logger.logs;
|
||||
logger.logInfo('starting up');
|
||||
|
||||
+2
-6
@@ -35,7 +35,6 @@ export function provideTheParent
|
||||
|
||||
|
||||
///////// C - Child //////////
|
||||
// #docregion carol
|
||||
const templateC = `
|
||||
<div class="c">
|
||||
<h3>{{name}}</h3>
|
||||
@@ -54,7 +53,6 @@ export class CarolComponent {
|
||||
// #enddocregion carol-ctor
|
||||
}
|
||||
// #enddocregion carol-class
|
||||
// #enddocregion carol
|
||||
|
||||
@Component({
|
||||
selector: 'chris',
|
||||
@@ -132,7 +130,7 @@ export class BethComponent implements Parent {
|
||||
|
||||
///////// A - Grandparent //////
|
||||
|
||||
// #docregion alex, alex-1
|
||||
// #docregion alex-1
|
||||
@Component({
|
||||
selector: 'alex',
|
||||
template: `
|
||||
@@ -157,11 +155,10 @@ export class AlexComponent extends Base
|
||||
{
|
||||
name = 'Alex';
|
||||
}
|
||||
// #enddocregion alex, alex-1
|
||||
// #enddocregion alex-1
|
||||
|
||||
/////
|
||||
|
||||
// #docregion alice
|
||||
@Component({
|
||||
selector: 'alice',
|
||||
template: `
|
||||
@@ -182,7 +179,6 @@ export class AliceComponent implements Parent
|
||||
{
|
||||
name = 'Alice';
|
||||
}
|
||||
// #enddocregion alice
|
||||
|
||||
////// Cathy ///////////
|
||||
/**
|
||||
|
||||
@@ -5,9 +5,7 @@ import { InjectionToken } from '@angular/core';
|
||||
import { Hero } from './hero';
|
||||
import { HeroService } from './hero.service';
|
||||
|
||||
// #docregion runners-up
|
||||
export const RUNNERS_UP = new InjectionToken<string>('RunnersUp');
|
||||
// #enddocregion runners-up
|
||||
|
||||
// #docregion factory-synopsis
|
||||
export function runnersUpFactory(take: number) {
|
||||
|
||||
+2
-4
@@ -6,7 +6,7 @@ import { Hero } from './hero';
|
||||
import { HeroService } from './hero.service';
|
||||
|
||||
/////// HeroesBaseComponent /////
|
||||
// #docregion heroes-base, injection
|
||||
// #docregion heroes-base
|
||||
@Component({
|
||||
selector: 'app-unsorted-heroes',
|
||||
template: `<div *ngFor="let hero of heroes">{{hero.name}}</div>`,
|
||||
@@ -14,7 +14,6 @@ import { HeroService } from './hero.service';
|
||||
})
|
||||
export class HeroesBaseComponent implements OnInit {
|
||||
constructor(private heroService: HeroService) { }
|
||||
// #enddocregion injection
|
||||
|
||||
heroes: Array<Hero>;
|
||||
|
||||
@@ -26,9 +25,8 @@ export class HeroesBaseComponent implements OnInit {
|
||||
// Post-process heroes in derived class override.
|
||||
protected afterGetHeroes() {}
|
||||
|
||||
// #docregion injection
|
||||
}
|
||||
// #enddocregion heroes-base,injection
|
||||
// #enddocregion heroes-base
|
||||
|
||||
/////// SortedHeroesComponent /////
|
||||
// #docregion sorted-heroes
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
// #docregion
|
||||
import { Inject, Injectable, InjectionToken } from '@angular/core';
|
||||
|
||||
// #docregion storage-token
|
||||
export const BROWSER_STORAGE = new InjectionToken<Storage>('Browser Storage', {
|
||||
providedIn: 'root',
|
||||
factory: () => localStorage
|
||||
});
|
||||
// #enddocregion storage-token
|
||||
|
||||
// #docregion inject-storage-token
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
@@ -31,4 +27,3 @@ export class BrowserStorageService {
|
||||
this.storage.clear();
|
||||
}
|
||||
}
|
||||
// #enddocregion inject-storage-token
|
||||
|
||||
@@ -1,27 +1,19 @@
|
||||
// #docplaster
|
||||
// #docregion
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { LoggerService } from './logger.service';
|
||||
import { UserService } from './user.service';
|
||||
|
||||
// #docregion injectables, injectable
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class UserContextService {
|
||||
// #enddocregion injectables, injectable
|
||||
name: string;
|
||||
role: string;
|
||||
loggedInSince: Date;
|
||||
|
||||
// #docregion ctor, injectables
|
||||
constructor(private userService: UserService, private loggerService: LoggerService) {
|
||||
// #enddocregion ctor, injectables
|
||||
this.loggedInSince = new Date();
|
||||
// #docregion ctor, injectables
|
||||
}
|
||||
// #enddocregion ctor, injectables
|
||||
|
||||
loadUser(userId: number) {
|
||||
const user = this.userService.getUserById(userId);
|
||||
@@ -30,6 +22,4 @@ export class UserContextService {
|
||||
|
||||
this.loggerService.logDebug('loaded User');
|
||||
}
|
||||
// #docregion injectables, injectable
|
||||
}
|
||||
// #enddocregion injectables, injectable
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
// #docregion
|
||||
// #docregion imports
|
||||
import { Component, Inject } from '@angular/core';
|
||||
|
||||
import { APP_CONFIG, AppConfig } from './app.config';
|
||||
// #enddocregion imports
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
@@ -22,5 +19,3 @@ export class AppComponent {
|
||||
}
|
||||
// #enddocregion ctor
|
||||
}
|
||||
// #enddocregion
|
||||
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
// #docplaster
|
||||
// #docregion
|
||||
// #docregion imports
|
||||
import { Component, Inject } from '@angular/core';
|
||||
|
||||
import { APP_CONFIG, AppConfig } from './app.config';
|
||||
import { UserService } from './user.service';
|
||||
// #enddocregion imports
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
@@ -28,13 +24,11 @@ import { UserService } from './user.service';
|
||||
export class AppComponent {
|
||||
title: string;
|
||||
|
||||
// #docregion ctor
|
||||
constructor(
|
||||
@Inject(APP_CONFIG) config: AppConfig,
|
||||
private userService: UserService) {
|
||||
this.title = config.title;
|
||||
}
|
||||
// #enddocregion ctor
|
||||
|
||||
get isAuthorized() { return this.user.isAuthorized; }
|
||||
nextUser() { this.userService.getNewUser(); }
|
||||
|
||||
@@ -15,7 +15,6 @@ import { UserService } from './user.service';
|
||||
|
||||
import { ProvidersModule } from './providers.module';
|
||||
|
||||
// #docregion ngmodule
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule,
|
||||
@@ -25,14 +24,12 @@ import { ProvidersModule } from './providers.module';
|
||||
AppComponent,
|
||||
CarComponent,
|
||||
HeroesComponent,
|
||||
// #enddocregion ngmodule
|
||||
HeroesTspComponent,
|
||||
HeroListComponent,
|
||||
InjectorComponent,
|
||||
TestComponent
|
||||
// #docregion ngmodule
|
||||
],
|
||||
// #docregion providers, providers-2
|
||||
// #docregion providers
|
||||
providers: [
|
||||
// #enddocregion providers
|
||||
Logger,
|
||||
@@ -40,7 +37,7 @@ import { ProvidersModule } from './providers.module';
|
||||
UserService,
|
||||
{ provide: APP_CONFIG, useValue: HERO_DI_CONFIG }
|
||||
],
|
||||
// #enddocregion providers, providers-2
|
||||
// #enddocregion providers
|
||||
exports: [ CarComponent, HeroesComponent ],
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
|
||||
@@ -1,47 +1,36 @@
|
||||
// Examples with car and engine variations
|
||||
|
||||
// #docplaster
|
||||
import { Car, Engine, Tires } from './car';
|
||||
|
||||
///////// example 1 ////////////
|
||||
export function simpleCar() {
|
||||
// #docregion car-ctor-instantiation
|
||||
// Simple car with 4 cylinders and Flintstone tires.
|
||||
const car = new Car(new Engine(), new Tires());
|
||||
// #enddocregion car-ctor-instantiation
|
||||
car.description = 'Simple';
|
||||
return car;
|
||||
}
|
||||
|
||||
|
||||
///////// example 2 ////////////
|
||||
// #docregion car-ctor-instantiation-with-param
|
||||
class Engine2 {
|
||||
constructor(public cylinders: number) { }
|
||||
}
|
||||
// #enddocregion car-ctor-instantiation-with-param
|
||||
|
||||
export function superCar() {
|
||||
// #docregion car-ctor-instantiation-with-param
|
||||
// Super car with 12 cylinders and Flintstone tires.
|
||||
const bigCylinders = 12;
|
||||
const car = new Car(new Engine2(bigCylinders), new Tires());
|
||||
// #enddocregion car-ctor-instantiation-with-param
|
||||
car.description = 'Super';
|
||||
return car;
|
||||
}
|
||||
|
||||
/////////// example 3 //////////
|
||||
// #docregion car-ctor-instantiation-with-mocks
|
||||
class MockEngine extends Engine { cylinders = 8; }
|
||||
class MockTires extends Tires { make = 'YokoGoodStone'; }
|
||||
|
||||
// #enddocregion car-ctor-instantiation-with-mocks
|
||||
export function testCar() {
|
||||
// #docregion car-ctor-instantiation-with-mocks
|
||||
// Test car with 8 cylinders and YokoGoodStone tires.
|
||||
const car = new Car(new MockEngine(), new MockTires());
|
||||
// #enddocregion car-ctor-instantiation-with-mocks
|
||||
car.description = 'Test';
|
||||
return car;
|
||||
}
|
||||
|
||||
@@ -3,21 +3,16 @@ import { Injector } from '@angular/core';
|
||||
import { Car, Engine, Tires } from './car';
|
||||
import { Logger } from '../logger.service';
|
||||
|
||||
// #docregion injector
|
||||
export function useInjector() {
|
||||
let injector: Injector;
|
||||
// #enddocregion injector
|
||||
/*
|
||||
// #docregion injector-no-new
|
||||
// Cannot instantiate an Injector like this!
|
||||
let injector = new Injector([
|
||||
{ provide: Car, deps: [Engine, Tires] },
|
||||
{ provide: Engine, deps: [] },
|
||||
{ provide: Tires, deps: [] }
|
||||
]);
|
||||
// #enddocregion injector-no-new
|
||||
*/
|
||||
// #docregion injector, injector-create-and-call
|
||||
injector = Injector.create({
|
||||
providers: [
|
||||
{ provide: Car, deps: [Engine, Tires] },
|
||||
@@ -25,9 +20,7 @@ export function useInjector() {
|
||||
{ provide: Tires, deps: [] }
|
||||
]
|
||||
});
|
||||
// #docregion injector-call
|
||||
const car = injector.get(Car);
|
||||
// #enddocregion injector-call, injector-create-and-call
|
||||
car.description = 'Injector';
|
||||
|
||||
injector = Injector.create({
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
// Car without DI
|
||||
import { Engine, Tires } from './car';
|
||||
|
||||
// #docregion car
|
||||
export class Car {
|
||||
|
||||
// #docregion car-ctor
|
||||
public engine: Engine;
|
||||
public tires: Tires;
|
||||
public description = 'No DI';
|
||||
@@ -13,7 +11,6 @@ export class Car {
|
||||
this.engine = new Engine();
|
||||
this.tires = new Tires();
|
||||
}
|
||||
// #enddocregion car-ctor
|
||||
|
||||
// Method using the engine and tires
|
||||
drive() {
|
||||
@@ -21,4 +18,3 @@ export class Car {
|
||||
`${this.engine.cylinders} cylinders and ${this.tires.make} tires.`;
|
||||
}
|
||||
}
|
||||
// #enddocregion car
|
||||
|
||||
@@ -11,11 +11,9 @@ export class Tires {
|
||||
|
||||
@Injectable()
|
||||
export class Car {
|
||||
// #docregion car-ctor
|
||||
public description = 'DI';
|
||||
|
||||
constructor(public engine: Engine, public tires: Tires) { }
|
||||
// #enddocregion car-ctor
|
||||
|
||||
// Method using the engine and tires
|
||||
drive() {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
import { HEROES } from './mock-heroes';
|
||||
|
||||
@@ -10,8 +9,6 @@ import { HEROES } from './mock-heroes';
|
||||
</div>
|
||||
`
|
||||
})
|
||||
// #docregion class
|
||||
export class HeroListComponent {
|
||||
heroes = HEROES;
|
||||
}
|
||||
// #enddocregion class
|
||||
|
||||
@@ -22,9 +22,7 @@ import { HeroService } from './hero.service';
|
||||
export class HeroListComponent {
|
||||
heroes: Hero[];
|
||||
|
||||
// #docregion ctor
|
||||
constructor(heroService: HeroService) {
|
||||
this.heroes = heroService.getHeroes();
|
||||
}
|
||||
// #enddocregion ctor
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// #docregion
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HEROES } from './mock-heroes';
|
||||
import { Logger } from '../logger.service';
|
||||
@@ -8,9 +7,7 @@ import { Logger } from '../logger.service';
|
||||
})
|
||||
export class HeroService {
|
||||
|
||||
// #docregion ctor
|
||||
constructor(private logger: Logger) { }
|
||||
// #enddocregion ctor
|
||||
|
||||
getHeroes() {
|
||||
this.logger.log('Getting heroes ...');
|
||||
|
||||
@@ -1,16 +1,10 @@
|
||||
// #docplaster
|
||||
// #docregion, v1
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
// #enddocregion v1
|
||||
import { HeroService } from './hero.service';
|
||||
|
||||
// #docregion v1
|
||||
@Component({
|
||||
selector: 'app-heroes',
|
||||
// #enddocregion v1
|
||||
providers: [ HeroService ],
|
||||
// #docregion v1
|
||||
template: `
|
||||
<h2>Heroes</h2>
|
||||
<app-hero-list></app-hero-list>
|
||||
|
||||
@@ -8,7 +8,6 @@ import { HeroService } from './heroes/hero.service';
|
||||
import { heroServiceProvider } from './heroes/hero.service.provider';
|
||||
import { Logger } from './logger.service';
|
||||
|
||||
// #docregion injector
|
||||
@Component({
|
||||
selector: 'app-injectors',
|
||||
template: `
|
||||
@@ -40,7 +39,6 @@ export class InjectorComponent implements OnInit {
|
||||
return this.injector.get(ROUS, rousDontExist);
|
||||
}
|
||||
}
|
||||
// #enddocregion injector
|
||||
|
||||
/**
|
||||
* R.O.U.S. - Rodents Of Unusual Size
|
||||
|
||||
@@ -19,9 +19,9 @@ const template = '{{log}}';
|
||||
@Component({
|
||||
selector: 'provider-1',
|
||||
template,
|
||||
// #docregion providers-1, providers-logger
|
||||
// #docregion providers-logger
|
||||
providers: [Logger]
|
||||
// #enddocregion providers-1, providers-logger
|
||||
// #enddocregion providers-logger
|
||||
})
|
||||
export class Provider1Component {
|
||||
log: string;
|
||||
@@ -114,11 +114,9 @@ export class OldLogger {
|
||||
selector: 'provider-6a',
|
||||
template,
|
||||
providers:
|
||||
// #docregion providers-6a
|
||||
[ NewLogger,
|
||||
// Not aliased! Creates two instances of `NewLogger`
|
||||
{ provide: OldLogger, useClass: NewLogger}]
|
||||
// #enddocregion providers-6a
|
||||
})
|
||||
export class Provider6aComponent {
|
||||
log: string;
|
||||
@@ -193,9 +191,7 @@ export class Provider8Component {
|
||||
// must be true else this component would have blown up at runtime
|
||||
log = 'Hero service injected successfully via heroServiceProvider';
|
||||
|
||||
// #docregion provider-8-ctor
|
||||
constructor(heroService: HeroService) { }
|
||||
// #enddocregion provider-8-ctor
|
||||
}
|
||||
|
||||
/////////////////
|
||||
@@ -221,9 +217,7 @@ export class Provider9Component implements OnInit {
|
||||
constructor(private config: AppConfig){ }
|
||||
// #enddocregion provider-9-ctor-interface
|
||||
*/
|
||||
// #docregion provider-9-ctor
|
||||
constructor(@Inject(APP_CONFIG) private config: AppConfig) { }
|
||||
// #enddocregion provider-9-ctor
|
||||
|
||||
ngOnInit() {
|
||||
this.log = 'APP_CONFIG Application title is ' + this.config.title;
|
||||
@@ -233,9 +227,7 @@ export class Provider9Component implements OnInit {
|
||||
//////////////////////////////////////////
|
||||
// Sample providers 1 to 7 illustrate a required logger dependency.
|
||||
// Optional logger, can be null
|
||||
// #docregion import-optional
|
||||
import { Optional } from '@angular/core';
|
||||
// #enddocregion import-optional
|
||||
|
||||
const someMessage = 'Hello from the injected logger';
|
||||
|
||||
@@ -246,13 +238,11 @@ const someMessage = 'Hello from the injected logger';
|
||||
})
|
||||
export class Provider10Component implements OnInit {
|
||||
log: string;
|
||||
// #docregion provider-10-ctor
|
||||
constructor(@Optional() private logger?: Logger) {
|
||||
if (this.logger) {
|
||||
this.logger.log(someMessage);
|
||||
}
|
||||
}
|
||||
// #enddocregion provider-10-ctor
|
||||
|
||||
ngOnInit() {
|
||||
this.log = this.logger ? this.logger.logs[0] : 'Optional logger was not available';
|
||||
|
||||
@@ -22,7 +22,6 @@ export class TestComponent {
|
||||
/////////////////////////////////////
|
||||
function runTests() {
|
||||
|
||||
// #docregion spec
|
||||
const expectedHeroes = [{name: 'A'}, {name: 'B'}]
|
||||
const mockService = <HeroService> {getHeroes: () => expectedHeroes }
|
||||
|
||||
@@ -31,7 +30,6 @@ function runTests() {
|
||||
const component = new HeroListComponent(mockService);
|
||||
expect(component.heroes.length).toEqual(expectedHeroes.length);
|
||||
});
|
||||
// #enddocregion spec
|
||||
|
||||
return testResults;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,4 @@ if (environment.production) {
|
||||
enableProdMode();
|
||||
}
|
||||
|
||||
// #docregion bootstrap
|
||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
||||
// #enddocregion bootstrap
|
||||
|
||||
@@ -7,7 +7,6 @@ import { Component } from '@angular/core';
|
||||
<h2>My favorite hero is: {{myHero}}</h2>
|
||||
`
|
||||
})
|
||||
// #docregion class
|
||||
export class AppComponent {
|
||||
title: string;
|
||||
myHero: string;
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
// #docregion template
|
||||
template: `
|
||||
<h1>{{title}}</h1>
|
||||
<h2>My favorite hero is: {{myHero}}</h2>
|
||||
`
|
||||
// #enddocregion template
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'Tour of Heroes';
|
||||
|
||||
@@ -1,24 +1,18 @@
|
||||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
// #docregion template
|
||||
template: `
|
||||
<h1>{{title}}</h1>
|
||||
<h2>My favorite hero is: {{myHero}}</h2>
|
||||
<p>Heroes:</p>
|
||||
<ul>
|
||||
// #docregion li
|
||||
<li *ngFor="let hero of heroes">
|
||||
{{ hero }}
|
||||
</li>
|
||||
// #enddocregion li
|
||||
</ul>
|
||||
`
|
||||
// #enddocregion template
|
||||
})
|
||||
// #docregion class
|
||||
export class AppComponent {
|
||||
title = 'Tour of Heroes';
|
||||
heroes = ['Windstorm', 'Bombasto', 'Magneta', 'Tornado'];
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
// #docregion import
|
||||
import { Hero } from './hero';
|
||||
// #enddocregion import
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
// #docregion template
|
||||
template: `
|
||||
<h1>{{title}}</h1>
|
||||
<h2>My favorite hero is: {{myHero.name}}</h2>
|
||||
@@ -18,12 +14,9 @@ import { Hero } from './hero';
|
||||
</li>
|
||||
</ul>
|
||||
`
|
||||
// #enddocregion template
|
||||
})
|
||||
// #docregion class
|
||||
export class AppComponent {
|
||||
title = 'Tour of Heroes';
|
||||
// #docregion heroes
|
||||
heroes = [
|
||||
new Hero(1, 'Windstorm'),
|
||||
new Hero(13, 'Bombasto'),
|
||||
@@ -31,5 +24,4 @@ export class AppComponent {
|
||||
new Hero(20, 'Tornado')
|
||||
];
|
||||
myHero = this.heroes[0];
|
||||
// #enddocregion heroes
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// #docplaster
|
||||
// #docregion final
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
import { Hero } from './hero';
|
||||
@@ -15,9 +13,7 @@ import { Hero } from './hero';
|
||||
{{ hero.name }}
|
||||
</li>
|
||||
</ul>
|
||||
// #docregion message
|
||||
<p *ngIf="heroes.length > 3">There are many heroes!</p>
|
||||
// #enddocregion message
|
||||
`
|
||||
})
|
||||
export class AppComponent {
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
// #docregion
|
||||
export class Hero {
|
||||
constructor(
|
||||
// #docregion id
|
||||
public id: number,
|
||||
// #enddocregion id
|
||||
public name: string) { }
|
||||
}
|
||||
// #enddocregion
|
||||
|
||||
@@ -7,10 +7,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
|
||||
<!-- #docregion body -->
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
</body>
|
||||
<!-- #enddocregion body -->
|
||||
|
||||
</html>
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
<!-- #docplaster -->
|
||||
<!-- #docregion -->
|
||||
<h1>{{title}}</h1>
|
||||
<h2>My Heroes</h2>
|
||||
<ul class="heroes">
|
||||
@@ -14,8 +12,6 @@
|
||||
<div><label>id: </label>{{selectedHero.id}}</div>
|
||||
<div>
|
||||
<label>name: </label>
|
||||
<!-- #docregion selected-hero -->
|
||||
<input [(ngModel)]="selectedHero.name" placeholder="name"/>
|
||||
<!-- #enddocregion selected-hero -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// #docregion
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { AppComponent } from './app.component';
|
||||
@@ -16,9 +15,7 @@ import { AdService } from './ad.service';
|
||||
HeroJobAdComponent,
|
||||
HeroProfileComponent,
|
||||
AdDirective ],
|
||||
// #docregion entry-components
|
||||
entryComponents: [ HeroJobAdComponent, HeroProfileComponent ],
|
||||
// #enddocregion entry-components
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
export class AppModule {
|
||||
|
||||
@@ -2,13 +2,9 @@
|
||||
|
||||
<div class="group">
|
||||
<h3>Target event</h3>
|
||||
<!-- #docregion event-binding-1 -->
|
||||
<button (click)="onSave($event)">Save</button>
|
||||
<!-- #enddocregion event-binding-1 -->
|
||||
|
||||
<!-- #docregion event-binding-2 -->
|
||||
<button on-click="onSave($event)">on-click Save</button>
|
||||
<!-- #enddocregion event-binding-2 -->
|
||||
|
||||
<!-- #docregion custom-directive -->
|
||||
<h4>myClick is an event on the custom ClickDirective:</h4>
|
||||
|
||||
-8
@@ -1,15 +1,10 @@
|
||||
// #docplaster
|
||||
// #docregion customer-dashboard
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
// #enddocregion customer-dashboard
|
||||
// #docregion customer-dashboard-component
|
||||
// import the new component
|
||||
import { CustomerDashboardComponent } from './customer-dashboard/customer-dashboard.component';
|
||||
// #enddocregion customer-dashboard-component
|
||||
|
||||
|
||||
// #docregion customer-dashboard-component
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule
|
||||
@@ -28,7 +23,4 @@ import { CustomerDashboardComponent } from './customer-dashboard/customer-dashbo
|
||||
|
||||
// #enddocregion customer-dashboard-component
|
||||
|
||||
// #docregion customer-dashboard
|
||||
export class CustomerDashboardModule { }
|
||||
|
||||
// #enddocregion customer-dashboard
|
||||
|
||||
-4
@@ -20,7 +20,6 @@ export class HeroFormReactiveComponent implements OnInit {
|
||||
heroForm: FormGroup;
|
||||
|
||||
ngOnInit(): void {
|
||||
// #docregion async-validation
|
||||
this.heroForm = new FormGroup({
|
||||
name: new FormControl(this.hero.name, [
|
||||
Validators.required,
|
||||
@@ -33,7 +32,6 @@ export class HeroFormReactiveComponent implements OnInit {
|
||||
}),
|
||||
power: new FormControl(this.hero.power, Validators.required)
|
||||
});
|
||||
// #enddocregion async-validation
|
||||
}
|
||||
|
||||
get name() { return this.heroForm.get('name'); }
|
||||
@@ -42,7 +40,5 @@ export class HeroFormReactiveComponent implements OnInit {
|
||||
|
||||
get alterEgo() { return this.heroForm.get('alterEgo'); }
|
||||
|
||||
// #docregion async-validation
|
||||
constructor(private alterEgoValidator: UniqueAlterEgoValidator) {}
|
||||
// #enddocregion async-validation
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
/* #docregion cross-validation-error-css */
|
||||
.cross-validation-error input {
|
||||
border-left: 5px solid red;
|
||||
}
|
||||
/* #enddocregion cross-validation-error-css */
|
||||
@@ -25,7 +25,6 @@ export class UniqueAlterEgoValidator implements AsyncValidator {
|
||||
}
|
||||
// #enddocregion async-validator
|
||||
|
||||
// #docregion async-validator-directive
|
||||
@Directive({
|
||||
selector: '[appUniqueAlterEgo]',
|
||||
providers: [
|
||||
@@ -43,4 +42,3 @@ export class UniqueAlterEgoValidatorDirective {
|
||||
this.validator.validate(control);
|
||||
}
|
||||
}
|
||||
// #enddocregion async-validator-directive
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// #docregion
|
||||
import { Directive, Input, OnChanges, SimpleChanges } from '@angular/core';
|
||||
import { AbstractControl, NG_VALIDATORS, Validator, ValidatorFn, Validators } from '@angular/forms';
|
||||
import { Directive, Input } from '@angular/core';
|
||||
import { AbstractControl, NG_VALIDATORS, ValidationErrors, Validator, ValidatorFn } from '@angular/forms';
|
||||
|
||||
// #docregion custom-validator
|
||||
/** A hero's name can't match the given regular expression */
|
||||
@@ -22,7 +22,7 @@ export function forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
|
||||
export class ForbiddenValidatorDirective implements Validator {
|
||||
@Input('appForbiddenName') forbiddenName: string;
|
||||
|
||||
validate(control: AbstractControl): {[key: string]: any} | null {
|
||||
validate(control: AbstractControl): ValidationErrors | null {
|
||||
return this.forbiddenName ? forbiddenNameValidator(new RegExp(this.forbiddenName, 'i'))(control)
|
||||
: null;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { AbstractControl, FormGroup, NG_VALIDATORS, ValidationErrors, Validator,
|
||||
|
||||
// #docregion cross-validation-validator
|
||||
/** A hero's name can't match the hero's alter ego */
|
||||
export const identityRevealedValidator: ValidatorFn = (control: FormGroup): ValidationErrors | null => {
|
||||
export const identityRevealedValidator: ValidatorFn = (control: AbstractControl): ValidationErrors | null => {
|
||||
const name = control.get('name');
|
||||
const alterEgo = control.get('alterEgo');
|
||||
|
||||
|
||||
-2
@@ -35,13 +35,11 @@
|
||||
|
||||
<div class="form-group">
|
||||
<label for="alterEgo">Alter Ego</label>
|
||||
<!-- #docregion async-validation -->
|
||||
<input id="alterEgo" class="form-control" name="alterEgo"
|
||||
#alterEgo="ngModel"
|
||||
[(ngModel)]="hero.alterEgo"
|
||||
[ngModelOptions]="{ updateOn: 'blur' }"
|
||||
appUniqueAlterEgo>
|
||||
<!-- #enddocregion async-validation -->
|
||||
|
||||
<div *ngIf="alterEgo.pending">Validating...</div>
|
||||
<div *ngIf="alterEgo.invalid" class="alert alert-danger alter-ego-errors">
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
/* tslint:disable: member-ordering */
|
||||
// #docplaster
|
||||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
// #docregion component
|
||||
@Component({
|
||||
selector: 'app-hero-form-template',
|
||||
templateUrl: './hero-form-template.component.html',
|
||||
@@ -16,4 +13,3 @@ export class HeroFormTemplateComponent {
|
||||
hero = {name: 'Dr.', alterEgo: 'Dr. What', power: this.powers[0]};
|
||||
|
||||
}
|
||||
// #enddocregion
|
||||
|
||||
@@ -102,7 +102,6 @@
|
||||
|
||||
<!-- ==================================================== -->
|
||||
<hr>
|
||||
<!-- #docregion phase1-->
|
||||
<style>
|
||||
.no-style .ng-valid {
|
||||
border-left: 1px solid #CCC
|
||||
@@ -113,7 +112,6 @@
|
||||
}
|
||||
</style>
|
||||
<div class="no-style" style="margin-left: 4px">
|
||||
<!-- #docregion start -->
|
||||
<div class="container">
|
||||
<h1>Hero Form</h1>
|
||||
<form>
|
||||
@@ -127,7 +125,6 @@
|
||||
<input type="text" class="form-control" id="alterEgo">
|
||||
</div>
|
||||
|
||||
<!-- #enddocregion start -->
|
||||
<!-- #docregion powers -->
|
||||
<div class="form-group">
|
||||
<label for="power">Hero Power</label>
|
||||
@@ -137,17 +134,13 @@
|
||||
</div>
|
||||
|
||||
<!-- #enddocregion powers -->
|
||||
<!-- #docregion start -->
|
||||
<button type="submit" class="btn btn-success">Submit</button>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
<!-- #enddocregion start -->
|
||||
<!-- #enddocregion phase1-->
|
||||
|
||||
<!-- ==================================================== -->
|
||||
<hr>
|
||||
<!-- #docregion phase2-->
|
||||
<div class="container">
|
||||
<h1>Hero Form</h1>
|
||||
<!-- #docregion template-variable-->
|
||||
@@ -182,7 +175,6 @@
|
||||
|
||||
</form>
|
||||
</div>
|
||||
<!-- #enddocregion phase2-->
|
||||
|
||||
<!-- EXTRA MATERIAL FOR DOCUMENTATION -->
|
||||
<hr>
|
||||
@@ -193,11 +185,9 @@
|
||||
TODO: remove this: {{model.name}}
|
||||
<!-- #enddocregion ngModelName-1 -->
|
||||
<hr>
|
||||
<!-- #docregion ngModel-3-->
|
||||
<input type="text" class="form-control" id="name"
|
||||
required
|
||||
[ngModel]="model.name" name="name"
|
||||
(ngModelChange)="model.name = $event">
|
||||
TODO: remove this: {{model.name}}
|
||||
<!-- #enddocregion ngModel-3-->
|
||||
</div>
|
||||
|
||||
@@ -49,9 +49,7 @@ export class HeroFormComponent {
|
||||
// Name via form.controls = {{showFormControls(heroForm)}}
|
||||
showFormControls(form: any) {
|
||||
return form && form.controls.name &&
|
||||
// #docregion form-controls
|
||||
form.controls.name.value; // Dr. IQ
|
||||
// #enddocregion form-controls
|
||||
}
|
||||
|
||||
/////////////////////////////
|
||||
|
||||
@@ -7,10 +7,8 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<!-- #docregion bootstrap -->
|
||||
<link rel="stylesheet"
|
||||
href="https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap.min.css">
|
||||
<!-- #enddocregion bootstrap -->
|
||||
<!-- #docregion styles -->
|
||||
<link rel="stylesheet" href="assets/forms.css">
|
||||
<!-- #enddocregion styles -->
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
// #docplaster
|
||||
// #docregion
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
// #docregion v1
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
|
||||
@@ -9,7 +9,7 @@ import { CartService } from '../cart.service';
|
||||
templateUrl: './cart.component.html',
|
||||
styleUrls: ['./cart.component.css']
|
||||
})
|
||||
// #docregion inject-cart, items, submit
|
||||
// #docregion inject-cart, items
|
||||
export class CartComponent {
|
||||
// #enddocregion inject-cart
|
||||
items = this.cartService.getItems();
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
// #docplaster
|
||||
// #docregion imports
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { CartService } from '../cart.service';
|
||||
// #enddocregion imports
|
||||
|
||||
@Component({
|
||||
selector: 'app-cart',
|
||||
templateUrl: './cart.component.html',
|
||||
styleUrls: ['./cart.component.css']
|
||||
})
|
||||
// #docregion props-services, submit
|
||||
export class CartComponent implements OnInit {
|
||||
items;
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import { CartService } from '../cart.service';
|
||||
templateUrl: './cart.component.html',
|
||||
styleUrls: ['./cart.component.css']
|
||||
})
|
||||
// #docregion props-services, submit, inject-form-builder, checkout-form, checkout-form-group
|
||||
// #docregion inject-form-builder, checkout-form-group
|
||||
export class CartComponent {
|
||||
// #enddocregion inject-form-builder
|
||||
items = this.cartService.getItems();
|
||||
@@ -19,7 +19,6 @@ export class CartComponent {
|
||||
name: '',
|
||||
address: ''
|
||||
});
|
||||
// #enddocregion checkout-form
|
||||
// #docregion inject-form-builder
|
||||
constructor(
|
||||
private cartService: CartService,
|
||||
@@ -27,12 +26,11 @@ export class CartComponent {
|
||||
) {}
|
||||
// #enddocregion inject-form-builder, checkout-form-group
|
||||
|
||||
// #enddocregion props-services
|
||||
onSubmit(): void {
|
||||
// Process checkout data here
|
||||
this.items = this.cartService.clearCart();
|
||||
console.warn('Your order has been submitted', this.checkoutForm.value);
|
||||
this.checkoutForm.reset();
|
||||
}
|
||||
// #docregion props-services, inject-form-builder, checkout-form, checkout-form-group
|
||||
// #docregion inject-form-builder, checkout-form-group
|
||||
}
|
||||
|
||||
+3
-9
@@ -1,10 +1,9 @@
|
||||
// #docplaster
|
||||
// #docregion imports, cart-service
|
||||
// #docregion cart-service
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
|
||||
import { products } from '../products';
|
||||
// #enddocregion imports
|
||||
import { CartService } from '../cart.service';
|
||||
// #enddocregion cart-service
|
||||
|
||||
@@ -13,7 +12,7 @@ import { CartService } from '../cart.service';
|
||||
templateUrl: './product-details.component.html',
|
||||
styleUrls: ['./product-details.component.css']
|
||||
})
|
||||
// #docregion props-methods, inject-cart-service, add-to-cart
|
||||
// #docregion inject-cart-service, add-to-cart
|
||||
export class ProductDetailsComponent implements OnInit {
|
||||
// #enddocregion add-to-cart, inject-cart-service
|
||||
product;
|
||||
@@ -21,28 +20,23 @@ export class ProductDetailsComponent implements OnInit {
|
||||
// #docregion inject-cart-service
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
// #enddocregion props-methods
|
||||
private cartService: CartService
|
||||
// #docregion props-methods
|
||||
) { }
|
||||
// #enddocregion inject-cart-service
|
||||
|
||||
ngOnInit() {
|
||||
// #enddocregion props-methods
|
||||
// First get the product id from the current route.
|
||||
const routeParams = this.route.snapshot.paramMap;
|
||||
const productIdFromRoute = Number(routeParams.get('productId'));
|
||||
|
||||
// Find the product that correspond with the id provided in route.
|
||||
this.product = products.find(product => product.id === productIdFromRoute);
|
||||
// #docregion props-methods
|
||||
}
|
||||
|
||||
// #enddocregion props-methods
|
||||
// #docregion add-to-cart
|
||||
addToCart(product) {
|
||||
this.cartService.addToCart(product);
|
||||
window.alert('Your product has been added to the cart!');
|
||||
}
|
||||
// #docregion props-methods, inject-cart-service
|
||||
// #docregion inject-cart-service
|
||||
}
|
||||
|
||||
-2
@@ -2,13 +2,11 @@
|
||||
|
||||
<div *ngFor="let product of products">
|
||||
|
||||
<!-- #docregion product-details -->
|
||||
<h3>
|
||||
<a [title]="product.name + ' details'">
|
||||
{{ product.name }}
|
||||
</a>
|
||||
</h3>
|
||||
<!-- #enddocregion product-details -->
|
||||
|
||||
<p *ngIf="product.description">
|
||||
Description: {{ product.description }}
|
||||
|
||||
@@ -10,7 +10,7 @@ import { CartService } from '../cart.service';
|
||||
templateUrl: './shipping.component.html',
|
||||
styleUrls: ['./shipping.component.css']
|
||||
})
|
||||
// #docregion props, ctor
|
||||
// #docregion props
|
||||
export class ShippingComponent {
|
||||
shippingCosts = this.cartService.getShippingPrices();
|
||||
// #enddocregion props
|
||||
|
||||
@@ -25,7 +25,7 @@ export class ConfigComponent {
|
||||
this.headers = undefined;
|
||||
}
|
||||
|
||||
// #docregion v1, v2, v3
|
||||
// #docregion v1, v2
|
||||
showConfig() {
|
||||
this.configService.getConfig()
|
||||
// #enddocregion v1, v2
|
||||
@@ -34,25 +34,22 @@ export class ConfigComponent {
|
||||
error => this.error = error // error path
|
||||
);
|
||||
}
|
||||
// #enddocregion v3
|
||||
|
||||
showConfig_v1() {
|
||||
this.configService.getConfig_1()
|
||||
// #docregion v1, v1_callback
|
||||
// #docregion v1
|
||||
.subscribe((data: Config) => this.config = {
|
||||
heroesUrl: data.heroesUrl,
|
||||
textfile: data.textfile
|
||||
});
|
||||
// #enddocregion v1_callback
|
||||
}
|
||||
// #enddocregion v1
|
||||
|
||||
showConfig_v2() {
|
||||
this.configService.getConfig()
|
||||
// #docregion v2, v2_callback
|
||||
// #docregion v2
|
||||
// clone the data object, using its known Config shape
|
||||
.subscribe((data: Config) => this.config = { ...data });
|
||||
// #enddocregion v2_callback
|
||||
}
|
||||
// #enddocregion v2
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<h3>Heroes</h3>
|
||||
<!-- #docregion add -->
|
||||
<div>
|
||||
<label>Hero name:
|
||||
<input #heroName />
|
||||
@@ -12,9 +11,7 @@
|
||||
search
|
||||
</button>
|
||||
</div>
|
||||
<!-- #enddocregion add -->
|
||||
|
||||
<!-- #docregion list -->
|
||||
<ul class="heroes">
|
||||
<li *ngFor="let hero of heroes">
|
||||
<a (click)="edit(hero)">
|
||||
@@ -23,10 +20,7 @@
|
||||
<input *ngIf="hero===editHero" [(ngModel)]="hero.name"
|
||||
(blur)="update()" (keyup.enter)="update()">
|
||||
</a>
|
||||
<!-- #docregion delete -->
|
||||
<button class="delete" title="delete hero"
|
||||
(click)="delete(hero)">x</button>
|
||||
<!-- #enddocregion delete -->
|
||||
</li>
|
||||
</ul>
|
||||
<!-- #enddocregion list -->
|
||||
|
||||
@@ -9,12 +9,10 @@ export interface RequestCacheEntry {
|
||||
lastRead: number;
|
||||
}
|
||||
|
||||
// #docregion request-cache
|
||||
export abstract class RequestCache {
|
||||
abstract get(req: HttpRequest<any>): HttpResponse<any> | undefined;
|
||||
abstract put(req: HttpRequest<any>, response: HttpResponse<any>): void;
|
||||
}
|
||||
// #enddocregion request-cache
|
||||
|
||||
const maxAge = 30000; // maximum cache age (ms)
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// #docregion import-locale
|
||||
import { registerLocaleData } from '@angular/common';
|
||||
import localeFr from '@angular/common/locales/fr';
|
||||
|
||||
// the second parameter 'fr-FR' is optional
|
||||
registerLocaleData(localeFr, 'fr-FR');
|
||||
// #enddocregion import-locale
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// #docregion import-locale-extra
|
||||
import { registerLocaleData } from '@angular/common';
|
||||
import localeFr from '@angular/common/locales/fr';
|
||||
import localeFrExtra from '@angular/common/locales/extra/fr';
|
||||
import localeFr from '@angular/common/locales/fr';
|
||||
|
||||
registerLocaleData(localeFr, 'fr-FR', localeFrExtra);
|
||||
// #enddocregion import-locale-extra
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
<!--#docregion-->
|
||||
<!--#docregion i18n-attribute-meaning-->
|
||||
<h1 i18n="User welcome|An introduction header for this sample@@introductionHeader">
|
||||
Hello i18n!
|
||||
</h1>
|
||||
<!--#enddocregion i18n-attribute-meaning-->
|
||||
|
||||
<!--#docregion i18n-ng-container-->
|
||||
<ng-container i18n>I don't output any element</ng-container>
|
||||
|
||||
@@ -5,12 +5,10 @@ import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
selector: 'app-aliasing',
|
||||
templateUrl: './aliasing.component.html',
|
||||
styleUrls: ['./aliasing.component.css'],
|
||||
// #docregion alias
|
||||
// tslint:disable: no-inputs-metadata-property no-outputs-metadata-property
|
||||
inputs: ['input1: saveForLaterItem'], // propertyName:alias
|
||||
outputs: ['outputEvent1: saveForLaterEvent']
|
||||
// tslint:disable: no-inputs-metadata-property no-outputs-metadata-property
|
||||
// #enddocregion alias
|
||||
|
||||
})
|
||||
export class AliasingComponent {
|
||||
@@ -18,10 +16,8 @@ export class AliasingComponent {
|
||||
input1: string;
|
||||
outputEvent1: EventEmitter<string> = new EventEmitter<string>();
|
||||
|
||||
// #docregion alias-input-output
|
||||
@Input('wishListItem') input2: string; // @Input(alias)
|
||||
@Output('wishEvent') outputEvent2 = new EventEmitter<string>(); // @Output(alias) propertyName = ...
|
||||
// #enddocregion alias-input-output
|
||||
|
||||
|
||||
saveIt() {
|
||||
|
||||
+1
-3
@@ -1,18 +1,16 @@
|
||||
/* tslint:disable:use-input-property-decorator */
|
||||
/* tslint:disable:use-output-property-decorator */
|
||||
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { Component, EventEmitter } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-in-the-metadata',
|
||||
templateUrl: './in-the-metadata.component.html',
|
||||
styleUrls: ['./in-the-metadata.component.css'],
|
||||
// #docregion metadata
|
||||
// tslint:disable: no-inputs-metadata-property no-outputs-metadata-property
|
||||
inputs: ['clearanceItem'],
|
||||
outputs: ['buyEvent']
|
||||
// tslint:enable: no-inputs-metadata-property no-outputs-metadata-property
|
||||
// #enddocregion metadata
|
||||
|
||||
})
|
||||
export class InTheMetadataComponent {
|
||||
|
||||
@@ -6,20 +6,14 @@ import { Component, Input, Output, EventEmitter } from '@angular/core';
|
||||
styleUrls: ['./input-output.component.css']
|
||||
})
|
||||
export class InputOutputComponent {
|
||||
// #docregion input-output
|
||||
@Input() item: string;
|
||||
// #docregion output
|
||||
@Output() deleteRequest = new EventEmitter<string>();
|
||||
// #enddocregion output
|
||||
// #enddocregion input-output
|
||||
|
||||
lineThrough = '';
|
||||
|
||||
// #docregion delete-method
|
||||
delete() {
|
||||
console.warn('Child says: emiting item deleteRequest with', this.item);
|
||||
this.deleteRequest.emit(this.item);
|
||||
this.lineThrough = this.lineThrough ? '' : 'line-through';
|
||||
}
|
||||
// #enddocregion delete-method
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
// #docregion imports
|
||||
import { Component, Output, EventEmitter } from '@angular/core';
|
||||
// #enddocregion imports
|
||||
|
||||
@Component({
|
||||
selector: 'app-item-output',
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
|
||||
// #docregion var-collision
|
||||
@Component({
|
||||
template: `
|
||||
<div>
|
||||
<!-- Hello, Padma -->
|
||||
<h1>Hello, {{customer}}</h1>
|
||||
<ul>
|
||||
<!-- Ebony and Chiho in a list-->
|
||||
<li *ngFor="let customer of customers">{{ customer.value }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
class AppComponent {
|
||||
customers = [{value: 'Ebony'}, {value: 'Chiho'}];
|
||||
customer = 'Padma';
|
||||
}
|
||||
// #enddocregion var-collision
|
||||
@@ -0,0 +1,8 @@
|
||||
div {
|
||||
max-width: 600px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// #docplaster
|
||||
// #docregion app-routing-module
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
|
||||
@@ -33,4 +32,3 @@ const routes: Routes = [
|
||||
providers: []
|
||||
})
|
||||
export class AppRoutingModule { }
|
||||
// #enddocregion app-routing-module
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user