Compare commits
169 Commits
Author | SHA1 | Date | |
---|---|---|---|
3e992e18eb | |||
d801941266 | |||
4dc066b979 | |||
71c1446def | |||
ca14509bfe | |||
19fe45dfdc | |||
42b7f8525b | |||
7f1c5f6248 | |||
7089c20ce5 | |||
b9609020f6 | |||
ea0f031995 | |||
2e1fc36c4e | |||
47c486860e | |||
77ee22eb6e | |||
8c0c689338 | |||
f971f83f06 | |||
895b0454f8 | |||
8febb5ac55 | |||
7d6d4c436c | |||
c15b223001 | |||
1423cc0ad2 | |||
e483078d6f | |||
29481a17b1 | |||
09b374c92c | |||
3f6b279033 | |||
b4c77d551b | |||
588a3ed79d | |||
9e33dc3e6a | |||
0930820748 | |||
96ff4971f2 | |||
c9b9be6c2e | |||
736afea5f1 | |||
a14dc2d7a4 | |||
a357daeaf7 | |||
ec4dced523 | |||
69786c2814 | |||
50bcaa6f5b | |||
6bf8e37827 | |||
91f2b1e4d7 | |||
c7075fe710 | |||
e2e0be4ac6 | |||
f6864cce91 | |||
ef038e8060 | |||
3580a6c986 | |||
67e9812c14 | |||
61b08629fd | |||
d727561c5e | |||
39ecc7b5b6 | |||
23f0a04387 | |||
e884c0cd7b | |||
ab72e06cde | |||
5218f5a401 | |||
e8b00ec404 | |||
94b0e8f288 | |||
157b948e6b | |||
7b9d62b2ed | |||
e4eed73591 | |||
a52123f538 | |||
15193fce98 | |||
572a5e4bd3 | |||
601fae944d | |||
d46f1f28e2 | |||
a2df6031ad | |||
542b7cd925 | |||
ce1b741255 | |||
4a1b4f17ae | |||
7ea8985500 | |||
eefae6d96d | |||
9f430f0ad9 | |||
60b5bf7b99 | |||
7671c73655 | |||
6d7a4ff45e | |||
cfa6ab1910 | |||
2f930a5d44 | |||
886df3e604 | |||
72900eccaf | |||
d9b1136ba4 | |||
97fc5f662e | |||
3ad67e5ef6 | |||
baec8abc75 | |||
1e3c015d89 | |||
9419165079 | |||
1f749fead5 | |||
3d60f6de5f | |||
8aefbfe7bc | |||
2d12af3589 | |||
57bef7306c | |||
c09a879b69 | |||
95d7144aba | |||
29d2986454 | |||
4a73dfc500 | |||
ac3e91bc2e | |||
516956905d | |||
81e8eeb0d8 | |||
cfae2c27cb | |||
f4be046d04 | |||
7081e39a78 | |||
5d5bb58e5a | |||
f65fa3aa1c | |||
dbbfab3ee8 | |||
b87ae8e5f9 | |||
8b1d28ff48 | |||
463e967abb | |||
71b8bbef95 | |||
a2cf677714 | |||
9e1ce318a8 | |||
a00c2a9210 | |||
a677d8b330 | |||
7fe89ba4ea | |||
a8af83bf36 | |||
c75e16aae8 | |||
1affcc63c0 | |||
34395aeea1 | |||
f64de2e9f3 | |||
86ad77c1b1 | |||
d5c815f1f2 | |||
32c6d5313a | |||
388c1a3638 | |||
334a3ba125 | |||
fd1d161844 | |||
280ea13342 | |||
3b1e539bab | |||
8e57965e3c | |||
761bb0aafd | |||
1b881b6ba2 | |||
f03d724fea | |||
cf8d934ba9 | |||
67f4852acb | |||
08f6a64893 | |||
ee49bbebc7 | |||
da78b02d71 | |||
d787925841 | |||
4e6efb361d | |||
aa371335dc | |||
090b6d92da | |||
a5cbfa2aab | |||
e8ed37a0e7 | |||
e5cbebef0d | |||
654ec1570a | |||
728d903a67 | |||
495f8e1bc6 | |||
d778a65447 | |||
e8dbba417d | |||
00c145f14c | |||
8c4c9858a2 | |||
caf3a53385 | |||
6ba1cd4365 | |||
bb18cba253 | |||
5abb9360d8 | |||
16c59aecf1 | |||
47d1216f6b | |||
5e614bfda8 | |||
efecf36eb5 | |||
b68d29791f | |||
136cd097c8 | |||
7be198a8e3 | |||
b4ee74667b | |||
67444e70ab | |||
09e55eabf3 | |||
1c838eb976 | |||
24ec9e57ad | |||
190330a612 | |||
9417086f6c | |||
535ff0564a | |||
e8c8ec7075 | |||
03d2813c20 | |||
fb5b2a89cd | |||
ea495d958f | |||
2edb87e7f8 |
17
.bazelrc
17
.bazelrc
@ -1,5 +1,3 @@
|
||||
# Load any settings specific to the current user
|
||||
try-import .bazelrc.user
|
||||
################################
|
||||
# Settings for Angular team members only
|
||||
################################
|
||||
@ -33,10 +31,11 @@ test:debug --test_arg=--node_options=--inspect-brk --test_output=streamed --test
|
||||
# eventually a surprising failure with auto-discovery of the C++ toolchain in
|
||||
# MacOS High Sierra.
|
||||
# See https://github.com/bazelbuild/bazel/issues/4603
|
||||
build --symlink_prefix=/
|
||||
build --symlink_prefix=dist/
|
||||
|
||||
# Performance: avoid stat'ing input files
|
||||
build --watchfs
|
||||
# Disable watchfs as it causes tests to be flaky on Windows
|
||||
# https://github.com/angular/angular/issues/29541
|
||||
build --nowatchfs
|
||||
|
||||
# Turn off legacy external runfiles
|
||||
run --nolegacy_external_runfiles
|
||||
@ -59,7 +58,9 @@ test --incompatible_strict_action_env
|
||||
###############################
|
||||
|
||||
# Releases should always be stamped with version control info
|
||||
build:release --workspace_status_command=./tools/bazel_stamp_vars.sh
|
||||
# This command assumes node on the path and is a workaround for
|
||||
# https://github.com/bazelbuild/bazel/issues/4802
|
||||
build:release --workspace_status_command="node ./tools/bazel_stamp_vars.js"
|
||||
|
||||
###############################
|
||||
# Output #
|
||||
@ -117,3 +118,7 @@ build:remote --remote_instance_name=projects/internal-200822/instances/default_i
|
||||
# Do not accept remote cache.
|
||||
# We need to understand the security risks of using prior build artifacts.
|
||||
build:remote --remote_accept_cached=false
|
||||
|
||||
# Load any settings specific to the current user. Needs to be last statement in this
|
||||
# config, as the user configuration should be able to overwrite flags from this file.
|
||||
try-import .bazelrc.user
|
||||
|
@ -63,26 +63,19 @@ var_6: &job_defaults
|
||||
docker:
|
||||
- image: *default_docker_image
|
||||
|
||||
# After checkout, rebase on top of master.
|
||||
# Similar to travis behavior, but not quite the same.
|
||||
# See https://discuss.circleci.com/t/1662
|
||||
# After checkout, rebase on top of target branch.
|
||||
var_7: &post_checkout
|
||||
run:
|
||||
name: Post checkout step
|
||||
name: Rebase PR on target branch
|
||||
command: >
|
||||
if [[ -n "${CIRCLE_PR_NUMBER}" ]]; then
|
||||
# Fetch the head and merge commits for this PR.
|
||||
git fetch origin +refs/pull/$CIRCLE_PR_NUMBER/head:pr/$CIRCLE_PR_NUMBER/head
|
||||
git fetch origin +refs/pull/$CIRCLE_PR_NUMBER/merge:pr/$CIRCLE_PR_NUMBER/merge
|
||||
# Checkout the merged PR for testing as CircleCI will just use the PR head otherwise.
|
||||
git checkout -qf pr/$CIRCLE_PR_NUMBER/merge
|
||||
# Reset the merge commit into its PR head.
|
||||
git reset pr/$CIRCLE_PR_NUMBER/head
|
||||
# Commit the merge changes into the head of the PR.
|
||||
# This way we keep the last commit message.
|
||||
# User is required for rebase.
|
||||
git config user.name "angular-ci"
|
||||
git config user.email "angular-ci"
|
||||
git commit . --amend --no-edit
|
||||
# Rebase PR on top of target branch.
|
||||
node tools/rebase-pr.js angular/angular ${CIRCLE_PR_NUMBER}
|
||||
else
|
||||
echo "This build is not over a PR, nothing to do."
|
||||
fi
|
||||
|
||||
var_8: &yarn_install
|
||||
@ -177,10 +170,7 @@ jobs:
|
||||
|
||||
# Setup remote execution and run RBE-compatible tests.
|
||||
- *setup_bazel_remote_execution
|
||||
- run: yarn bazel test //... --build_tag_filters=-ivy-only --test_tag_filters=-ivy-only,-local
|
||||
# Now run RBE incompatible tests locally.
|
||||
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
|
||||
- run: yarn bazel test //... --build_tag_filters=-ivy-only,local --test_tag_filters=-ivy-only,local
|
||||
- run: yarn bazel test //... --build_tag_filters=-ivy-only --test_tag_filters=-ivy-only
|
||||
|
||||
# Temporary job to test what will happen when we flip the Ivy flag to true
|
||||
test_ivy_aot:
|
||||
@ -302,10 +292,8 @@ jobs:
|
||||
docker:
|
||||
# Needed because the example e2e tests depend on Chrome.
|
||||
- image: *browsers_docker_image
|
||||
# We increase the parallelism here to five while the "test_docs_examples" job runs with
|
||||
# a parallelism of four. This is necessary because this job also need to run NGCC which
|
||||
# takes up more time and we don't want these jobs to impact the overall CI turnaround.
|
||||
parallelism: 5
|
||||
parallelism: 4
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- *attach_workspace
|
||||
- *init_environment
|
||||
@ -314,14 +302,18 @@ jobs:
|
||||
# Run examples tests. The "CIRCLE_NODE_INDEX" will be set if "parallelism" is enabled.
|
||||
# Since the parallelism is set to "3", there will be three parallel CircleCI containers
|
||||
# with either "0", "1" or "2" as node index. This can be passed to the "--shard" argument.
|
||||
- run: yarn --cwd aio example-e2e --setup --local --shard=${CIRCLE_NODE_INDEX}/${CIRCLE_NODE_TOTAL}
|
||||
- run: yarn --cwd aio example-e2e --setup --local --cliSpecsConcurrency=5 --shard=${CIRCLE_NODE_INDEX}/${CIRCLE_NODE_TOTAL}
|
||||
|
||||
test_docs_examples_ivy:
|
||||
<<: *job_defaults
|
||||
docker:
|
||||
# Needed because the example e2e tests depend on Chrome.
|
||||
- image: *browsers_docker_image
|
||||
parallelism: 4
|
||||
resource_class: xlarge
|
||||
# We increase the parallelism here to five while the "test_docs_examples" job runs with
|
||||
# a parallelism of four. This is necessary because this job also need to run NGCC which
|
||||
# takes up more time and we don't want these jobs to impact the overall CI turnaround.
|
||||
parallelism: 5
|
||||
steps:
|
||||
- *attach_workspace
|
||||
- *init_environment
|
||||
@ -336,7 +328,7 @@ jobs:
|
||||
# Run examples tests with ivy. The "CIRCLE_NODE_INDEX" will be set if "parallelism" is enabled.
|
||||
# Since the parallelism is set to "3", there will be three parallel CircleCI containers
|
||||
# with either "0", "1" or "2" as node index. This can be passed to the "--shard" argument.
|
||||
- run: yarn --cwd aio example-e2e --setup --local --ivy --shard=${CIRCLE_NODE_INDEX}/${CIRCLE_NODE_TOTAL}
|
||||
- run: yarn --cwd aio example-e2e --setup --local --ivy --cliSpecsConcurrency=5 --shard=${CIRCLE_NODE_INDEX}/${CIRCLE_NODE_TOTAL}
|
||||
|
||||
# This job should only be run on PR builds, where `CI_PULL_REQUEST` is not `false`.
|
||||
aio_preview:
|
||||
@ -546,6 +538,9 @@ workflows:
|
||||
- test_aio:
|
||||
requires:
|
||||
- setup
|
||||
- legacy-unit-tests-saucelabs:
|
||||
requires:
|
||||
- setup
|
||||
- deploy_aio:
|
||||
requires:
|
||||
- test_aio
|
||||
@ -598,24 +593,9 @@ workflows:
|
||||
# Get the artifacts to publish from the build-packages-dist job
|
||||
# since the publishing script expects the legacy outputs layout.
|
||||
- build-npm-packages
|
||||
- legacy-unit-tests-saucelabs
|
||||
- legacy-misc-tests
|
||||
|
||||
saucelabs_tests:
|
||||
jobs:
|
||||
- setup
|
||||
- legacy-unit-tests-saucelabs:
|
||||
requires:
|
||||
- setup
|
||||
triggers:
|
||||
- schedule:
|
||||
# Runs the Saucelabs legacy tests every hour. We still want to run Saucelabs
|
||||
# frequently as the caretaker needs up-to-date results when merging PRs or creating
|
||||
# a new release. Also we primarily moved the Saucelabs job into a cronjob that doesn't
|
||||
# run for PRs, in order to ensure that PRs are not affected by Saucelabs flakiness or
|
||||
# incidents. This is still guaranteed (even if we run the job every hour).
|
||||
cron: "0 * * * *"
|
||||
filters: *publish_branches_filter
|
||||
|
||||
aio_monitoring:
|
||||
jobs:
|
||||
- aio_monitoring
|
||||
|
@ -141,7 +141,7 @@ function getJson(url) {
|
||||
const opts = {headers: {Accept: 'application/json'}};
|
||||
const onResponse = res => {
|
||||
const statusCode = res.statusCode || -1;
|
||||
const isSuccess = (200 <= statusCode) && (statusCode <= 400);
|
||||
const isSuccess = (200 <= statusCode) && (statusCode < 400);
|
||||
let responseText = '';
|
||||
|
||||
res.
|
||||
|
108
.github/CODEOWNERS
vendored
108
.github/CODEOWNERS
vendored
@ -39,12 +39,14 @@
|
||||
# (just to make this file easier to understand)
|
||||
# ================================================
|
||||
|
||||
# alan-agius4 - Alan Agius
|
||||
# alexeagle - Alex Eagle
|
||||
# alxhub - Alex Rickabaugh
|
||||
# AndrewKushnir - Andrew Kushnir
|
||||
# andrewseguin - Andrew Seguin
|
||||
# benlesh - Ben Lesh
|
||||
# brandonroberts - Brandon Roberts
|
||||
# devversion - Paul Gschwendtner
|
||||
# filipesilva - Filipe Silva
|
||||
# gkalpak - George Kalpakas
|
||||
# hansl - Hans Larsen
|
||||
@ -86,6 +88,7 @@
|
||||
# - IgorMinar
|
||||
# - kara
|
||||
# - mhevery
|
||||
# - alexeagle
|
||||
|
||||
|
||||
# ===========================================================
|
||||
@ -293,6 +296,17 @@
|
||||
# - IgorMinar
|
||||
|
||||
|
||||
# ===========================================================
|
||||
# @angular/tools-docs-libraries
|
||||
# ===========================================================
|
||||
#
|
||||
# - alan-agius4
|
||||
# - alexeagle
|
||||
# - hansl
|
||||
# - IgorMinar
|
||||
# - mgechev
|
||||
|
||||
|
||||
# ===========================================================
|
||||
# @angular/fw-docs-marketing
|
||||
# ===========================================================
|
||||
@ -313,6 +327,7 @@
|
||||
# ===========================================================
|
||||
#
|
||||
# - alexeagle
|
||||
# - devversion
|
||||
# - filipesilva
|
||||
# - gkalpak
|
||||
# - IgorMinar
|
||||
@ -349,10 +364,19 @@
|
||||
|
||||
/packages/animations/** @angular/fw-animations @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/packages/platform-browser/animations/** @angular/fw-animations @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
|
||||
/aio/content/guide/animations.md @angular/fw-animations @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/animations/** @angular/fw-animations @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/images/guide/animations/** @angular/fw-animations @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
|
||||
/aio/content/guide/complex-animation-sequences.md @angular/fw-animations @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
|
||||
/aio/content/guide/reusable-animations.md @angular/fw-animations @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
|
||||
/aio/content/guide/route-animations.md @angular/fw-animations @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
|
||||
/aio/content/guide/transition-and-triggers.md @angular/fw-animations @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
|
||||
|
||||
|
||||
# ================================================
|
||||
@ -383,12 +407,13 @@
|
||||
|
||||
|
||||
# ================================================
|
||||
# @angular/compiler-cli/ngtools
|
||||
# Framework/cli integration
|
||||
#
|
||||
# a rule to control API changes between @angular/compiler-cli and @angular/cli
|
||||
# ================================================
|
||||
|
||||
/packages/compiler-cli/src/ngtools/** @angular/tools-cli @angular/framework-global-approvers
|
||||
/aio/content/guide/ivy.md @angular/tools-cli @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
|
||||
|
||||
|
||||
@ -407,6 +432,15 @@
|
||||
/packages/platform-browser-dynamic/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/packages/platform-webworker/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/packages/platform-webworker-dynamic/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/packages/examples/common/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
|
||||
/aio/content/guide/architecture-components.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/guide/architecture-modules.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/guide/architecture-next-steps.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/guide/architecture-services.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/guide/architecture.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/architecture/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/images/guide/architecture/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
|
||||
/aio/content/guide/attribute-directives.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/attribute-directives/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
@ -415,6 +449,8 @@
|
||||
/aio/content/guide/bootstrapping.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/bootstrapping/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
|
||||
/aio/content/guide/cheatsheet.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
|
||||
/aio/content/guide/component-interaction.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/component-interaction/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/images/guide/component-interaction/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
@ -430,7 +466,13 @@
|
||||
/aio/content/examples/dependency-injection-in-action/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/images/guide/dependency-injection-in-action/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
|
||||
/aio/content/guide/dependency-injection-pattern.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/guide/dependency-injection-navtree.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
|
||||
/aio/content/guide/dependency-injection-providers.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
|
||||
/aio/content/guide/displaying-data.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/displaying-data/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/images/guide/displaying-data/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
|
||||
/aio/content/guide/dynamic-component-loader.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/dynamic-component-loader/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
@ -457,12 +499,9 @@
|
||||
/aio/content/images/guide/lifecycle-hooks/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
|
||||
/aio/content/examples/ngcontainer/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/images/guide/ngcontainer/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
|
||||
/aio/content/guide/ngmodules.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/ngmodules/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/ngmodule/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/images/guide/ngmodule/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
|
||||
/aio/content/guide/ngmodule-api.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
|
||||
@ -474,6 +513,9 @@
|
||||
/aio/content/guide/module-types.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
|
||||
/aio/content/guide/template-syntax.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/built-in-template-functions/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/event-binding/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/interpolation/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/template-syntax/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/images/guide/template-syntax/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
|
||||
@ -496,6 +538,10 @@
|
||||
/aio/content/examples/structural-directives/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/images/guide/structural-directives/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
|
||||
/aio/content/guide/user-input.md @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/user-input/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/images/guide/user-input/** @angular/fw-core @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
|
||||
|
||||
|
||||
# ================================================
|
||||
@ -521,6 +567,7 @@
|
||||
/aio/content/guide/elements.md @angular/fw-elements @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
|
||||
|
||||
|
||||
# ================================================
|
||||
# @angular/forms
|
||||
# ================================================
|
||||
@ -582,6 +629,7 @@
|
||||
/packages/service-worker/** @angular/fw-service-worker @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/guide/service-worker-getting-started.md @angular/fw-service-worker @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/service-worker-getting-started/** @angular/fw-service-worker @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/guide/app-shell.md @angular/fw-service-worker @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/guide/service-worker-communications.md @angular/fw-service-worker @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/guide/service-worker-config.md @angular/fw-service-worker @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/guide/service-worker-devops.md @angular/fw-service-worker @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
@ -651,6 +699,7 @@ testing/** @angular/fw-test
|
||||
/packages/platform-browser/src/security/** @angular/fw-security
|
||||
/aio/content/guide/security.md @angular/fw-security @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/security/** @angular/fw-security @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/images/guide/security/** @angular/fw-security @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
|
||||
|
||||
|
||||
@ -681,6 +730,14 @@ testing/** @angular/fw-test
|
||||
/aio/tests/** @angular/docs-infra @angular/framework-global-approvers
|
||||
/aio/tools/** @angular/docs-infra @angular/framework-global-approvers
|
||||
|
||||
# Hidden docs
|
||||
/aio/content/guide/change-log.md @angular/docs-infra @angular/framework-global-approvers
|
||||
/aio/content/guide/docs-style-guide.md @angular/docs-infra @angular/framework-global-approvers
|
||||
/aio/content/examples/docs-style-guide/** @angular/docs-infra @angular/framework-global-approvers
|
||||
/aio/content/images/guide/docs-style-guide/** @angular/docs-infra @angular/framework-global-approvers
|
||||
/aio/content/guide/visual-studio-2015.md @angular/docs-infra @angular/framework-global-approvers
|
||||
/aio/content/examples/visual-studio-2015/** @angular/docs-infra @angular/framework-global-approvers
|
||||
|
||||
|
||||
|
||||
# ================================================
|
||||
@ -688,7 +745,17 @@ testing/** @angular/fw-test
|
||||
# ================================================
|
||||
|
||||
/aio/content/guide/quickstart.md @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/cli-quickstart/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/images/guide/cli-quickstart/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/tutorial/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/images/guide/toh/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/toh-pt0/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/toh-pt1/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/toh-pt2/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/toh-pt3/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/toh-pt4/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/toh-pt5/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/toh-pt6/** @angular/fw-docs-intro @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
|
||||
|
||||
|
||||
@ -696,17 +763,15 @@ testing/** @angular/fw-test
|
||||
# Docs: observables
|
||||
# ================================================
|
||||
|
||||
/aio/content/examples/observables/** @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/images/guide/observables/** @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/guide/observables.md @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/observables/** @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/guide/comparing-observables.md @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/observables-in-angular/** @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/images/guide/observables-in-angular/** @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/guide/observables-in-angular.md @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/practical-observable-usage/** @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/observables-in-angular/** @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/guide/practical-observable-usage.md @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/rx-library/** @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/practical-observable-usage/** @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/guide/rx-library.md @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/rx-library/** @angular/fw-docs-observables @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
|
||||
|
||||
|
||||
@ -717,12 +782,25 @@ testing/** @angular/fw-test
|
||||
/aio/content/guide/npm-packages.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/guide/browser-support.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/guide/typescript-configuration.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/guide/setup-systemjs-anatomy.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/guide/setup.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/examples/setup/** @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/guide/build.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/images/guide/build/** @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/guide/deployment.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/guide/file-structure.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/guide/releases.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/guide/updating.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/guide/workspace-config.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
|
||||
|
||||
|
||||
# ================================================
|
||||
# Docs: libraries
|
||||
# ================================================
|
||||
|
||||
/aio/content/guide/creating-libraries.md @angular/tools-docs-libraries @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/guide/libraries.md @angular/tools-docs-libraries @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
/aio/content/guide/using-libraries.md @angular/tools-docs-libraries @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
|
||||
|
||||
|
||||
|
||||
@ -745,7 +823,9 @@ testing/** @angular/fw-test
|
||||
/* @angular/fw-dev-infra
|
||||
/.buildkite/** @angular/fw-dev-infra
|
||||
/.circleci/** @angular/fw-dev-infra
|
||||
/.codefresh/** @angular/fw-dev-infra
|
||||
/.github/** @angular/fw-dev-infra
|
||||
/.vscode/** @angular/fw-dev-infra
|
||||
/docs/BAZEL.md @angular/fw-dev-infra
|
||||
/packages/* @angular/fw-dev-infra
|
||||
/scripts/** @angular/fw-dev-infra
|
||||
@ -760,6 +840,10 @@ testing/** @angular/fw-test
|
||||
# ================================================
|
||||
|
||||
/tools/public_api_guard/** @angular/fw-public-api
|
||||
/aio/content/guide/glossary.md @angular/fw-public-api
|
||||
/aio/content/guide/styleguide.md @angular/fw-public-api
|
||||
/aio/content/examples/styleguide/** @angular/fw-public-api
|
||||
/aio/content/images/guide/styleguide/** @angular/fw-public-api
|
||||
|
||||
|
||||
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -14,6 +14,7 @@ pubspec.lock
|
||||
.idea/
|
||||
.settings/
|
||||
.vscode/launch.json
|
||||
.vscode/settings.json
|
||||
*.swo
|
||||
modules/.settings
|
||||
modules/.vscode
|
||||
|
23
.vscode/README.md
vendored
Normal file
23
.vscode/README.md
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
# VSCode Configuration
|
||||
|
||||
This folder contains opt-in [Workspace Settings](https://code.visualstudio.com/docs/getstarted/settings) and [Extension Recommendations](https://code.visualstudio.com/docs/editor/extension-gallery#_workspace-recommended-extensions) that the Angular team recommends using when working on this repository.
|
||||
|
||||
## Usage
|
||||
|
||||
To use the recommended settings follow the steps below:
|
||||
|
||||
- install <https://marketplace.visualstudio.com/items?itemName=xaver.clang-format>
|
||||
- copy `.vscode/recommended-settings.json` to `.vscode/settings.json`
|
||||
- restart the editor
|
||||
|
||||
If you already have your custom workspace settings you should instead manually merge the file content.
|
||||
|
||||
This isn't an automatic process so you will need to repeat it when settings are updated.
|
||||
|
||||
To see the recommended extensions select "Extensions: Show Recommended Extensions" in the [Command Palette](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette).
|
||||
|
||||
## Editing `.vscode/recommended-settings.json`
|
||||
|
||||
If you wish to add extra configuration items please keep in mind any settings you add here will be used by many users.
|
||||
|
||||
Try to keep these settings to things that help facilitate the development process and avoid altering the user workflow whenever possible.
|
1
.vscode/extensions.json
vendored
1
.vscode/extensions.json
vendored
@ -4,6 +4,7 @@
|
||||
|
||||
// List of extensions which should be recommended for users of this workspace.
|
||||
"recommendations": [
|
||||
"devondcarew.bazel-code",
|
||||
"gkalpak.aio-docs-utils",
|
||||
"ms-vscode.vscode-typescript-tslint-plugin",
|
||||
"xaver.clang-format",
|
||||
|
@ -1,4 +1,7 @@
|
||||
{
|
||||
// Format js and ts files on save with `clang-format.executable`
|
||||
// If `clang-format.executable` is not being used, these two settings should be removed otherwise it will break existing formatting.
|
||||
// You can instead run `yarn gulp format` to manually format your code.
|
||||
"[javascript]": {
|
||||
"editor.formatOnSave": true,
|
||||
},
|
||||
@ -8,18 +11,21 @@
|
||||
// Please install https://marketplace.visualstudio.com/items?itemName=xaver.clang-format to take advantage of `clang-format` in VSCode.
|
||||
// (See https://clang.llvm.org/docs/ClangFormat.html for more info `clang-format`.)
|
||||
"clang-format.executable": "${workspaceRoot}/node_modules/.bin/clang-format",
|
||||
// Exclude third party modules and build artifacts from the editor watchers/searches.
|
||||
"files.watcherExclude": {
|
||||
"**/.git/objects/**": true,
|
||||
"**/.git/subtree-cache/**": true,
|
||||
"**/node_modules/**": true,
|
||||
"**/bazel-out/**": true,
|
||||
"**/dist/**": true,
|
||||
"**/aio/src/generated/**": true,
|
||||
},
|
||||
"search.exclude": {
|
||||
"**/node_modules": true,
|
||||
"**/bower_components": true,
|
||||
"**/bazel-out": true,
|
||||
"**/dist": true,
|
||||
"**/aio/src/generated": true,
|
||||
},
|
||||
"git.ignoreLimitWarning": true,
|
||||
}
|
50
BUILD.bazel
50
BUILD.bazel
@ -1,19 +1,23 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
exports_files([
|
||||
"tsconfig.json",
|
||||
"LICENSE",
|
||||
"protractor-perf.conf.js",
|
||||
])
|
||||
|
||||
alias(
|
||||
name = "tsconfig.json",
|
||||
actual = "//packages:tsconfig-build.json",
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "web_test_bootstrap_scripts",
|
||||
# do not sort
|
||||
srcs = [
|
||||
"@ngdeps//node_modules/reflect-metadata:Reflect.js",
|
||||
"@ngdeps//node_modules/zone.js:dist/zone.js",
|
||||
"@ngdeps//node_modules/zone.js:dist/zone-testing.js",
|
||||
"@ngdeps//node_modules/zone.js:dist/task-tracking.js",
|
||||
"@npm//node_modules/reflect-metadata:Reflect.js",
|
||||
"@npm//node_modules/zone.js:dist/zone.js",
|
||||
"@npm//node_modules/zone.js:dist/zone-testing.js",
|
||||
"@npm//node_modules/zone.js:dist/task-tracking.js",
|
||||
"//:test-events.js",
|
||||
],
|
||||
)
|
||||
@ -23,32 +27,14 @@ filegroup(
|
||||
srcs = [
|
||||
# We also declare the unminfied AngularJS files since these can be used for
|
||||
# local debugging (e.g. see: packages/upgrade/test/common/test_helpers.ts)
|
||||
"@ngdeps//node_modules/angular:angular.js",
|
||||
"@ngdeps//node_modules/angular:angular.min.js",
|
||||
"@ngdeps//node_modules/angular-1.5:angular.js",
|
||||
"@ngdeps//node_modules/angular-1.5:angular.min.js",
|
||||
"@ngdeps//node_modules/angular-1.6:angular.js",
|
||||
"@ngdeps//node_modules/angular-1.6:angular.min.js",
|
||||
"@ngdeps//node_modules/angular-mocks:angular-mocks.js",
|
||||
"@ngdeps//node_modules/angular-mocks-1.5:angular-mocks.js",
|
||||
"@ngdeps//node_modules/angular-mocks-1.6:angular-mocks.js",
|
||||
"@npm//node_modules/angular:angular.js",
|
||||
"@npm//node_modules/angular:angular.min.js",
|
||||
"@npm//node_modules/angular-1.5:angular.js",
|
||||
"@npm//node_modules/angular-1.5:angular.min.js",
|
||||
"@npm//node_modules/angular-1.6:angular.js",
|
||||
"@npm//node_modules/angular-1.6:angular.min.js",
|
||||
"@npm//node_modules/angular-mocks:angular-mocks.js",
|
||||
"@npm//node_modules/angular-mocks-1.5:angular-mocks.js",
|
||||
"@npm//node_modules/angular-mocks-1.6:angular-mocks.js",
|
||||
],
|
||||
)
|
||||
|
||||
load("@build_bazel_rules_nodejs//:defs.bzl", "nodejs_binary")
|
||||
|
||||
# A nodejs_binary for @angular/bazel/ngc-wrapped to use by default in
|
||||
# ng_module that depends on @npm//@angular/bazel instead of the
|
||||
# output of the //packages/bazel/src/ngc-wrapped ts_library rule. This
|
||||
# default is for downstream users that depend on the @angular/bazel npm
|
||||
# package. The generated @npm//@angular/bazel/ngc-wrapped target
|
||||
# does not work because it does not have the node `--expose-gc` flag
|
||||
# set which is required to support the call to `global.gc()`.
|
||||
nodejs_binary(
|
||||
name = "@angular/bazel/ngc-wrapped",
|
||||
configuration_env_vars = ["compile"],
|
||||
data = ["@npm//@angular/bazel"],
|
||||
entry_point = "@angular/bazel/src/ngc-wrapped/index.js",
|
||||
install_source_map_support = False,
|
||||
templated_args = ["--node_options=--expose-gc"],
|
||||
)
|
||||
|
45
CHANGELOG.md
45
CHANGELOG.md
@ -1,3 +1,48 @@
|
||||
<a name="7.2.13"></a>
|
||||
## [7.2.13](https://github.com/angular/angular/compare/7.2.12...7.2.13) (2019-04-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **bazel:** use //:tsconfig.json as the default for ng_module ([#29670](https://github.com/angular/angular/issues/29670)) ([#29711](https://github.com/angular/angular/issues/29711)) ([9e33dc3](https://github.com/angular/angular/commit/9e33dc3))
|
||||
* **platform-browser:** insert APP_ID in styles, contentAttr and hostAttr ([#17745](https://github.com/angular/angular/issues/17745)) ([ca14509](https://github.com/angular/angular/commit/ca14509))
|
||||
|
||||
|
||||
|
||||
<a name="7.2.12"></a>
|
||||
## [7.2.12](https://github.com/angular/angular/compare/7.2.11...7.2.12) (2019-04-03)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **common:** escape query selector used when anchor scrolling ([#29577](https://github.com/angular/angular/issues/29577)) ([7671c73](https://github.com/angular/angular/commit/7671c73)), closes [#28193](https://github.com/angular/angular/issues/28193)
|
||||
* **router:** adjust setting navigationTransition when a new navigation cancels an existing one ([#29636](https://github.com/angular/angular/issues/29636)) ([e884c0c](https://github.com/angular/angular/commit/e884c0c)), closes [#29389](https://github.com/angular/angular/issues/29389) [#29590](https://github.com/angular/angular/issues/29590)
|
||||
|
||||
|
||||
|
||||
<a name="7.2.11"></a>
|
||||
## [7.2.11](https://github.com/angular/angular/compare/7.2.10...7.2.11) (2019-03-26)
|
||||
|
||||
This release contains various API docs improvements.
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="7.2.10"></a>
|
||||
## [7.2.10](https://github.com/angular/angular/compare/7.2.9...7.2.10) (2019-03-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **compiler-cli:** incorrect metadata bundle for multiple unnamed re-exports ([#29360](https://github.com/angular/angular/issues/29360)) ([cf8d934](https://github.com/angular/angular/commit/cf8d934)), closes [/github.com/angular/material2/blob/master/tools/package-tools/build-release.ts#L78-L85](https://github.com//github.com/angular/material2/blob/master/tools/package-tools/build-release.ts/issues/L78-L85)
|
||||
|
||||
|
||||
|
||||
<a name="7.2.9"></a>
|
||||
## [7.2.9](https://github.com/angular/angular/compare/7.2.8...7.2.9) (2019-03-12)
|
||||
|
||||
This release contains various API docs improvements.
|
||||
|
||||
<a name="7.2.8"></a>
|
||||
## [7.2.8](https://github.com/angular/angular/compare/7.2.7...7.2.8) (2019-03-06)
|
||||
|
||||
|
51
WORKSPACE
51
WORKSPACE
@ -15,22 +15,13 @@ 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 = "1416d03823fed624b49a0abbd9979f7c63bbedfd37890ddecedd2fe25cccebc6",
|
||||
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/0.18.6/rules_nodejs-0.18.6.tar.gz"],
|
||||
)
|
||||
|
||||
# Use a mock @npm repository while we are building angular from source
|
||||
# downstream. Angular will get its npm dependencies with in @ngdeps which
|
||||
# is setup in ng_setup_workspace().
|
||||
# TODO(gregmagolan): remove @ngdeps once angular is no longer build from source
|
||||
# downstream and have build use @npm for npm dependencies
|
||||
local_repository(
|
||||
name = "npm",
|
||||
path = "tools/npm_workspace",
|
||||
sha256 = "5c86b055c57e15bf32d9009a15bcd6d8e190c41b1ff2fb18037b75e0012e4e7c",
|
||||
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/0.26.0/rules_nodejs-0.26.0.tar.gz"],
|
||||
)
|
||||
|
||||
# Check the bazel version and download npm dependencies
|
||||
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories")
|
||||
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories", "yarn_install")
|
||||
load("@build_bazel_rules_nodejs//:package.bzl", "check_rules_nodejs_version")
|
||||
|
||||
# Bazel version must be at least v0.21.0 because:
|
||||
# - 0.21.0 Using --incompatible_strict_action_env flag fixes cache when running `yarn bazel`
|
||||
@ -46,6 +37,13 @@ Try running `yarn bazel` instead.
|
||||
minimum_bazel_version = "0.21.0",
|
||||
)
|
||||
|
||||
# The NodeJS rules version must be at least v0.15.3 because:
|
||||
# - 0.15.2 Re-introduced the prod_only attribute on yarn_install
|
||||
# - 0.15.3 Includes a fix for the `jasmine_node_test` rule ignoring target tags
|
||||
# - 0.16.8 Supports npm installed bazel workspaces
|
||||
# - 0.26.0 Fix for data files in yarn_install and npm_install
|
||||
check_rules_nodejs_version("0.26.0")
|
||||
|
||||
# Setup the Node.js toolchain
|
||||
node_repositories(
|
||||
node_version = "10.9.0",
|
||||
@ -54,13 +52,28 @@ node_repositories(
|
||||
yarn_version = "1.12.1",
|
||||
)
|
||||
|
||||
# Setup the angular toolchain which installs npm dependencies into @ngdeps
|
||||
load("//tools:ng_setup_workspace.bzl", "ng_setup_workspace")
|
||||
yarn_install(
|
||||
name = "npm",
|
||||
data = [
|
||||
"//:tools/npm/@angular_bazel/index.js",
|
||||
"//:tools/npm/@angular_bazel/package.json",
|
||||
"//:tools/postinstall-patches.js",
|
||||
"//:tools/yarn/check-yarn.js",
|
||||
],
|
||||
package_json = "//:package.json",
|
||||
# Don't install devDependencies, they are large and not used under Bazel
|
||||
prod_only = True,
|
||||
yarn_lock = "//:yarn.lock",
|
||||
)
|
||||
|
||||
ng_setup_workspace()
|
||||
yarn_install(
|
||||
name = "ts-api-guardian_deps",
|
||||
package_json = "@angular//tools/ts-api-guardian:package.json",
|
||||
yarn_lock = "@angular//tools/ts-api-guardian:yarn.lock",
|
||||
)
|
||||
|
||||
# Install all bazel dependencies of the @ngdeps npm packages
|
||||
load("@ngdeps//:install_bazel_dependencies.bzl", "install_bazel_dependencies")
|
||||
# Install all bazel dependencies of the @npm npm packages
|
||||
load("@npm//:install_bazel_dependencies.bzl", "install_bazel_dependencies")
|
||||
|
||||
install_bazel_dependencies()
|
||||
|
||||
@ -86,7 +99,7 @@ load("@npm_bazel_karma//:browser_repositories.bzl", "browser_repositories")
|
||||
browser_repositories()
|
||||
|
||||
# Setup the rules_typescript tooolchain
|
||||
load("@npm_bazel_typescript//:defs.bzl", "ts_setup_workspace")
|
||||
load("@npm_bazel_typescript//:index.bzl", "ts_setup_workspace")
|
||||
|
||||
ts_setup_workspace()
|
||||
|
||||
|
@ -41,16 +41,6 @@ Here are the most important tasks you might need to use:
|
||||
- `yarn example-e2e --filter=foo` - limit e2e tests to those containing the word "foo"
|
||||
- `yarn example-e2e --setup --local` - run e2e tests with the local version of Angular contained in the "dist" folder
|
||||
|
||||
## Developing on Windows
|
||||
The `packages/` directory may contain Linux-specific symlinks, which are not recognized by Windows.
|
||||
These unresolved links cause the docs generation process to fail because it cannot locate certain files.
|
||||
|
||||
> Hint: The following steps require administration rights or [Windows Developer Mode](https://docs.microsoft.com/en-us/windows/uwp/get-started/enable-your-device-for-development) enabled!
|
||||
|
||||
To fix this problem, run `scripts/windows/create-symlinks.sh`. This command creates temporary files where the symlinks used to be. Make sure not to commit those files with your documentation changes.
|
||||
When you are done making and testing your documentation changes, you can restore the original symlinks and delete the temporary files by running `scripts/windows/remove-symlinks.sh`.
|
||||
|
||||
It's necessary to remove the temporary files, because otherwise they're displayed as local changes in your git working copy and certain operations are blocked.
|
||||
|
||||
## Using ServiceWorker locally
|
||||
|
||||
|
@ -26,8 +26,8 @@ ARG AIO_GITHUB_ORGANIZATION=angular
|
||||
ARG TEST_AIO_GITHUB_ORGANIZATION=test-org
|
||||
ARG AIO_GITHUB_REPO=angular
|
||||
ARG TEST_AIO_GITHUB_REPO=test-repo
|
||||
ARG AIO_GITHUB_TEAM_SLUGS=aio-contributors
|
||||
ARG TEST_AIO_GITHUB_TEAM_SLUGS=aio-contributors
|
||||
ARG AIO_GITHUB_TEAM_SLUGS=aio-auto-previews,aio-contributors
|
||||
ARG TEST_AIO_GITHUB_TEAM_SLUGS=test-team-1,test-team-2
|
||||
ARG AIO_NGINX_HOSTNAME=$AIO_DOMAIN_NAME
|
||||
ARG TEST_AIO_NGINX_HOSTNAME=$TEST_AIO_DOMAIN_NAME
|
||||
ARG AIO_NGINX_PORT_HTTP=80
|
||||
|
3
aio/content/examples/.gitignore
vendored
3
aio/content/examples/.gitignore
vendored
@ -92,3 +92,6 @@ upgrade-phonecat-3-final/tsconfig-aot.json
|
||||
upgrade-phonecat-3-final/rollup-config.js
|
||||
!upgrade-phonecat-*/**/karma.conf.js
|
||||
!upgrade-phonecat-*/**/karma-test-shim.js
|
||||
|
||||
# schematics
|
||||
!schematics-for-libraries/projects/my-lib/package.json
|
@ -0,0 +1,20 @@
|
||||
'use strict'; // necessary for es6 output in node
|
||||
|
||||
import { browser, element, by } from 'protractor';
|
||||
|
||||
describe('Built Template Functions Example', function () {
|
||||
beforeAll(function () {
|
||||
browser.get('');
|
||||
});
|
||||
|
||||
it('should have title Built-in Template Functions', function () {
|
||||
let title = element.all(by.css('h1')).get(0);
|
||||
expect(title.getText()).toEqual('Built-in Template Functions');
|
||||
});
|
||||
|
||||
it('should display $any( ) in h2', function () {
|
||||
let header = element(by.css('h2'));
|
||||
expect(header.getText()).toContain('$any( )');
|
||||
});
|
||||
|
||||
});
|
@ -0,0 +1,15 @@
|
||||
<h1>{{title}}</h1>
|
||||
|
||||
<h2><code>$any( )</code> type cast function and an undeclared member</h2>
|
||||
|
||||
<p>There is no such member as <code>bestByDate</code> in the following two examples, so nothing renders:</p>
|
||||
<!-- #docregion any-type-cast-function-1 -->
|
||||
<p>The item's undeclared best by date is: {{$any(item).bestByDate}}</p>
|
||||
<!-- #enddocregion any-type-cast-function-1 -->
|
||||
|
||||
<h2>using <code>this</code></h2>
|
||||
<!-- #docregion any-type-cast-function-2 -->
|
||||
<p>The item's undeclared best by date is: {{$any(this).bestByDate}}</p>
|
||||
<!-- #enddocregion any-type-cast-function-2 -->
|
||||
|
||||
|
@ -0,0 +1,16 @@
|
||||
import { TestBed, async } from '@angular/core/testing';
|
||||
import { AppComponent } from './app.component';
|
||||
describe('AppComponent', () => {
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
}).compileComponents();
|
||||
}));
|
||||
it('should create the app', async(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.debugElement.componentInstance;
|
||||
expect(app).toBeTruthy();
|
||||
}));
|
||||
});
|
@ -0,0 +1,16 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.css']
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'Built-in Template Functions';
|
||||
|
||||
item = {
|
||||
name : 'Telephone',
|
||||
origin : 'Sweden',
|
||||
price: 98
|
||||
};
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule
|
||||
],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Built-in Template Functions Example</title>
|
||||
<base href="/">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
</head>
|
||||
<body>
|
||||
<app-root>Loading...</app-root>
|
||||
</body>
|
||||
</html>
|
@ -1,4 +1,3 @@
|
||||
// #docregion
|
||||
import { enableProdMode } from '@angular/core';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
|
@ -0,0 +1,10 @@
|
||||
{
|
||||
"description": "Built-in Template Functions",
|
||||
"files": [
|
||||
"!**/*.d.ts",
|
||||
"!**/*.js",
|
||||
"!**/*.[1,2].*"
|
||||
],
|
||||
"file": "src/app/app.component.ts",
|
||||
"tags": ["Built-in Template Functions"]
|
||||
}
|
@ -4,7 +4,8 @@
|
||||
"cmd": "yarn",
|
||||
"args": [
|
||||
"e2e",
|
||||
"--no-webdriver-update"
|
||||
"--no-webdriver-update",
|
||||
"--port={PORT}"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
@ -4,7 +4,8 @@
|
||||
"cmd": "yarn",
|
||||
"args": [
|
||||
"e2e",
|
||||
"--no-webdriver-update"
|
||||
"--no-webdriver-update",
|
||||
"--port={PORT}"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
71
aio/content/examples/event-binding/e2e/src/app.e2e-spec.ts
Normal file
71
aio/content/examples/event-binding/e2e/src/app.e2e-spec.ts
Normal file
@ -0,0 +1,71 @@
|
||||
'use strict'; // necessary for es6 output in node
|
||||
|
||||
import { browser, element, by, protractor } from 'protractor';
|
||||
|
||||
describe('Event binding example', function () {
|
||||
|
||||
beforeEach(function () {
|
||||
browser.get('');
|
||||
});
|
||||
|
||||
let saveButton = element.all(by.css('button')).get(0);
|
||||
let onSaveButton = element.all(by.css('button')).get(1);
|
||||
let myClick = element.all(by.css('button')).get(2);
|
||||
let deleteButton = element.all(by.css('button')).get(3);
|
||||
let saveNoProp = element.all(by.css('button')).get(4);
|
||||
let saveProp = element.all(by.css('button')).get(5);
|
||||
|
||||
|
||||
it('should display Event Binding with Angular', function () {
|
||||
expect(element(by.css('h1')).getText()).toEqual('Event Binding');
|
||||
});
|
||||
|
||||
it('should display 6 buttons', function() {
|
||||
expect(saveButton.getText()).toBe('Save');
|
||||
expect(onSaveButton.getText()).toBe('on-click Save');
|
||||
expect(myClick.getText()).toBe('click with myClick');
|
||||
expect(deleteButton.getText()).toBe('Delete');
|
||||
expect(saveNoProp.getText()).toBe('Save, no propagation');
|
||||
expect(saveProp.getText()).toBe('Save with propagation');
|
||||
});
|
||||
|
||||
it('should support user input', function () {
|
||||
let input = element(by.css('input'));
|
||||
let bindingResult = element.all(by.css('h4')).get(1);
|
||||
expect(bindingResult.getText()).toEqual('Result: teapot');
|
||||
input.sendKeys('abc');
|
||||
expect(bindingResult.getText()).toEqual('Result: teapotabc');
|
||||
});
|
||||
|
||||
it('should hide the item img', async () => {
|
||||
let deleteButton = element.all(by.css('button')).get(3);
|
||||
await deleteButton.click();
|
||||
browser.switchTo().alert().accept();
|
||||
expect(element.all(by.css('img')).get(0).getCssValue('display')).toEqual('none');
|
||||
});
|
||||
|
||||
it('should show two alerts', async () => {
|
||||
let parentDiv = element.all(by.css('.parent-div'));
|
||||
let childDiv = element.all(by.css('div > div')).get(1);
|
||||
await parentDiv.click();
|
||||
browser.switchTo().alert().accept();
|
||||
expect(childDiv.getText()).toEqual('Click me too! (child)');
|
||||
await childDiv.click();
|
||||
expect(browser.switchTo().alert().getText()).toEqual('Click me. Event target class is child-div');
|
||||
browser.switchTo().alert().accept();
|
||||
});
|
||||
|
||||
it('should show 1 alert from Save, no prop, button', async () => {
|
||||
await saveNoProp.click();
|
||||
expect(browser.switchTo().alert().getText()).toEqual('Saved. Event target is Save, no propagation');
|
||||
browser.switchTo().alert().accept();
|
||||
});
|
||||
|
||||
it('should show 2 alerts from Save w/prop button', async () => {
|
||||
await saveProp.click();
|
||||
expect(browser.switchTo().alert().getText()).toEqual('Saved.');
|
||||
browser.switchTo().alert().accept();
|
||||
expect(browser.switchTo().alert().getText()).toEqual('Saved.');
|
||||
browser.switchTo().alert().accept();
|
||||
});
|
||||
});
|
25
aio/content/examples/event-binding/src/app/app.component.css
Normal file
25
aio/content/examples/event-binding/src/app/app.component.css
Normal file
@ -0,0 +1,25 @@
|
||||
.group {
|
||||
background-color: #dae8f9;
|
||||
padding: 1rem;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
.parent-div {
|
||||
background-color: #bdd1f7;
|
||||
border: solid 1px rgb(25, 118, 210);
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.parent-div:hover {
|
||||
background-color: #8fb4f9;
|
||||
}
|
||||
|
||||
.child-div {
|
||||
margin-top: 1rem;
|
||||
background-color: #fff;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.child-div:hover {
|
||||
background-color: #eee;
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
<h1 id="event-binding">Event Binding</h1>
|
||||
|
||||
<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>
|
||||
<button (myClick)="clickMessage=$event" clickable>click with myClick</button>
|
||||
{{clickMessage}}
|
||||
<!-- #enddocregion custom-directive -->
|
||||
|
||||
</div>
|
||||
|
||||
<div class="group">
|
||||
<h3>$event and event handling statements</h3>
|
||||
<h4>Result: {{currentItem.name}}</h4>
|
||||
|
||||
<!-- #docregion event-binding-3-->
|
||||
<input [value]="currentItem.name"
|
||||
(input)="currentItem.name=$event.target.value" >
|
||||
without NgModel
|
||||
<!-- #enddocregion event-binding-3-->
|
||||
</div>
|
||||
|
||||
<div class="group">
|
||||
<h3>Binding to a nested component</h3>
|
||||
<h4>Custom events with EventEmitter</h4>
|
||||
<!-- #docregion event-binding-to-component -->
|
||||
<app-item-detail (deleteRequest)="deleteItem($event)" [item]="currentItem"></app-item-detail>
|
||||
<!-- #enddocregion event-binding-to-component -->
|
||||
|
||||
|
||||
<h4>Click to see event target class:</h4>
|
||||
<div class="parent-div" (click)="onClickMe($event)" clickable>Click me (parent)
|
||||
<div class="child-div">Click me too! (child) </div>
|
||||
</div>
|
||||
|
||||
<h3>Saves only once:</h3>
|
||||
<div (click)="onSave()" clickable>
|
||||
<button (click)="onSave($event)">Save, no propagation</button>
|
||||
</div>
|
||||
|
||||
<h3>Saves twice:</h3>
|
||||
<div (click)="onSave()" clickable>
|
||||
<button (click)="onSave()">Save with propagation</button>
|
||||
</div>
|
@ -0,0 +1,27 @@
|
||||
import { TestBed, async } from '@angular/core/testing';
|
||||
import { AppComponent } from './app.component';
|
||||
describe('AppComponent', () => {
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
}).compileComponents();
|
||||
}));
|
||||
it('should create the app', async(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.debugElement.componentInstance;
|
||||
expect(app).toBeTruthy();
|
||||
}));
|
||||
it(`should have as title 'Featured product:'`, async(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.debugElement.componentInstance;
|
||||
expect(app.title).toEqual('Featured product:');
|
||||
}));
|
||||
it('should render title in a p tag', async(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
fixture.detectChanges();
|
||||
const compiled = fixture.debugElement.nativeElement;
|
||||
expect(compiled.querySelector('p').textContent).toContain('Featured product:');
|
||||
}));
|
||||
});
|
29
aio/content/examples/event-binding/src/app/app.component.ts
Normal file
29
aio/content/examples/event-binding/src/app/app.component.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Item } from './item';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.css']
|
||||
})
|
||||
export class AppComponent {
|
||||
|
||||
currentItem = { name: 'teapot'} ;
|
||||
clickMessage = '';
|
||||
|
||||
onSave(event?: KeyboardEvent) {
|
||||
const evtMsg = event ? ' Event target is ' + (<HTMLElement>event.target).textContent : '';
|
||||
alert('Saved.' + evtMsg);
|
||||
if (event) { event.stopPropagation(); }
|
||||
}
|
||||
|
||||
deleteItem(item?: Item) {
|
||||
alert(`Delete the ${item}.`);
|
||||
}
|
||||
|
||||
onClickMe(event?: KeyboardEvent) {
|
||||
const evtMsg = event ? ' Event target class is ' + (<HTMLElement>event.target).className : '';
|
||||
alert('Click me.' + evtMsg);
|
||||
}
|
||||
|
||||
}
|
22
aio/content/examples/event-binding/src/app/app.module.ts
Normal file
22
aio/content/examples/event-binding/src/app/app.module.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { ItemDetailComponent } from './item-detail/item-detail.component';
|
||||
import { ClickDirective } from './click.directive';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
ItemDetailComponent,
|
||||
ClickDirective
|
||||
],
|
||||
imports: [
|
||||
BrowserModule
|
||||
],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
@ -0,0 +1,18 @@
|
||||
/* tslint:disable use-output-property-decorator directive-class-suffix */
|
||||
import { Directive, ElementRef, EventEmitter, Output } from '@angular/core';
|
||||
|
||||
@Directive({selector: '[myClick]'})
|
||||
export class ClickDirective {
|
||||
@Output('myClick') clicks = new EventEmitter<string>(); // @Output(alias) propertyName = ...
|
||||
|
||||
toggle = false;
|
||||
|
||||
constructor(el: ElementRef) {
|
||||
el.nativeElement
|
||||
.addEventListener('click', (event: Event) => {
|
||||
this.toggle = !this.toggle;
|
||||
this.clicks.emit(this.toggle ? 'Click!' : '');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,11 @@
|
||||
.detail {
|
||||
border: 1px solid rgb(25, 118, 210);
|
||||
padding: 1rem;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100px;
|
||||
display: block;
|
||||
padding: 1rem 0;
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
<div class="detail">
|
||||
<p>This is the ItemDetailComponent</p>
|
||||
<!-- #docregion line-through -->
|
||||
<img src="{{itemImageUrl}}" [style.display]="displayNone">
|
||||
<span [style.text-decoration]="lineThrough">{{ item.name }}
|
||||
</span>
|
||||
<button (click)="delete()">Delete</button>
|
||||
<!-- #enddocregion line-through -->
|
||||
</div>
|
@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ItemDetailComponent } from './item-detail.component';
|
||||
|
||||
describe('ItemDetailComponent', () => {
|
||||
let component: ItemDetailComponent;
|
||||
let fixture: ComponentFixture<ItemDetailComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ItemDetailComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ItemDetailComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,30 @@
|
||||
/* tslint:disable use-input-property-decorator use-output-property-decorator */
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
|
||||
import { Item } from '../item';
|
||||
|
||||
@Component({
|
||||
selector: 'app-item-detail',
|
||||
styleUrls: ['./item-detail.component.css'],
|
||||
templateUrl: './item-detail.component.html'
|
||||
})
|
||||
export class ItemDetailComponent {
|
||||
|
||||
@Input() item;
|
||||
itemImageUrl = 'assets/teapot.svg';
|
||||
lineThrough = '';
|
||||
displayNone = '';
|
||||
@Input() prefix = '';
|
||||
|
||||
// #docregion deleteRequest
|
||||
// This component makes a request but it can't actually delete a hero.
|
||||
@Output() deleteRequest = new EventEmitter<Item>();
|
||||
|
||||
delete() {
|
||||
this.deleteRequest.emit(this.item.name);
|
||||
this.displayNone = this.displayNone ? '' : 'none';
|
||||
this.lineThrough = this.lineThrough ? '' : 'line-through';
|
||||
}
|
||||
// #enddocregion deleteRequest
|
||||
|
||||
}
|
4
aio/content/examples/event-binding/src/app/item.ts
Normal file
4
aio/content/examples/event-binding/src/app/item.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export class Item {
|
||||
name: '';
|
||||
}
|
||||
|
1
aio/content/examples/event-binding/src/assets/teapot.svg
Normal file
1
aio/content/examples/event-binding/src/assets/teapot.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 23 KiB |
@ -1,15 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>EventBinding</title>
|
||||
<base href="/">
|
||||
<title>NgModule Minimal</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
</head>
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,11 +1,12 @@
|
||||
import { enableProdMode } from '@angular/core';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
|
||||
import { AppModule } from './app/app.module.0';
|
||||
import { AppModule } from './app/app.module';
|
||||
import { environment } from './environments/environment';
|
||||
|
||||
if (environment.production) {
|
||||
enableProdMode();
|
||||
}
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
||||
platformBrowserDynamic().bootstrapModule(AppModule)
|
||||
.catch(err => console.log(err));
|
10
aio/content/examples/event-binding/stackblitz.json
Normal file
10
aio/content/examples/event-binding/stackblitz.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"description": "Event Binding",
|
||||
"files": [
|
||||
"!**/*.d.ts",
|
||||
"!**/*.js",
|
||||
"!**/*.[1,2].*"
|
||||
],
|
||||
"file": "src/app/app.component.ts",
|
||||
"tags": ["Event Binding"]
|
||||
}
|
@ -5,7 +5,8 @@
|
||||
"cmd": "yarn",
|
||||
"args": [
|
||||
"e2e",
|
||||
"--no-webdriver-update"
|
||||
"--no-webdriver-update",
|
||||
"--port={PORT}"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
@ -13,15 +13,4 @@ describe('AppComponent', () => {
|
||||
const app = fixture.debugElement.componentInstance;
|
||||
expect(app).toBeTruthy();
|
||||
}));
|
||||
it(`should have as title 'Featured product:'`, async(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.debugElement.componentInstance;
|
||||
expect(app.title).toEqual('Featured product:');
|
||||
}));
|
||||
it('should render title in a p tag', async(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
fixture.detectChanges();
|
||||
const compiled = fixture.debugElement.nativeElement;
|
||||
expect(compiled.querySelector('p').textContent).toContain('Featured product:');
|
||||
}));
|
||||
});
|
||||
|
@ -1,24 +0,0 @@
|
||||
{
|
||||
"description": "Contact NgModule v.1",
|
||||
"files": [
|
||||
"src/app/app.component.1b.ts",
|
||||
"src/app/app.module.1b.ts",
|
||||
"src/app/highlight.directive.ts",
|
||||
"src/app/title.component.html",
|
||||
"src/app/title.component.ts",
|
||||
"src/app/user.service.ts",
|
||||
|
||||
"src/app/contact/awesome.pipe.ts",
|
||||
"src/app/contact/contact.component.css",
|
||||
"src/app/contact/contact.component.html",
|
||||
"src/app/contact/contact.component.3.ts",
|
||||
"src/app/contact/contact.service.ts",
|
||||
"src/app/contact/contact-highlight.directive.ts",
|
||||
|
||||
"src/main.1b.ts",
|
||||
"src/styles.css",
|
||||
"src/index.1b.html"
|
||||
],
|
||||
"main": "src/index.1b.html",
|
||||
"tags": ["NgModule"]
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
{
|
||||
"description": "Contact NgModule v.2",
|
||||
"files": [
|
||||
"src/app/app.component.2.ts",
|
||||
"src/app/app.module.2.ts",
|
||||
"src/app/highlight.directive.ts",
|
||||
"src/app/title.component.html",
|
||||
"src/app/title.component.ts",
|
||||
"src/app/user.service.ts",
|
||||
|
||||
"src/app/contact/contact.component.css",
|
||||
"src/app/contact/contact.component.html",
|
||||
"src/app/contact/contact.service.ts",
|
||||
|
||||
"src/app/contact/awesome.pipe.ts",
|
||||
"src/app/contact/contact.component.3.ts",
|
||||
"src/app/contact/contact.module.2.ts",
|
||||
"src/app/contact/contact-highlight.directive.ts",
|
||||
|
||||
"src/main.2.ts",
|
||||
"src/styles.css",
|
||||
"src/index.2.html"
|
||||
],
|
||||
"main": "src/index.2.html",
|
||||
"tags": ["NgModule"]
|
||||
}
|
@ -1,223 +0,0 @@
|
||||
'use strict'; // necessary for es6 output in node
|
||||
|
||||
import { browser, element, by } from 'protractor';
|
||||
|
||||
describe('NgModule', function () {
|
||||
|
||||
// helpers
|
||||
const gold = 'rgba(255, 215, 0, 1)';
|
||||
const powderblue = 'rgba(176, 224, 230, 1)';
|
||||
const lightgray = 'rgba(211, 211, 211, 1)';
|
||||
const white = 'rgba(0, 0, 0, 0)';
|
||||
|
||||
function getCommonsSectionStruct() {
|
||||
const buttons = element.all(by.css('nav a'));
|
||||
|
||||
return {
|
||||
title: element.all(by.tagName('h1')).get(0),
|
||||
welcome: element.all(by.css('app-title p i')).get(0),
|
||||
contactButton: buttons.get(0),
|
||||
crisisButton: buttons.get(1),
|
||||
heroesButton: buttons.get(2)
|
||||
};
|
||||
}
|
||||
|
||||
function getContactSectionStruct() {
|
||||
const buttons = element.all(by.css('app-contact form button'));
|
||||
|
||||
return {
|
||||
header: element.all(by.css('app-contact h2')).get(0),
|
||||
popupMessage: element.all(by.css('app-contact div')).get(0),
|
||||
contactNameHeader: element.all(by.css('app-contact form h3')).get(0),
|
||||
input: element.all(by.css('app-contact form input')).get(0),
|
||||
validationError: element.all(by.css('app-contact form .alert')).get(0),
|
||||
saveButton: buttons.get(0), // can't be tested
|
||||
nextContactButton: buttons.get(1),
|
||||
newContactButton: buttons.get(2)
|
||||
};
|
||||
}
|
||||
|
||||
function getCrisisSectionStruct() {
|
||||
return {
|
||||
title: element.all(by.css('ng-component h3')).get(0),
|
||||
items: element.all(by.css('ng-component a')),
|
||||
itemId: element.all(by.css('ng-component div')).get(0),
|
||||
listLink: element.all(by.css('ng-component a')).get(0),
|
||||
};
|
||||
}
|
||||
|
||||
function getHeroesSectionStruct() {
|
||||
return {
|
||||
header: element.all(by.css('ng-component h2')).get(0),
|
||||
title: element.all(by.css('ng-component h3')).get(0),
|
||||
items: element.all(by.css('ng-component a')),
|
||||
itemId: element.all(by.css('ng-component ng-component div div')).get(0),
|
||||
itemInput: element.all(by.css('ng-component ng-component input')).get(0),
|
||||
listLink: element.all(by.css('ng-component ng-component a')).get(0),
|
||||
};
|
||||
}
|
||||
|
||||
// tests
|
||||
function appTitleTests(color: string, name?: string) {
|
||||
return function() {
|
||||
it('should have a gray header', function() {
|
||||
const commons = getCommonsSectionStruct();
|
||||
expect(commons.title.getCssValue('backgroundColor')).toBe(color);
|
||||
});
|
||||
|
||||
it('should welcome us', function () {
|
||||
const commons = getCommonsSectionStruct();
|
||||
expect(commons.welcome.getText()).toBe('Welcome, ' + (name || 'Sherlock Holmes'));
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function contactTests(color: string, name?: string) {
|
||||
return function() {
|
||||
it('shows the contact\'s owner', function() {
|
||||
const contacts = getContactSectionStruct();
|
||||
expect(contacts.header.getText()).toBe('Contact of ' + (name || 'Sherlock Holmes'));
|
||||
});
|
||||
|
||||
it('can cycle between contacts', function () {
|
||||
const contacts = getContactSectionStruct();
|
||||
const nextButton = contacts.nextContactButton;
|
||||
expect(contacts.contactNameHeader.getText()).toBe('Awesome Sam Spade');
|
||||
expect(contacts.contactNameHeader.getCssValue('backgroundColor')).toBe(color);
|
||||
nextButton.click().then(function () {
|
||||
expect(contacts.contactNameHeader.getText()).toBe('Awesome Nick Danger');
|
||||
return nextButton.click();
|
||||
}).then(function () {
|
||||
expect(contacts.contactNameHeader.getText()).toBe('Awesome Nancy Drew');
|
||||
});
|
||||
});
|
||||
|
||||
it('can change an existing contact', function () {
|
||||
const contacts = getContactSectionStruct();
|
||||
contacts.input.sendKeys('a');
|
||||
expect(contacts.input.getCssValue('backgroundColor')).toBe(color);
|
||||
expect(contacts.contactNameHeader.getText()).toBe('Awesome Sam Spadea');
|
||||
});
|
||||
|
||||
it('can create a new contact', function () {
|
||||
const contacts = getContactSectionStruct();
|
||||
const newContactButton = contacts.newContactButton;
|
||||
newContactButton.click().then(function () {
|
||||
expect(contacts.validationError.getText()).toBe('Name is required');
|
||||
contacts.input.sendKeys('John Doe');
|
||||
expect(contacts.contactNameHeader.getText()).toBe('Awesome John Doe');
|
||||
expect(contacts.validationError.getText()).toBe('');
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
describe('index.html', function () {
|
||||
beforeEach(function () {
|
||||
browser.get('');
|
||||
});
|
||||
|
||||
describe('app-title', appTitleTests(white, 'Miss Marple'));
|
||||
|
||||
describe('contact', contactTests(lightgray, 'Miss Marple'));
|
||||
|
||||
describe('crisis center', function () {
|
||||
beforeEach(function () {
|
||||
getCommonsSectionStruct().crisisButton.click();
|
||||
});
|
||||
|
||||
it('shows a list of crisis', function () {
|
||||
const crisis = getCrisisSectionStruct();
|
||||
expect(crisis.title.getText()).toBe('Crisis List');
|
||||
expect(crisis.items.count()).toBe(4);
|
||||
expect(crisis.items.get(0).getText()).toBe('1 - Dragon Burning Cities');
|
||||
});
|
||||
|
||||
it('can navigate to one crisis details', function () {
|
||||
const crisis = getCrisisSectionStruct();
|
||||
crisis.items.get(0).click().then(function() {
|
||||
expect(crisis.itemId.getText()).toBe('Crisis id: 1');
|
||||
return crisis.listLink.click();
|
||||
}).then(function () {
|
||||
// We are back to the list
|
||||
expect(crisis.items.count()).toBe(4);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('heroes', function () {
|
||||
beforeEach(function () {
|
||||
getCommonsSectionStruct().heroesButton.click();
|
||||
});
|
||||
|
||||
it('shows a list of heroes', function() {
|
||||
const heroes = getHeroesSectionStruct();
|
||||
expect(heroes.header.getText()).toBe('Heroes of Miss Marple');
|
||||
expect(heroes.title.getText()).toBe('Hero List');
|
||||
expect(heroes.items.count()).toBe(6);
|
||||
expect(heroes.items.get(0).getText()).toBe('11 - Mr. Nice');
|
||||
});
|
||||
|
||||
it('can navigate and edit one hero details', function () {
|
||||
const heroes = getHeroesSectionStruct();
|
||||
heroes.items.get(0).click().then(function () {
|
||||
expect(heroes.itemId.getText()).toBe('Id: 11');
|
||||
heroes.itemInput.sendKeys(' try');
|
||||
return heroes.listLink.click();
|
||||
}).then(function () {
|
||||
// We are back to the list
|
||||
expect(heroes.items.count()).toBe(6);
|
||||
expect(heroes.items.get(0).getText()).toBe('11 - Mr. Nice try');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// describe('index.0.html', function() {
|
||||
// beforeEach(function () {
|
||||
// browser.get('index.0.html');
|
||||
// });
|
||||
|
||||
// it('has a title', function () {
|
||||
// const title = element.all(by.tagName('h1')).get(0);
|
||||
// expect(title.getText()).toBe('Minimal NgModule');
|
||||
// });
|
||||
// });
|
||||
|
||||
// describe('index.1.html', function () {
|
||||
// beforeEach(function () {
|
||||
// browser.get('index.1.html');
|
||||
// });
|
||||
|
||||
// describe('app-title', appTitleTests(powderblue));
|
||||
// });
|
||||
|
||||
// describe('index.1b.html', function () {
|
||||
// beforeEach(function () {
|
||||
// browser.get('index.1b.html');
|
||||
// });
|
||||
|
||||
// describe('app-title', appTitleTests(powderblue));
|
||||
|
||||
// describe('contact', contactTests(powderblue));
|
||||
// });
|
||||
|
||||
// describe('index.2.html', function () {
|
||||
// beforeEach(function () {
|
||||
// browser.get('index.2.html');
|
||||
// });
|
||||
|
||||
// describe('app-title', appTitleTests(gold));
|
||||
|
||||
// describe('contact', contactTests(powderblue));
|
||||
// });
|
||||
|
||||
// describe('index.3.html', function () {
|
||||
// beforeEach(function () {
|
||||
// browser.get('index.3.html');
|
||||
// });
|
||||
|
||||
// describe('app-title', appTitleTests(gold));
|
||||
// });
|
||||
|
||||
});
|
@ -1,12 +0,0 @@
|
||||
{
|
||||
"description": "Minimal NgModule",
|
||||
"files": [
|
||||
"src/app/app.component.0.ts",
|
||||
"src/app/app.module.0.ts",
|
||||
"src/main.0.ts",
|
||||
"src/styles.css",
|
||||
"src/index.0.html"
|
||||
],
|
||||
"main": "src/index.0.html",
|
||||
"tags": ["NgModule"]
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
{
|
||||
"description": "NgModule v.3",
|
||||
"files": [
|
||||
"src/app/app.component.3.ts",
|
||||
"src/app/app.module.3.ts",
|
||||
"src/app/app-routing.module.3.ts",
|
||||
|
||||
"src/app/highlight.directive.ts",
|
||||
"src/app/title.component.html",
|
||||
"src/app/title.component.ts",
|
||||
"src/app/user.service.ts",
|
||||
|
||||
"src/app/contact/contact.component.css",
|
||||
"src/app/contact/contact.component.html",
|
||||
"src/app/contact/contact.service.ts",
|
||||
|
||||
"src/app/contact/awesome.pipe.ts",
|
||||
"src/app/contact/contact.component.3.ts",
|
||||
"src/app/contact/contact.module.3.ts",
|
||||
"src/app/contact/contact-routing.module.3.ts",
|
||||
"src/app/contact/contact-highlight.directive.ts",
|
||||
|
||||
"src/app/crisis/*.ts",
|
||||
|
||||
"src/app/hero/hero-detail.component.ts",
|
||||
"src/app/hero/hero-list.component.ts",
|
||||
"src/app/hero/hero.service.ts",
|
||||
|
||||
"src/app/hero/hero.component.3.ts",
|
||||
"src/app/hero/hero.module.3.ts",
|
||||
"src/app/hero/hero-routing.module.3.ts",
|
||||
"src/app/hero/highlight.directive.ts",
|
||||
|
||||
"src/main.3.ts",
|
||||
"src/styles.css",
|
||||
"src/index.3.html"
|
||||
],
|
||||
"main": "src/index.3.html",
|
||||
"tags": ["NgModule"]
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
|
||||
import { ContactModule } from './contact/contact.module.3';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '', redirectTo: 'contact', pathMatch: 'full'},
|
||||
{ path: 'crisis', loadChildren: './crisis/crisis.module#CrisisModule' },
|
||||
{ path: 'heroes', loadChildren: './hero/hero.module.3#HeroModule' }
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
ContactModule,
|
||||
RouterModule.forRoot(routes)
|
||||
],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class AppRoutingModule {}
|
@ -1,30 +0,0 @@
|
||||
// #docregion
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
|
||||
import { ContactModule } from './contact/contact.module';
|
||||
|
||||
// #docregion routes
|
||||
const routes: Routes = [
|
||||
{ path: '', redirectTo: 'contact', pathMatch: 'full'},
|
||||
// #docregion lazy-routes
|
||||
{ path: 'crisis', loadChildren: './crisis/crisis.module#CrisisModule' },
|
||||
{ path: 'heroes', loadChildren: './hero/hero.module#HeroModule' }
|
||||
// #enddocregion lazy-routes
|
||||
];
|
||||
// #enddocregion routes
|
||||
|
||||
@NgModule({
|
||||
// #docregion imports
|
||||
imports: [
|
||||
ContactModule,
|
||||
// #docregion forRoot
|
||||
RouterModule.forRoot(routes),
|
||||
// #enddocregion forRoot
|
||||
],
|
||||
// #enddocregion imports
|
||||
// #docregion exports
|
||||
exports: [RouterModule]
|
||||
// #enddocregion exports
|
||||
})
|
||||
export class AppRoutingModule {}
|
@ -1,17 +0,0 @@
|
||||
// #docplaster
|
||||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
// #enddocregion
|
||||
/*
|
||||
// #docregion template
|
||||
template: '<h1 highlight>{{title}}</h1>'
|
||||
// #enddocregion template
|
||||
*/
|
||||
// #docregion
|
||||
template: '<app-title></app-title>'
|
||||
})
|
||||
export class AppComponent {}
|
||||
// #enddocregion
|
@ -1,13 +0,0 @@
|
||||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
// #docregion template
|
||||
template: `
|
||||
<app-title></app-title>
|
||||
<app-contact></app-contact>
|
||||
`
|
||||
// #enddocregion template
|
||||
})
|
||||
export class AppComponent {}
|
@ -1,10 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
template: `
|
||||
<app-title></app-title>
|
||||
<app-contact></app-contact>
|
||||
`
|
||||
})
|
||||
export class AppComponent {}
|
@ -1,17 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
// #docregion template
|
||||
template: `
|
||||
<app-title></app-title>
|
||||
<nav>
|
||||
<a routerLink="contact" routerLinkActive="active">Contact</a>
|
||||
<a routerLink="crisis" routerLinkActive="active">Crisis Center</a>
|
||||
<a routerLink="heroes" routerLinkActive="active">Heroes</a>
|
||||
</nav>
|
||||
<router-outlet></router-outlet>
|
||||
`
|
||||
// #enddocregion template
|
||||
})
|
||||
export class AppComponent {}
|
@ -1,17 +0,0 @@
|
||||
// #docplaster
|
||||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
template: `
|
||||
<app-title></app-title>
|
||||
<nav>
|
||||
<a routerLink="contact" routerLinkActive="active">Contact</a>
|
||||
<a routerLink="crisis" routerLinkActive="active">Crisis Center</a>
|
||||
<a routerLink="heroes" routerLinkActive="active">Heroes</a>
|
||||
</nav>
|
||||
<router-outlet></router-outlet>
|
||||
`
|
||||
})
|
||||
export class AppComponent {}
|
@ -1,13 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { AppComponent } from './app.component.0';
|
||||
|
||||
@NgModule({
|
||||
// #docregion imports
|
||||
imports: [ BrowserModule ],
|
||||
// #enddocregion imports
|
||||
declarations: [ AppComponent ],
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
export class AppModule { }
|
@ -1,52 +0,0 @@
|
||||
// #docplaster
|
||||
// #docregion
|
||||
/* Angular Imports */
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
/* App Imports */
|
||||
// #enddocregion
|
||||
import { AppComponent } from './app.component.1';
|
||||
/*
|
||||
// #docregion
|
||||
import { AppComponent } from './app.component';
|
||||
// #enddocregion
|
||||
*/
|
||||
// #docregion
|
||||
import { HighlightDirective } from './highlight.directive';
|
||||
import { TitleComponent } from './title.component';
|
||||
import { UserService } from './user.service';
|
||||
|
||||
/* Contact Related Imports */
|
||||
import { FormsModule } from '@angular/forms';
|
||||
|
||||
import { AwesomePipe } from './contact/awesome.pipe';
|
||||
import { ContactComponent } from './contact/contact.component.3';
|
||||
import {
|
||||
ContactHighlightDirective as ContactHighlightDirective
|
||||
} from './contact/contact-highlight.directive';
|
||||
|
||||
@NgModule({
|
||||
// #docregion imports
|
||||
imports: [ BrowserModule, FormsModule ],
|
||||
// #enddocregion imports
|
||||
// #docregion declarations, directive, component
|
||||
declarations: [
|
||||
AppComponent,
|
||||
HighlightDirective,
|
||||
// #enddocregion directive
|
||||
TitleComponent,
|
||||
// #enddocregion component
|
||||
|
||||
AwesomePipe,
|
||||
ContactComponent,
|
||||
ContactHighlightDirective
|
||||
// #docregion directive, component
|
||||
],
|
||||
// #enddocregion declarations, directive, component
|
||||
// #docregion providers
|
||||
providers: [ UserService ],
|
||||
// #enddocregion providers
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
export class AppModule { }
|
@ -1,46 +0,0 @@
|
||||
// #docplaster
|
||||
// #docregion
|
||||
/* Angular Imports */
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
|
||||
/* App Imports */
|
||||
// #enddocregion
|
||||
import { AppComponent } from './app.component.1b';
|
||||
/*
|
||||
// #docregion
|
||||
import { AppComponent } from './app.component';
|
||||
// #enddocregion
|
||||
*/
|
||||
// #docregion
|
||||
import { HighlightDirective } from './highlight.directive';
|
||||
import { TitleComponent } from './title.component';
|
||||
import { UserService } from './user.service';
|
||||
|
||||
/* Contact Imports */
|
||||
// #enddocregion
|
||||
import { ContactComponent } from './contact/contact.component.3';
|
||||
/*
|
||||
// #docregion
|
||||
import { ContactComponent } from './contact/contact.component';
|
||||
// #enddocregion
|
||||
*/
|
||||
// #docregion
|
||||
import { AwesomePipe } from './contact/awesome.pipe';
|
||||
import { ContactService } from './contact/contact.service';
|
||||
import { ContactHighlightDirective } from './contact/contact-highlight.directive';
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule, FormsModule ],
|
||||
// #docregion declarations
|
||||
declarations: [
|
||||
AppComponent, HighlightDirective, TitleComponent,
|
||||
AwesomePipe, ContactComponent, ContactHighlightDirective
|
||||
],
|
||||
// #docregion providers
|
||||
providers: [ ContactService, UserService ],
|
||||
// #enddocregion providers
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
export class AppModule { }
|
@ -1,36 +0,0 @@
|
||||
// #docplaster
|
||||
// #docregion
|
||||
/* Angular Imports */
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
/* App Imports */
|
||||
// #enddocregion
|
||||
import { AppComponent } from './app.component.2';
|
||||
/*
|
||||
// #docregion
|
||||
import { AppComponent } from './app.component';
|
||||
// #enddocregion
|
||||
*/
|
||||
// #docregion
|
||||
import { HighlightDirective } from './highlight.directive';
|
||||
import { TitleComponent } from './title.component';
|
||||
import { UserService } from './user.service';
|
||||
|
||||
/* Contact Imports */
|
||||
// #enddocregion
|
||||
import { ContactModule } from './contact/contact.module.2';
|
||||
/*
|
||||
// #docregion
|
||||
import { ContactModule } from './contact/contact.module';
|
||||
// #enddocregion
|
||||
*/
|
||||
// #docregion
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule, ContactModule ],
|
||||
declarations: [ AppComponent, HighlightDirective, TitleComponent ],
|
||||
providers: [ UserService ],
|
||||
bootstrap: [ AppComponent ],
|
||||
})
|
||||
export class AppModule { }
|
@ -1,39 +0,0 @@
|
||||
// #docplaster
|
||||
// #docregion
|
||||
// #docregion v4
|
||||
/* Angular Imports */
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
/* App Imports */
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
/* Core Modules */
|
||||
import { CoreModule } from './core/core.module';
|
||||
|
||||
/* Routing Module */
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
|
||||
@NgModule({
|
||||
// #docregion import-for-root
|
||||
imports: [
|
||||
BrowserModule,
|
||||
// #enddocregion v4
|
||||
// #enddocregion import-for-root
|
||||
/*
|
||||
// #docregion v4
|
||||
CoreModule,
|
||||
// #enddocregion v4
|
||||
*/
|
||||
// #docregion import-for-root
|
||||
CoreModule.forRoot({userName: 'Miss Marple'}),
|
||||
// #docregion v4
|
||||
AppRoutingModule
|
||||
],
|
||||
// #enddocregion import-for-root
|
||||
declarations: [ AppComponent ],
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
export class AppModule { }
|
||||
// #enddocregion v4
|
||||
// #enddocregion
|
@ -1,14 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
import { ContactComponent } from './contact.component.3';
|
||||
|
||||
const routes = [
|
||||
{ path: 'contact', component: ContactComponent}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [ RouterModule.forChild(routes) ],
|
||||
exports: [ RouterModule ]
|
||||
})
|
||||
export class ContactRoutingModule {}
|
@ -1,16 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
import { ContactComponent } from './contact.component';
|
||||
|
||||
// #docregion routing
|
||||
const routes = [
|
||||
{ path: 'contact', component: ContactComponent}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [ RouterModule.forChild(routes) ],
|
||||
exports: [ RouterModule ]
|
||||
})
|
||||
export class ContactRoutingModule {}
|
||||
// #enddocregion
|
@ -1,53 +0,0 @@
|
||||
// #docregion
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { Contact, ContactService } from './contact.service';
|
||||
import { UserService } from '../user.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-contact',
|
||||
templateUrl: './contact.component.html',
|
||||
styleUrls: [ './contact.component.css' ]
|
||||
})
|
||||
export class ContactComponent implements OnInit {
|
||||
contact: Contact;
|
||||
contacts: Contact[];
|
||||
|
||||
msg = 'Loading contacts ...';
|
||||
userName = '';
|
||||
|
||||
constructor(private contactService: ContactService, userService: UserService) {
|
||||
this.userName = userService.userName;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.contactService.getContacts().subscribe(contacts => {
|
||||
this.msg = '';
|
||||
this.contacts = contacts;
|
||||
this.contact = contacts[0];
|
||||
});
|
||||
}
|
||||
|
||||
next() {
|
||||
let ix = 1 + this.contacts.indexOf(this.contact);
|
||||
if (ix >= this.contacts.length) { ix = 0; }
|
||||
this.contact = this.contacts[ix];
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
// POST-DEMO TODO: do something like save it
|
||||
this.displayMessage('Saved ' + this.contact.name);
|
||||
}
|
||||
|
||||
newContact() {
|
||||
this.displayMessage('New contact');
|
||||
this.contact = {id: 42, name: ''};
|
||||
this.contacts.push(this.contact);
|
||||
}
|
||||
|
||||
/** Display a message briefly, then remove it. */
|
||||
displayMessage(msg: string) {
|
||||
this.msg = msg;
|
||||
setTimeout(() => this.msg = '', 1500);
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
/* #docregion */
|
||||
.ng-valid[required] {
|
||||
border-left: 5px solid #42A948; /* green */
|
||||
}
|
||||
|
||||
.ng-invalid {
|
||||
border-left: 5px solid #a94442; /* red */
|
||||
}
|
||||
|
||||
.alert {
|
||||
padding: 15px;
|
||||
margin: 8px 0;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.alert-danger {
|
||||
color: #a94442;
|
||||
background-color: #f2dede;
|
||||
border-color: #ebccd1;
|
||||
}
|
||||
|
||||
.msg {
|
||||
color: blue;
|
||||
background-color: whitesmoke;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
padding-top: 12px;
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
<!-- #docregion -->
|
||||
<h2>Contact of {{userName}}</h2>
|
||||
<div *ngIf="msg" class="msg">{{msg}}</div>
|
||||
|
||||
<form *ngIf="contacts" (ngSubmit)="onSubmit()" #contactForm="ngForm">
|
||||
<!-- #docregion awesome -->
|
||||
<h3 highlight>{{ contact.name | awesome }}</h3>
|
||||
<!-- #enddocregion awesome -->
|
||||
|
||||
<div class="form-group">
|
||||
<label for="name">Name</label>
|
||||
|
||||
<!-- #docregion ngModel -->
|
||||
<input type="text" class="form-control" required
|
||||
[(ngModel)]="contact.name"
|
||||
name="name" #name="ngModel" >
|
||||
<!-- #enddocregion ngModel -->
|
||||
|
||||
<div [hidden]="name.valid" class="alert alert-danger">
|
||||
Name is required
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="button-group">
|
||||
<button type="submit" class="btn btn-default"
|
||||
[disabled]="!contactForm.form.valid">
|
||||
Save</button>
|
||||
|
||||
<button type="button" class="btn" (click)="next()"
|
||||
[disabled]="!contactForm.form.valid">
|
||||
Next Contact</button>
|
||||
|
||||
<button type="button" class="btn" (click)="newContact()">
|
||||
New Contact</button>
|
||||
</div>
|
||||
</form>
|
||||
<!-- #enddocregion -->
|
@ -1,54 +0,0 @@
|
||||
// Exact copy except import UserService from core
|
||||
// #docregion
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { Contact, ContactService } from './contact.service';
|
||||
import { UserService } from '../core/user.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-contact',
|
||||
templateUrl: './contact.component.html',
|
||||
styleUrls: [ './contact.component.css' ]
|
||||
})
|
||||
export class ContactComponent implements OnInit {
|
||||
contact: Contact;
|
||||
contacts: Contact[];
|
||||
|
||||
msg = 'Loading contacts ...';
|
||||
userName = '';
|
||||
|
||||
constructor(private contactService: ContactService, userService: UserService) {
|
||||
this.userName = userService.userName;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.contactService.getContacts().subscribe(contacts => {
|
||||
this.msg = '';
|
||||
this.contacts = contacts;
|
||||
this.contact = contacts[0];
|
||||
});
|
||||
}
|
||||
|
||||
next() {
|
||||
let ix = 1 + this.contacts.indexOf(this.contact);
|
||||
if (ix >= this.contacts.length) { ix = 0; }
|
||||
this.contact = this.contacts[ix];
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
// POST-DEMO TODO: do something like save it
|
||||
this.displayMessage('Saved ' + this.contact.name);
|
||||
}
|
||||
|
||||
newContact() {
|
||||
this.displayMessage('New contact');
|
||||
this.contact = {id: 42, name: ''};
|
||||
this.contacts.push(this.contact);
|
||||
}
|
||||
|
||||
/** Display a message briefly, then remove it. */
|
||||
displayMessage(msg: string) {
|
||||
this.msg = msg;
|
||||
setTimeout(() => this.msg = '', 1500);
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
// #docregion
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule
|
||||
],
|
||||
declarations: []
|
||||
})
|
||||
export class ContactModule { }
|
@ -1,37 +0,0 @@
|
||||
// #docplaster
|
||||
// #docregion
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
|
||||
import { AwesomePipe } from './awesome.pipe';
|
||||
// #enddocregion
|
||||
import { ContactComponent } from './contact.component.3';
|
||||
/*
|
||||
// #docregion
|
||||
import { ContactComponent } from './contact.component';
|
||||
// #enddocregion
|
||||
*/
|
||||
// #docregion
|
||||
import { ContactHighlightDirective } from './contact-highlight.directive';
|
||||
import { ContactService } from './contact.service';
|
||||
|
||||
// #docregion class
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule
|
||||
],
|
||||
declarations: [
|
||||
AwesomePipe,
|
||||
ContactComponent,
|
||||
ContactHighlightDirective
|
||||
],
|
||||
// #docregion exports
|
||||
exports: [ ContactComponent ],
|
||||
// #enddocregion exports
|
||||
providers: [ ContactService ]
|
||||
})
|
||||
export class ContactModule { }
|
||||
// #enddocregion class
|
||||
// #enddocregion
|
@ -1,44 +0,0 @@
|
||||
// #docplaster
|
||||
// #docregion
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
|
||||
import { AwesomePipe } from './awesome.pipe';
|
||||
// #enddocregion
|
||||
import { ContactComponent } from './contact.component.3';
|
||||
/*
|
||||
// #docregion
|
||||
import { ContactComponent } from './contact.component';
|
||||
// #enddocregion
|
||||
*/
|
||||
// #docregion
|
||||
import { ContactHighlightDirective } from './contact-highlight.directive';
|
||||
import { ContactService } from './contact.service';
|
||||
|
||||
// #enddocregion
|
||||
import { ContactRoutingModule } from './contact-routing.module.3';
|
||||
/*
|
||||
// #docregion
|
||||
import { ContactRoutingModule } from './contact-routing.module';
|
||||
// #enddocregion
|
||||
*/
|
||||
// #docregion
|
||||
|
||||
// #docregion class
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ContactRoutingModule
|
||||
],
|
||||
declarations: [
|
||||
AwesomePipe,
|
||||
ContactComponent,
|
||||
ContactHighlightDirective
|
||||
],
|
||||
providers: [ ContactService ]
|
||||
})
|
||||
export class ContactModule { }
|
||||
// #enddocregion class
|
||||
// #enddocregion
|
@ -1,19 +0,0 @@
|
||||
// #docregion
|
||||
import { NgModule } from '@angular/core';
|
||||
import { SharedModule } from '../shared/shared.module';
|
||||
|
||||
import { ContactComponent } from './contact.component';
|
||||
import { ContactService } from './contact.service';
|
||||
import { ContactRoutingModule } from './contact-routing.module';
|
||||
|
||||
// #docregion class
|
||||
@NgModule({
|
||||
imports: [
|
||||
SharedModule,
|
||||
ContactRoutingModule
|
||||
],
|
||||
declarations: [ ContactComponent ],
|
||||
providers: [ ContactService ]
|
||||
})
|
||||
export class ContactModule { }
|
||||
// #enddocregion class
|
@ -1,37 +0,0 @@
|
||||
// #docplaster
|
||||
// #docregion
|
||||
import { Injectable, OnDestroy } from '@angular/core';
|
||||
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { delay } from 'rxjs/operators';
|
||||
|
||||
export class Contact {
|
||||
constructor(public id: number, public name: string) { }
|
||||
}
|
||||
|
||||
const CONTACTS: Contact[] = [
|
||||
new Contact(21, 'Sam Spade'),
|
||||
new Contact(22, 'Nick Danger'),
|
||||
new Contact(23, 'Nancy Drew')
|
||||
];
|
||||
|
||||
const FETCH_LATENCY = 500;
|
||||
|
||||
/** Simulate a data service that retrieves contacts from a server */
|
||||
@Injectable()
|
||||
export class ContactService implements OnDestroy {
|
||||
// #enddocregion
|
||||
constructor() { console.log('ContactService instance created.'); }
|
||||
ngOnDestroy() { console.log('ContactService instance destroyed.'); }
|
||||
|
||||
// #docregion
|
||||
getContacts(): Observable<Contact[]> {
|
||||
return of(CONTACTS).pipe(delay(FETCH_LATENCY));
|
||||
}
|
||||
|
||||
getContact(id: number | string): Observable<Contact> {
|
||||
return of(CONTACTS.find(contact => contact.id === +id))
|
||||
.pipe(delay(FETCH_LATENCY));
|
||||
}
|
||||
}
|
||||
// #enddocregion
|
@ -1,48 +0,0 @@
|
||||
/* tslint:disable:member-ordering no-unused-variable */
|
||||
// #docplaster
|
||||
// #docregion
|
||||
// #docregion v4
|
||||
import {
|
||||
ModuleWithProviders, NgModule,
|
||||
Optional, SkipSelf } from '@angular/core';
|
||||
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { TitleComponent } from './title.component';
|
||||
import { UserService } from './user.service';
|
||||
// #enddocregion
|
||||
import { UserServiceConfig } from './user.service';
|
||||
|
||||
// #docregion v4
|
||||
@NgModule({
|
||||
imports: [ CommonModule ],
|
||||
declarations: [ TitleComponent ],
|
||||
exports: [ TitleComponent ],
|
||||
providers: [ UserService ]
|
||||
})
|
||||
export class CoreModule {
|
||||
// #enddocregion v4
|
||||
|
||||
// #docregion ctor
|
||||
constructor (@Optional() @SkipSelf() parentModule: CoreModule) {
|
||||
if (parentModule) {
|
||||
throw new Error(
|
||||
'CoreModule is already loaded. Import it in the AppModule only');
|
||||
}
|
||||
}
|
||||
// #enddocregion ctor
|
||||
|
||||
// #docregion for-root
|
||||
static forRoot(config: UserServiceConfig): ModuleWithProviders {
|
||||
return {
|
||||
ngModule: CoreModule,
|
||||
providers: [
|
||||
{provide: UserServiceConfig, useValue: config }
|
||||
]
|
||||
};
|
||||
}
|
||||
// #enddocregion for-root
|
||||
// #docregion v4
|
||||
}
|
||||
// #enddocregion v4
|
||||
// #enddocregion
|
@ -1,6 +0,0 @@
|
||||
<!-- Exact copy from earlier app.component.html -->
|
||||
<h1 highlight>{{title}}</h1>
|
||||
<p *ngIf="user">
|
||||
<i>Welcome, {{user}}</i>
|
||||
<p>
|
||||
|
@ -1,16 +0,0 @@
|
||||
// Exact copy of app/title.component.ts except import UserService from shared
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { UserService } from '../core/user.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-title',
|
||||
templateUrl: './title.component.html',
|
||||
})
|
||||
export class TitleComponent {
|
||||
title = 'Angular Modules';
|
||||
user = '';
|
||||
|
||||
constructor(userService: UserService) {
|
||||
this.user = userService.userName;
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
// Crazy copy of the app/user.service
|
||||
// Proves that UserService is an app-wide singleton and only instantiated once
|
||||
// IFF shared.module follows the `forRoot` pattern
|
||||
//
|
||||
// If it didn't, a new instance of UserService would be created
|
||||
// after each lazy load and the userName would double up.
|
||||
|
||||
import { Injectable, Optional } from '@angular/core';
|
||||
|
||||
let nextId = 1;
|
||||
|
||||
export class UserServiceConfig {
|
||||
userName = 'Philip Marlowe';
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class UserService {
|
||||
id = nextId++;
|
||||
private _userName = 'Sherlock Holmes';
|
||||
|
||||
// #docregion ctor
|
||||
constructor(@Optional() config: UserServiceConfig) {
|
||||
if (config) { this._userName = config.userName; }
|
||||
}
|
||||
// #enddocregion ctor
|
||||
|
||||
get userName() {
|
||||
// Demo: add a suffix if this service has been created more than once
|
||||
const suffix = this.id > 1 ? ` times ${this.id}` : '';
|
||||
return this._userName + suffix;
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<h3 highlight>Crisis Detail</h3>
|
||||
<div>Crisis id: {{id}}</div>
|
||||
<br>
|
||||
<a routerLink="../list">Crisis List</a>
|
||||
`
|
||||
})
|
||||
export class CrisisDetailComponent implements OnInit {
|
||||
id: number;
|
||||
constructor(private route: ActivatedRoute) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.id = parseInt(this.route.snapshot.paramMap.get('id'), 10);
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { Crisis,
|
||||
CrisisService } from './crisis.service';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<h3 highlight>Crisis List</h3>
|
||||
<div *ngFor='let crisis of crises | async'>
|
||||
<a routerLink="{{'../' + crisis.id}}">{{crisis.id}} - {{crisis.name}}</a>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
export class CrisisListComponent {
|
||||
crises: Observable<Crisis[]>;
|
||||
|
||||
constructor(private crisisService: CrisisService) {
|
||||
this.crises = this.crisisService.getCrises();
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Routes,
|
||||
RouterModule } from '@angular/router';
|
||||
|
||||
import { CrisisListComponent } from './crisis-list.component';
|
||||
import { CrisisDetailComponent } from './crisis-detail.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '', redirectTo: 'list', pathMatch: 'full'},
|
||||
{ path: 'list', component: CrisisListComponent },
|
||||
{ path: ':id', component: CrisisDetailComponent }
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class CrisisRoutingModule {}
|
@ -1,14 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { CrisisListComponent } from './crisis-list.component';
|
||||
import { CrisisDetailComponent } from './crisis-detail.component';
|
||||
import { CrisisService } from './crisis.service';
|
||||
import { CrisisRoutingModule } from './crisis-routing.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [ CommonModule, CrisisRoutingModule ],
|
||||
declarations: [ CrisisDetailComponent, CrisisListComponent ],
|
||||
providers: [ CrisisService ]
|
||||
})
|
||||
export class CrisisModule {}
|
@ -1,33 +0,0 @@
|
||||
import { Injectable, OnDestroy } from '@angular/core';
|
||||
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { delay } from 'rxjs/operators';
|
||||
|
||||
export class Crisis {
|
||||
constructor(public id: number, public name: string) { }
|
||||
}
|
||||
|
||||
const CRISES: Crisis[] = [
|
||||
new Crisis(1, 'Dragon Burning Cities'),
|
||||
new Crisis(2, 'Sky Rains Great White Sharks'),
|
||||
new Crisis(3, 'Giant Asteroid Heading For Earth'),
|
||||
new Crisis(4, 'Procrastinators Meeting Delayed Again'),
|
||||
];
|
||||
|
||||
const FETCH_LATENCY = 500;
|
||||
|
||||
/** Simulate a data service that retrieves crises from a server */
|
||||
@Injectable()
|
||||
export class CrisisService implements OnDestroy {
|
||||
constructor() { console.log('CrisisService instance created.'); }
|
||||
ngOnDestroy() { console.log('CrisisService instance destroyed.'); }
|
||||
|
||||
getCrises(): Observable<Crisis[]> {
|
||||
return of(CRISES).pipe(delay(FETCH_LATENCY));
|
||||
}
|
||||
|
||||
getCrisis(id: number | string): Observable<Crisis> {
|
||||
return of(CRISES.find(crisis => crisis.id === +id))
|
||||
.pipe(delay(FETCH_LATENCY));
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
|
||||
import { Hero,
|
||||
HeroService } from './hero.service';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<h3 highlight>Hero Detail</h3>
|
||||
<div *ngIf="hero">
|
||||
<div>Id: {{hero.id}}</div><br>
|
||||
<label>Name:
|
||||
<input [(ngModel)]="hero.name">
|
||||
</label>
|
||||
</div>
|
||||
<br>
|
||||
<a routerLink="../">Hero List</a>
|
||||
`
|
||||
})
|
||||
export class HeroDetailComponent implements OnInit {
|
||||
hero: Hero;
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private heroService: HeroService) { }
|
||||
|
||||
ngOnInit() {
|
||||
let id = parseInt(this.route.snapshot.paramMap.get('id'), 10);
|
||||
this.heroService.getHero(id).subscribe(hero => this.hero = hero);
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { Hero,
|
||||
HeroService } from './hero.service';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<h3 highlight>Hero List</h3>
|
||||
<div *ngFor='let hero of heroes | async'>
|
||||
<a routerLink="{{hero.id}}">{{hero.id}} - {{hero.name}}</a>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
export class HeroListComponent {
|
||||
heroes: Observable<Hero[]>;
|
||||
constructor(private heroService: HeroService) {
|
||||
this.heroes = this.heroService.getHeroes();
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Routes,
|
||||
RouterModule } from '@angular/router';
|
||||
|
||||
import { HeroComponent } from './hero.component.3';
|
||||
import { HeroListComponent } from './hero-list.component';
|
||||
import { HeroDetailComponent } from './hero-detail.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '',
|
||||
component: HeroComponent,
|
||||
children: [
|
||||
{ path: '', component: HeroListComponent },
|
||||
{ path: ':id', component: HeroDetailComponent }
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class HeroRoutingModule {}
|
@ -1,23 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Routes,
|
||||
RouterModule } from '@angular/router';
|
||||
|
||||
import { HeroComponent } from './hero.component';
|
||||
import { HeroListComponent } from './hero-list.component';
|
||||
import { HeroDetailComponent } from './hero-detail.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '',
|
||||
component: HeroComponent,
|
||||
children: [
|
||||
{ path: '', component: HeroListComponent },
|
||||
{ path: ':id', component: HeroDetailComponent }
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class HeroRoutingModule {}
|
@ -1,18 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
import { HeroService } from './hero.service';
|
||||
import { UserService } from '../user.service';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<h2>Heroes of {{userName}}</h2>
|
||||
<router-outlet></router-outlet>
|
||||
`,
|
||||
providers: [ HeroService ]
|
||||
})
|
||||
export class HeroComponent {
|
||||
userName = '';
|
||||
constructor(userService: UserService) {
|
||||
this.userName = userService.userName;
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
// Exact copy except import UserService from core
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
import { HeroService } from './hero.service';
|
||||
import { UserService } from '../core/user.service';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<h2>Heroes of {{userName}}</h2>
|
||||
<router-outlet></router-outlet>
|
||||
`,
|
||||
providers: [ HeroService ]
|
||||
})
|
||||
export class HeroComponent {
|
||||
userName = '';
|
||||
constructor(userService: UserService) {
|
||||
this.userName = userService.userName;
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
|
||||
import { HeroComponent } from './hero.component.3';
|
||||
import { HeroDetailComponent } from './hero-detail.component';
|
||||
import { HeroListComponent } from './hero-list.component';
|
||||
import { HeroRoutingModule } from './hero-routing.module.3';
|
||||
|
||||
import { HighlightDirective } from './highlight.directive';
|
||||
|
||||
// #docregion class
|
||||
@NgModule({
|
||||
imports: [ CommonModule, FormsModule, HeroRoutingModule ],
|
||||
declarations: [
|
||||
HeroComponent, HeroDetailComponent, HeroListComponent,
|
||||
HighlightDirective
|
||||
]
|
||||
})
|
||||
export class HeroModule { }
|
||||
// #enddocregion class
|
@ -1,16 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { SharedModule } from '../shared/shared.module';
|
||||
|
||||
import { HeroComponent } from './hero.component';
|
||||
import { HeroDetailComponent } from './hero-detail.component';
|
||||
import { HeroListComponent } from './hero-list.component';
|
||||
import { HeroRoutingModule } from './hero-routing.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [ SharedModule, HeroRoutingModule ],
|
||||
declarations: [
|
||||
HeroComponent, HeroDetailComponent, HeroListComponent,
|
||||
]
|
||||
})
|
||||
export class HeroModule { }
|
@ -1,36 +0,0 @@
|
||||
import { Injectable, OnDestroy } from '@angular/core';
|
||||
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { delay } from 'rxjs/operators';
|
||||
|
||||
export class Hero {
|
||||
constructor(public id: number, public name: string) { }
|
||||
}
|
||||
|
||||
const HEROES: Hero[] = [
|
||||
new Hero(11, 'Mr. Nice'),
|
||||
new Hero(12, 'Narco'),
|
||||
new Hero(13, 'Bombasto'),
|
||||
new Hero(14, 'Celeritas'),
|
||||
new Hero(15, 'Magneta'),
|
||||
new Hero(16, 'RubberMan')
|
||||
];
|
||||
|
||||
const FETCH_LATENCY = 500;
|
||||
|
||||
/** Simulate a data service that retrieves heroes from a server */
|
||||
@Injectable()
|
||||
export class HeroService implements OnDestroy {
|
||||
|
||||
constructor() { console.log('HeroService instance created.'); }
|
||||
ngOnDestroy() { console.log('HeroService instance destroyed.'); }
|
||||
|
||||
getHeroes(): Observable<Hero[]> {
|
||||
return of(HEROES).pipe(delay(FETCH_LATENCY));
|
||||
}
|
||||
|
||||
getHero(id: number | string): Observable<Hero> {
|
||||
return of(HEROES.find(hero => hero.id === +id))
|
||||
.pipe(delay(FETCH_LATENCY));
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
// Exact copy of contact.awesome.pipe
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
|
||||
@Pipe({ name: 'awesome' })
|
||||
/** Precede the input string with the word "Awesome " */
|
||||
export class AwesomePipe implements PipeTransform {
|
||||
transform(phrase: string) {
|
||||
return phrase ? 'Awesome ' + phrase : '';
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
// Exact copy of contact/highlight.directive except for color and message
|
||||
import { Directive, ElementRef } from '@angular/core';
|
||||
|
||||
@Directive({ selector: '[highlight], input' })
|
||||
// Highlight the host element or any InputElement in gray
|
||||
export class HighlightDirective {
|
||||
constructor(el: ElementRef) {
|
||||
el.nativeElement.style.backgroundColor = 'lightgray';
|
||||
console.log(
|
||||
`* Shared highlight called for ${el.nativeElement.tagName}`);
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
// #docregion
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
|
||||
import { AwesomePipe } from './awesome.pipe';
|
||||
import { HighlightDirective } from './highlight.directive';
|
||||
|
||||
// #docregion module
|
||||
@NgModule({
|
||||
imports: [ CommonModule ],
|
||||
declarations: [ AwesomePipe, HighlightDirective ],
|
||||
exports: [ AwesomePipe, HighlightDirective,
|
||||
CommonModule, FormsModule ]
|
||||
})
|
||||
export class SharedModule { }
|
||||
// #enddocregion module
|
||||
// #enddocregion
|
@ -1,8 +0,0 @@
|
||||
// #docregion
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
/** Dummy version of an authenticated user service */
|
||||
export class UserService {
|
||||
userName = 'Sherlock Holmes';
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<base href="/">
|
||||
<title>NgModule Minimal</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
</body>
|
||||
</html>
|
@ -1,13 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<base href="/">
|
||||
<title>NgModule Minimal</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
</body>
|
||||
</html>
|
@ -1,13 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<base href="/">
|
||||
<title>NgModule Minimal</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
</body>
|
||||
</html>
|
@ -1,13 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<base href="/">
|
||||
<title>NgModule Minimal</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
</body>
|
||||
</html>
|
@ -1,13 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<base href="/">
|
||||
<title>NgModule Deluxe</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
</body>
|
||||
</html>
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user