Compare commits
205 Commits
10.1.1
...
guide/libr
Author | SHA1 | Date | |
---|---|---|---|
5d8f869913 | |||
2ca7ee8f54 | |||
ebee38994f | |||
6ebb0246ab | |||
f8c56ec8eb | |||
c7a054fa31 | |||
6ff6acbb21 | |||
8a09cb9794 | |||
eeb59b4f4d | |||
7afbc3a1c1 | |||
3da8ebf27e | |||
7e33d531ae | |||
32577820f4 | |||
3686c640d6 | |||
cbe53247fa | |||
bbbae1065a | |||
b5c3bb998d | |||
4ff7aeadbb | |||
86eaf57d53 | |||
ff7b7a9c2f | |||
dea267e5c8 | |||
07200be358 | |||
45e6bb4a74 | |||
b44f7b1a5c | |||
3c9c40c4b7 | |||
15bb08eea6 | |||
10953bddcb | |||
7b87a797ed | |||
4ea5a19a10 | |||
ee263f3b97 | |||
f73846cd6b | |||
b2fd28d2b0 | |||
05535d985b | |||
4dc8aa2a27 | |||
3d084ac910 | |||
f8678d7513 | |||
c50136e2cb | |||
c3b4e0f37e | |||
4d33c41e92 | |||
eff4e3e3c2 | |||
e6c7536d62 | |||
5f4a06039e | |||
05b9bb71b1 | |||
c7cae616e0 | |||
14daffecc5 | |||
f6ae7d4f49 | |||
316d9d5c34 | |||
ba99c7792a | |||
66a2af0c77 | |||
ab87527e1d | |||
a0486577a8 | |||
6f4c65c029 | |||
295f3796c6 | |||
6362ec46d5 | |||
de2b1c4bb4 | |||
6aad16e11f | |||
78b657e8f3 | |||
ee9e65ecb1 | |||
5341121fde | |||
265581e525 | |||
06da025393 | |||
317bbd8f46 | |||
9cb99bbaa8 | |||
8a70ac0950 | |||
9956446ad7 | |||
f0865de125 | |||
5cb6779305 | |||
1e2e9201b2 | |||
6062e658db | |||
eca92ea193 | |||
3177ce1f35 | |||
faa17f8959 | |||
d42a09e9b6 | |||
408d38b223 | |||
333a1266cc | |||
a4912ff297 | |||
a9920d6776 | |||
71b1f1ad88 | |||
a198e2984c | |||
e160d8466c | |||
575479a6a1 | |||
8b97de61f5 | |||
d870e5c309 | |||
2da56a70a2 | |||
0b2f134680 | |||
5d32a199a9 | |||
f677c22fba | |||
97ae2d3b9b | |||
a3fe2de883 | |||
7f6c3b3fc1 | |||
ab4ab682e5 | |||
a69cb738a8 | |||
e9eeee5608 | |||
d89ab70036 | |||
fa82a82a07 | |||
39f92d985b | |||
da0129b83e | |||
c980caecac | |||
b88abd81c8 | |||
201c38e407 | |||
31c53670e7 | |||
e169f00193 | |||
e1ee231993 | |||
7d4aebd603 | |||
2cde8da71c | |||
6f54c28c87 | |||
17841959f5 | |||
cfe5fadb3a | |||
3cd4a5ded5 | |||
36156244a1 | |||
a66a804082 | |||
d2524eef7f | |||
f6d2af17fc | |||
a86754b4c4 | |||
2968435f81 | |||
4096bbfeee | |||
0314fd4b6e | |||
3f2257f209 | |||
271e0f9896 | |||
79b5e1891d | |||
b4b453d6de | |||
06f085560c | |||
38fb735551 | |||
b0ecee8155 | |||
ba46a0c05b | |||
0112164c34 | |||
f60fafbb2e | |||
004079b07a | |||
523a1a71d7 | |||
d3999d904a | |||
63894062d4 | |||
5c60a65eaf | |||
c387933d3c | |||
882336e0e6 | |||
e91aa6db32 | |||
325b3fd0db | |||
84348299b3 | |||
e934864a90 | |||
920205bc61 | |||
0dcc34837e | |||
57d8d7fcd4 | |||
f26f014ffc | |||
134aa72467 | |||
a7a8938291 | |||
9338556872 | |||
28ef4bc441 | |||
686f9ae4b2 | |||
a57119761b | |||
6881149540 | |||
4f842e23df | |||
47873a339a | |||
03e02185d9 | |||
e565d97bc8 | |||
6bf8d2b356 | |||
2981656ebe | |||
5ec0ba72cd | |||
f020941629 | |||
f1a92872a4 | |||
9e7ce2c916 | |||
788532dc99 | |||
54679ea9cc | |||
cb0aeaf708 | |||
8de04115ec | |||
e65e5ea9d0 | |||
19b577bf66 | |||
ccb0b42ffb | |||
1d46ef38d2 | |||
06356d806a | |||
45847c62ce | |||
9cb6bb8535 | |||
e9b25a1e98 | |||
ad51b996a2 | |||
8a05f311b9 | |||
e72267bc00 | |||
2e0973a814 | |||
27092a822a | |||
0cd8e48c36 | |||
2b95289ee2 | |||
5df5ce6463 | |||
04ad0077f4 | |||
1bf2f118c7 | |||
2119abf954 | |||
fc728d0cfb | |||
dd01edd168 | |||
7c3edad3d4 | |||
c4d76a65da | |||
db394e2b81 | |||
92c7145139 | |||
d133525502 | |||
cd1817bf6d | |||
0d1491b1a6 | |||
f67774d84b | |||
37668d159e | |||
38554288f5 | |||
04dcc3bceb | |||
0910a2fc0d | |||
3325cb2f86 | |||
a1e8443bfb | |||
599d34b41e | |||
7fd1733882 | |||
2e42123870 | |||
4cbb90daf7 | |||
cf2663b034 | |||
95681b16bd | |||
e620827fa8 |
@ -30,11 +30,6 @@ var_4: &cache_key_fallback v7-angular-node-12-{{ checksum ".bazelversion" }}
|
||||
var_3_win: &cache_key_win v7-angular-win-node-12-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "packages/bazel/package.bzl" }}-{{ checksum "aio/yarn.lock" }}
|
||||
var_4_win: &cache_key_win_fallback v7-angular-win-node-12-{{ checksum ".bazelversion" }}
|
||||
|
||||
# Cache key for the `components-repo-unit-tests` job. **Note** when updating the SHA in the
|
||||
# cache keys also update the SHA for the "COMPONENTS_REPO_COMMIT" environment variable.
|
||||
var_5: &components_repo_unit_tests_cache_key v9-angular-components-09e68db8ed5b1253f2fe38ff954ef0df019fc25a
|
||||
var_6: &components_repo_unit_tests_cache_key_fallback v9-angular-components-
|
||||
|
||||
# Workspace initially persisted by the `setup` job, and then enhanced by `build-npm-packages` and
|
||||
# `build-ivy-npm-packages`.
|
||||
# https://circleci.com/docs/2.0/workflows/#using-workspaces-to-share-data-among-jobs
|
||||
@ -156,27 +151,6 @@ commands:
|
||||
git config --global url."ssh://git@github.com".insteadOf "https://github.com" || true
|
||||
git config --global gc.auto 0 || true
|
||||
|
||||
init_saucelabs_environment:
|
||||
description: Sets up a domain that resolves to the local host.
|
||||
steps:
|
||||
- run:
|
||||
name: Preparing environment for running tests on Sauce Labs.
|
||||
command: |
|
||||
# For SauceLabs jobs, we set up a domain which resolves to the machine which launched
|
||||
# the tunnel. We do this because devices are sometimes not able to properly resolve
|
||||
# `localhost` or `127.0.0.1` through the SauceLabs tunnel. Using a domain that does not
|
||||
# resolve to anything on SauceLabs VMs ensures that such requests are always resolved
|
||||
# through the tunnel, and resolve to the actual tunnel host machine (i.e. the CircleCI VM).
|
||||
# More context can be found in: https://github.com/angular/angular/pull/35171.
|
||||
setPublicVar SAUCE_LOCALHOST_ALIAS_DOMAIN "angular-ci.local"
|
||||
setSecretVar SAUCE_ACCESS_KEY $(echo $SAUCE_ACCESS_KEY | rev)
|
||||
- run:
|
||||
# Sets up a local domain in the machine's host file that resolves to the local
|
||||
# host. This domain is helpful in Sauce Labs tests where devices are not able to
|
||||
# properly resolve `localhost` or `127.0.0.1` through the sauce-connect tunnel.
|
||||
name: Setting up alias domain for local host.
|
||||
command: echo "127.0.0.1 $SAUCE_LOCALHOST_ALIAS_DOMAIN" | sudo tee -a /etc/hosts
|
||||
|
||||
# Normally this would be an individual job instead of a command.
|
||||
# But startup and setup time for each individual windows job are high enough to discourage
|
||||
# many small jobs, so instead we use a command for setup unless the gain becomes significant.
|
||||
@ -272,109 +246,8 @@ jobs:
|
||||
- run: yarn -s tslint
|
||||
- run: yarn -s ng-dev format changed $CI_GIT_BASE_REVISION --check
|
||||
- run: yarn -s ts-circular-deps:check
|
||||
- run: yarn -s ng-dev pullapprove verify
|
||||
- run: yarn -s ng-dev commit-message validate-range --range $CI_COMMIT_RANGE
|
||||
|
||||
test:
|
||||
executor:
|
||||
name: default-executor
|
||||
# Now that large integration tests are running locally in parallel (they can't run on RBE yet
|
||||
# as they require network access for yarn install), this test is running out of memory
|
||||
# consistently with the xlarge machine.
|
||||
# TODO: switch back to xlarge once integration tests are running on remote-exec
|
||||
resource_class: 2xlarge+
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
- install_chrome_libs
|
||||
- install_java
|
||||
- run:
|
||||
command: yarn bazel test //... --build_tag_filters=-ivy-only --test_tag_filters=-ivy-only
|
||||
no_output_timeout: 20m
|
||||
|
||||
# Temporary job to test what will happen when we flip the Ivy flag to true
|
||||
test_ivy_aot:
|
||||
executor:
|
||||
name: default-executor
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
- install_chrome_libs
|
||||
# We need to explicitly specify the --symlink_prefix option because otherwise we would
|
||||
# not be able to easily find the output bin directory when uploading artifacts for size
|
||||
# measurements.
|
||||
- run:
|
||||
command: yarn test-ivy-aot //... --symlink_prefix=dist/
|
||||
no_output_timeout: 20m
|
||||
|
||||
# Publish bundle artifacts which will be used to calculate the size change. **Note**: Make
|
||||
# sure that the size plugin from the Angular robot fetches the artifacts from this CircleCI
|
||||
# job (see .github/angular-robot.yml). Additionally any artifacts need to be stored with the
|
||||
# following path format: "{projectName}/{context}/{fileName}". This format is necessary
|
||||
# because otherwise the bot is not able to pick up the artifacts from CircleCI. See:
|
||||
# https://github.com/angular/github-robot/blob/master/functions/src/plugins/size.ts#L392-L394
|
||||
- store_artifacts:
|
||||
path: dist/bin/packages/core/test/bundling/hello_world/bundle.min.js
|
||||
destination: core/hello_world/bundle
|
||||
- store_artifacts:
|
||||
path: dist/bin/packages/core/test/bundling/todo/bundle.min.js
|
||||
destination: core/todo/bundle
|
||||
- store_artifacts:
|
||||
path: dist/bin/packages/core/test/bundling/hello_world/bundle.min.js.br
|
||||
destination: core/hello_world/bundle.br
|
||||
- store_artifacts:
|
||||
path: dist/bin/packages/core/test/bundling/todo/bundle.min.js.br
|
||||
destination: core/todo/bundle.br
|
||||
|
||||
# NOTE: This is currently limited to master builds only. See the `monitoring` configuration.
|
||||
saucelabs_view_engine:
|
||||
executor:
|
||||
name: default-executor
|
||||
# In order to avoid the bottleneck of having a slow host machine, we acquire a better
|
||||
# container for this job. This is necessary because we launch a lot of browsers concurrently
|
||||
# and therefore the tunnel and Karma need to process a lot of file requests and tests.
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
- init_saucelabs_environment
|
||||
- run:
|
||||
name: Run Bazel tests on Saucelabs with ViewEngine
|
||||
# See /tools/saucelabs/README.md for more info
|
||||
command: |
|
||||
yarn bazel run //tools/saucelabs:sauce_service_setup
|
||||
TESTS=$(./node_modules/.bin/bazelisk query --output label '(kind(karma_web_test, ...) intersect attr("tags", "saucelabs", ...)) except attr("tags", "ivy-only", ...) except attr("tags", "fixme-saucelabs-ve", ...)')
|
||||
yarn bazel test --config=saucelabs ${TESTS}
|
||||
yarn bazel run //tools/saucelabs:sauce_service_stop
|
||||
no_output_timeout: 40m
|
||||
- notify_webhook_on_fail:
|
||||
webhook_url_env_var: SLACK_DEV_INFRA_CI_FAILURES_WEBHOOK_URL
|
||||
|
||||
# NOTE: This is currently limited to master builds only. See the `monitoring` configuration.
|
||||
saucelabs_ivy:
|
||||
executor:
|
||||
name: default-executor
|
||||
# In order to avoid the bottleneck of having a slow host machine, we acquire a better
|
||||
# container for this job. This is necessary because we launch a lot of browsers concurrently
|
||||
# and therefore the tunnel and Karma need to process a lot of file requests and tests.
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
- init_saucelabs_environment
|
||||
- run:
|
||||
name: Run Bazel tests on Saucelabs with Ivy
|
||||
# See /tools/saucelabs/README.md for more info
|
||||
command: |
|
||||
yarn bazel run //tools/saucelabs:sauce_service_setup
|
||||
TESTS=$(./node_modules/.bin/bazelisk query --output label '(kind(karma_web_test, ...) intersect attr("tags", "saucelabs", ...)) except attr("tags", "no-ivy-aot", ...) except attr("tags", "fixme-saucelabs-ivy", ...)')
|
||||
yarn bazel test --config=saucelabs --config=ivy ${TESTS}
|
||||
yarn bazel run //tools/saucelabs:sauce_service_stop
|
||||
no_output_timeout: 40m
|
||||
- notify_webhook_on_fail:
|
||||
webhook_url_env_var: SLACK_DEV_INFRA_CI_FAILURES_WEBHOOK_URL
|
||||
|
||||
test_aio:
|
||||
executor: default-executor
|
||||
steps:
|
||||
@ -393,10 +266,6 @@ jobs:
|
||||
- run: yarn --cwd aio test-pwa-score-localhost $CI_AIO_MIN_PWA_SCORE
|
||||
# Run accessibility tests
|
||||
- run: yarn --cwd aio test-a11y-score-localhost
|
||||
# Check the bundle sizes.
|
||||
- run: yarn --cwd aio payload-size
|
||||
# Run unit tests for Firebase redirects
|
||||
- run: yarn --cwd aio redirects-test
|
||||
|
||||
deploy_aio:
|
||||
executor: default-executor
|
||||
@ -426,8 +295,6 @@ jobs:
|
||||
- run: yarn --cwd aio e2e --configuration=ci
|
||||
# Run PWA-score tests
|
||||
- run: yarn --cwd aio test-pwa-score-localhost $CI_AIO_MIN_PWA_SCORE
|
||||
# Check the bundle sizes.
|
||||
- run: yarn --cwd aio payload-size aio-local<<# parameters.viewengine >>-viewengine<</ parameters.viewengine >>
|
||||
|
||||
test_aio_tools:
|
||||
executor: default-executor
|
||||
@ -441,26 +308,6 @@ jobs:
|
||||
- run: yarn --cwd aio tools-test
|
||||
- run: ./aio/aio-builds-setup/scripts/test.sh
|
||||
|
||||
test_docs_examples:
|
||||
parameters:
|
||||
viewengine:
|
||||
type: boolean
|
||||
default: false
|
||||
executor:
|
||||
name: default-executor
|
||||
resource_class: xlarge
|
||||
parallelism: 5
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
- install_chrome_libs
|
||||
# Install aio
|
||||
- run: yarn --cwd aio install --frozen-lockfile --non-interactive
|
||||
# Run examples tests. The "CIRCLE_NODE_INDEX" will be set if "parallelism" is enabled.
|
||||
# Since the parallelism is set to "5", there will be five parallel CircleCI containers.
|
||||
# with either "0", "1", etc as node index. This can be passed to the "--shard" argument.
|
||||
- run: yarn --cwd aio example-e2e --setup --local <<# parameters.viewengine >>--viewengine<</ parameters.viewengine >> --cliSpecsConcurrency=5 --shard=${CIRCLE_NODE_INDEX}/${CIRCLE_NODE_TOTAL} --retry 2
|
||||
|
||||
# This job should only be run on PR builds, where `CI_PULL_REQUEST` is not `false`.
|
||||
aio_preview:
|
||||
executor: default-executor
|
||||
@ -489,7 +336,6 @@ jobs:
|
||||
name: Wait for preview and run tests
|
||||
command: node aio/scripts/test-preview.js $CI_PULL_REQUEST $CI_COMMIT $CI_AIO_MIN_PWA_SCORE
|
||||
|
||||
|
||||
# The `build-npm-packages` tasks exist for backwards-compatibility with old scripts and
|
||||
# tests that rely on the pre-Bazel `dist/packages-dist` output structure (build.sh).
|
||||
# Having multiple jobs that independently build in this manner duplicates some work; we build
|
||||
@ -501,7 +347,7 @@ jobs:
|
||||
build-npm-packages:
|
||||
executor:
|
||||
name: default-executor
|
||||
resource_class: xlarge
|
||||
resource_class: medium
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
@ -523,246 +369,6 @@ jobs:
|
||||
- "~/bazel_repository_cache"
|
||||
- "~/.cache/bazelisk"
|
||||
|
||||
# Build the ivy npm packages.
|
||||
build-ivy-npm-packages:
|
||||
executor:
|
||||
name: default-executor
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
- run: node scripts/build/build-ivy-npm-packages.js
|
||||
|
||||
# Save the npm packages from //packages/... for other workflow jobs to read
|
||||
- persist_to_workspace:
|
||||
root: *workspace_location
|
||||
paths:
|
||||
- ng/dist/packages-dist-ivy-aot
|
||||
- ng/dist/zone.js-dist-ivy-aot
|
||||
|
||||
# This job creates compressed tarballs (`.tgz` files) for all Angular packages and stores them as
|
||||
# build artifacts. This makes it easy to try out changes from a PR build for testing purposes.
|
||||
# More info CircleCI build artifacts: https://circleci.com/docs/2.0/artifacts
|
||||
#
|
||||
# NOTE: Currently, this job only runs for PR builds. See `publish_snapshot` for non-PR builds.
|
||||
publish_packages_as_artifacts:
|
||||
executor: default-executor
|
||||
environment:
|
||||
NG_PACKAGES_DIR: &ng_packages_dir 'dist/packages-dist'
|
||||
NG_PACKAGES_ARCHIVES_DIR: &ng_packages_archives_dir 'dist/packages-dist-archives'
|
||||
ZONEJS_PACKAGES_DIR: &zonejs_packages_dir 'dist/zone.js-dist'
|
||||
ZONEJS_PACKAGES_ARCHIVES_DIR: &zonejs_packages_archives_dir 'dist/zone.js-dist-archives'
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
# Publish `@angular/*` packages.
|
||||
- run:
|
||||
name: Create artifacts for @angular/* packages
|
||||
command: ./scripts/ci/create-package-archives.sh $CI_BRANCH $CI_COMMIT $NG_PACKAGES_DIR $NG_PACKAGES_ARCHIVES_DIR
|
||||
- store_artifacts:
|
||||
path: *ng_packages_archives_dir
|
||||
destination: angular
|
||||
# Publish `zone.js` package.
|
||||
- run:
|
||||
name: Create artifacts for zone.js package
|
||||
command: ./scripts/ci/create-package-archives.sh $CI_BRANCH $CI_COMMIT $ZONEJS_PACKAGES_DIR $ZONEJS_PACKAGES_ARCHIVES_DIR
|
||||
- store_artifacts:
|
||||
path: *zonejs_packages_archives_dir
|
||||
destination: zone.js
|
||||
|
||||
# This job updates the content of repos like github.com/angular/core-builds
|
||||
# for every green build on angular/angular.
|
||||
publish_snapshot:
|
||||
executor: default-executor
|
||||
steps:
|
||||
# See below - ideally this job should not trigger for non-upstream builds.
|
||||
# But since it does, we have to check this condition.
|
||||
- run:
|
||||
name: Skip this job for Pull Requests and Fork builds
|
||||
# Note: Using `CIRCLE_*` env variables (instead of those defined in `env.sh` so that this
|
||||
# step can be run before `init_environment`.
|
||||
command: >
|
||||
if [[ -n "${CIRCLE_PR_NUMBER}" ]] ||
|
||||
[[ "$CIRCLE_PROJECT_USERNAME" != "angular" ]] ||
|
||||
[[ "$CIRCLE_PROJECT_REPONAME" != "angular" ]]; then
|
||||
circleci step halt
|
||||
fi
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
# CircleCI has a config setting to force SSH for all github connections
|
||||
# This is not compatible with our mechanism of using a Personal Access Token
|
||||
# Clear the global setting
|
||||
- run: git config --global --unset "url.ssh://git@github.com.insteadof"
|
||||
- run:
|
||||
name: Decrypt github credentials
|
||||
# We need ensure that the same default digest is used for encoding and decoding with
|
||||
# OpenSSL. OpenSSL versions might have different default digests which can cause
|
||||
# decryption failures based on the installed OpenSSL version. https://stackoverflow.com/a/39641378/4317734
|
||||
command: 'openssl aes-256-cbc -d -in .circleci/github_token -md md5 -k "${KEY}" -out ~/.git_credentials'
|
||||
- run: ./scripts/ci/publish-build-artifacts.sh
|
||||
|
||||
aio_monitoring_stable:
|
||||
executor: default-executor
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
- install_chrome_libs
|
||||
- run: setPublicVar_CI_STABLE_BRANCH
|
||||
- run:
|
||||
name: Check out `aio/` and yarn from the stable branch
|
||||
command: |
|
||||
git fetch origin $CI_STABLE_BRANCH
|
||||
git checkout --force origin/$CI_STABLE_BRANCH -- aio/ .yarn/ .yarnrc
|
||||
# Ignore yarn's engines check, because we checked out `aio/package.json` from the stable
|
||||
# branch and there could be a node version skew, which is acceptable in this monitoring job.
|
||||
- run: yarn config set ignore-engines true
|
||||
- run:
|
||||
name: Run tests against https://angular.io/
|
||||
command: ./aio/scripts/test-production.sh https://angular.io/ $CI_AIO_MIN_PWA_SCORE
|
||||
- notify_webhook_on_fail:
|
||||
webhook_url_env_var: SLACK_CARETAKER_WEBHOOK_URL
|
||||
- notify_webhook_on_fail:
|
||||
webhook_url_env_var: SLACK_DEV_INFRA_CI_FAILURES_WEBHOOK_URL
|
||||
|
||||
aio_monitoring_next:
|
||||
executor: default-executor
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
- install_chrome_libs
|
||||
- run:
|
||||
name: Run tests against https://next.angular.io/
|
||||
command: ./aio/scripts/test-production.sh https://next.angular.io/ $CI_AIO_MIN_PWA_SCORE
|
||||
- notify_webhook_on_fail:
|
||||
webhook_url_env_var: SLACK_CARETAKER_WEBHOOK_URL
|
||||
- notify_webhook_on_fail:
|
||||
webhook_url_env_var: SLACK_DEV_INFRA_CI_FAILURES_WEBHOOK_URL
|
||||
|
||||
legacy-unit-tests-saucelabs:
|
||||
executor:
|
||||
name: default-executor
|
||||
# In order to avoid the bottleneck of having a slow host machine, we acquire a better
|
||||
# container for this job. This is necessary because we launch a lot of browsers concurrently
|
||||
# and therefore the tunnel and Karma need to process a lot of file requests and tests.
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
- init_saucelabs_environment
|
||||
- run:
|
||||
name: Starting Saucelabs tunnel service
|
||||
command: ./tools/saucelabs/sauce-service.sh run
|
||||
background: true
|
||||
- run: yarn tsc -p packages
|
||||
- run: yarn tsc -p modules
|
||||
- run: yarn bazel build //packages/zone.js:npm_package
|
||||
- run:
|
||||
# Waiting on ready ensures that we don't run tests too early without Saucelabs not being ready.
|
||||
name: Waiting for Saucelabs tunnel to connect
|
||||
command: ./tools/saucelabs/sauce-service.sh ready-wait
|
||||
- run:
|
||||
name: Running tests on Saucelabs.
|
||||
command: |
|
||||
browsers=$(node -e 'console.log(require("./browser-providers.conf").sauceAliases.CI_REQUIRED.join(","))')
|
||||
yarn karma start ./karma-js.conf.js --single-run --browsers=${browsers}
|
||||
- run:
|
||||
name: Stop Saucelabs tunnel service
|
||||
command: ./tools/saucelabs/sauce-service.sh stop
|
||||
|
||||
# Job that runs all unit tests of the `angular/components` repository.
|
||||
components-repo-unit-tests:
|
||||
executor:
|
||||
name: default-executor
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
# Restore the cache before cloning the repository because the clone script re-uses
|
||||
# the restored repository if present. This reduces the amount of times the components
|
||||
# repository needs to be cloned (this is slow and increases based on commits in the repo).
|
||||
- restore_cache:
|
||||
keys:
|
||||
- *components_repo_unit_tests_cache_key
|
||||
# Whenever the `angular/components` SHA is updated, the cache key will no longer
|
||||
# match. The fallback cache will still match, and CircleCI will restore the most
|
||||
# recently cached repository folder. Without the fallback cache, we'd need to download
|
||||
# the repository from scratch and it would slow down the job. This is because we can't
|
||||
# clone the repository with reduced `--depth`, but rather need to clone the whole
|
||||
# repository to be able to support arbitrary SHAs.
|
||||
- *components_repo_unit_tests_cache_key_fallback
|
||||
- run:
|
||||
name: "Fetching angular/components repository"
|
||||
command: ./scripts/ci/clone_angular_components_repo.sh
|
||||
- run:
|
||||
# Run yarn install to fetch the Bazel binaries as used in the components repo.
|
||||
name: Installing dependencies.
|
||||
# TODO: remove this once the repo has been updated to use NodeJS v12 and Yarn 1.19.1.
|
||||
# We temporarily ignore the "engines" because the Angular components repository has
|
||||
# minimum dependency on NodeJS v12 and Yarn 1.19.1, but the framework repository uses
|
||||
# older versions.
|
||||
command: yarn --ignore-engines --cwd ${COMPONENTS_REPO_TMP_DIR} install --frozen-lockfile --non-interactive
|
||||
- save_cache:
|
||||
key: *components_repo_unit_tests_cache_key
|
||||
paths:
|
||||
# Temporary directory must be kept in sync with the `$COMPONENTS_REPO_TMP_DIR` env
|
||||
# variable. It needs to be hardcoded here, because env variables interpolation is
|
||||
# not supported.
|
||||
- "/tmp/angular-components-repo"
|
||||
- run:
|
||||
# Updates the `angular/components` `package.json` file to refer to the release output
|
||||
# inside the `packages-dist` directory. Note that it's not necessary to perform a yarn
|
||||
# install as Bazel runs Yarn automatically when needed.
|
||||
name: Setting up release packages.
|
||||
command: node scripts/ci/update-deps-to-dist-packages.js ${COMPONENTS_REPO_TMP_DIR}/package.json dist/packages-dist/
|
||||
- run:
|
||||
name: "Running `angular/components` unit tests"
|
||||
command: ./scripts/ci/run_angular_components_unit_tests.sh
|
||||
|
||||
test_zonejs:
|
||||
executor:
|
||||
name: default-executor
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
# Install
|
||||
- run: yarn --cwd packages/zone.js install --frozen-lockfile --non-interactive
|
||||
# Run zone.js tools tests
|
||||
- run: yarn --cwd packages/zone.js promisetest
|
||||
- run: yarn --cwd packages/zone.js promisefinallytest
|
||||
- run: yarn bazel build //packages/zone.js:npm_package &&
|
||||
cp dist/bin/packages/zone.js/npm_package/bundles/zone-mix.umd.js ./packages/zone.js/test/extra/ &&
|
||||
cp dist/bin/packages/zone.js/npm_package/bundles/zone-patch-electron.umd.js ./packages/zone.js/test/extra/ &&
|
||||
yarn --cwd packages/zone.js electrontest
|
||||
- run: yarn --cwd packages/zone.js jesttest
|
||||
|
||||
# Windows jobs
|
||||
# Docs: https://circleci.com/docs/2.0/hello-world-windows/
|
||||
test_win:
|
||||
executor: windows-executor
|
||||
steps:
|
||||
- setup_win
|
||||
- run:
|
||||
# Ran into a command parsing problem where `-browser:chromium-local` was converted to
|
||||
# `-browser: chromium-local` (a space was added) in https://circleci.com/gh/angular/angular/357511.
|
||||
# Probably a powershell command parsing thing. There's no problem using a yarn script though.
|
||||
command: yarn circleci-win-ve
|
||||
no_output_timeout: 45m
|
||||
# Save bazel repository cache to use on subsequent runs.
|
||||
# We don't save node_modules because it's faster to use the linux workspace and reinstall.
|
||||
- save_cache:
|
||||
key: *cache_key_win
|
||||
paths:
|
||||
- "C:/Users/circleci/bazel_repository_cache"
|
||||
|
||||
test_ivy_aot_win:
|
||||
executor: windows-executor
|
||||
steps:
|
||||
- setup_win
|
||||
- run:
|
||||
command: yarn circleci-win-ivy
|
||||
no_output_timeout: 45m
|
||||
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
@ -775,21 +381,9 @@ workflows:
|
||||
- lint:
|
||||
requires:
|
||||
- setup
|
||||
- test:
|
||||
requires:
|
||||
- setup
|
||||
- test_ivy_aot:
|
||||
requires:
|
||||
- setup
|
||||
- build-npm-packages:
|
||||
requires:
|
||||
- setup
|
||||
- build-ivy-npm-packages:
|
||||
requires:
|
||||
- setup
|
||||
- legacy-unit-tests-saucelabs:
|
||||
requires:
|
||||
- setup
|
||||
- test_aio:
|
||||
requires:
|
||||
- setup
|
||||
@ -799,22 +393,9 @@ workflows:
|
||||
- test_aio_local:
|
||||
requires:
|
||||
- build-npm-packages
|
||||
- test_aio_local:
|
||||
name: test_aio_local_viewengine
|
||||
viewengine: true
|
||||
requires:
|
||||
- build-npm-packages
|
||||
- test_aio_tools:
|
||||
requires:
|
||||
- build-npm-packages
|
||||
- test_docs_examples:
|
||||
requires:
|
||||
- build-npm-packages
|
||||
- test_docs_examples:
|
||||
name: test_docs_examples_viewengine
|
||||
viewengine: true
|
||||
requires:
|
||||
- build-npm-packages
|
||||
- aio_preview:
|
||||
# Only run on PR builds. (There can be no previews for non-PR builds.)
|
||||
<<: *only_on_pull_requests
|
||||
@ -823,78 +404,3 @@ workflows:
|
||||
- test_aio_preview:
|
||||
requires:
|
||||
- aio_preview
|
||||
- publish_packages_as_artifacts:
|
||||
requires:
|
||||
- build-npm-packages
|
||||
- publish_snapshot:
|
||||
# Note: no filters on this job because we want it to run for all upstream branches
|
||||
# We'd really like to filter out pull requests here, but not yet available:
|
||||
# https://discuss.circleci.com/t/workflows-pull-request-filter/14396/4
|
||||
# Instead, the job just exits immediately at the first step.
|
||||
requires:
|
||||
# Only publish if tests and integration tests pass
|
||||
- test
|
||||
- test_ivy_aot
|
||||
# Only publish if `aio`/`docs` tests using the locally built Angular packages pass
|
||||
- test_aio_local
|
||||
- test_aio_local_viewengine
|
||||
- test_docs_examples
|
||||
- test_docs_examples_viewengine
|
||||
# Get the artifacts to publish from the build-packages-dist job
|
||||
# since the publishing script expects the legacy outputs layout.
|
||||
- build-npm-packages
|
||||
- build-ivy-npm-packages
|
||||
- legacy-unit-tests-saucelabs
|
||||
- components-repo-unit-tests:
|
||||
requires:
|
||||
- build-npm-packages
|
||||
- test_zonejs:
|
||||
requires:
|
||||
- setup
|
||||
# Windows Jobs
|
||||
# These are very slow so we run them on non-PRs only for now.
|
||||
# TODO: remove the filter when CircleCI makes Windows FS faster.
|
||||
# The Windows jobs are only run after their non-windows counterparts finish successfully.
|
||||
# This isn't strictly necessary as there is no artifact dependency, but helps economize
|
||||
# CI resources by not attempting to build when we know should fail.
|
||||
- test_win:
|
||||
<<: *skip_on_pull_requests
|
||||
requires:
|
||||
- test
|
||||
- test_ivy_aot_win:
|
||||
<<: *skip_on_pull_requests
|
||||
requires:
|
||||
- test_ivy_aot
|
||||
|
||||
monitoring:
|
||||
jobs:
|
||||
- setup
|
||||
- aio_monitoring_stable:
|
||||
requires:
|
||||
- setup
|
||||
- aio_monitoring_next:
|
||||
requires:
|
||||
- setup
|
||||
- saucelabs_ivy:
|
||||
# Testing saucelabs via Bazel currently taking longer than the legacy saucelabs job as it
|
||||
# each karma_web_test target is provisioning and tearing down browsers which is adding
|
||||
# a lot of overhead. Running once daily on master only to avoid wasting resources and
|
||||
# slowing down CI for PRs.
|
||||
# TODO: Run this job on all branches (including PRs) once karma_web_test targets can
|
||||
# share provisioned browsers and we can remove the legacy saucelabs job.
|
||||
requires:
|
||||
- setup
|
||||
- saucelabs_view_engine:
|
||||
# Testing saucelabs via Bazel currently taking longer than the legacy saucelabs job as it
|
||||
# each karma_web_test target is provisioning and tearing down browsers which is adding
|
||||
# a lot of overhead. Running once daily on master only to avoid wasting resources and
|
||||
# slowing down CI for PRs.
|
||||
# TODO: Run this job on all branches (including PRs) once karma_web_test targets can
|
||||
# share provisioned browsers and we can remove the legacy saucelabs job.
|
||||
requires:
|
||||
- setup
|
||||
triggers:
|
||||
- schedule:
|
||||
<<: *only_on_master
|
||||
# Runs monitoring jobs at 10:00AM every day.
|
||||
cron: "0 10 * * *"
|
||||
|
@ -17,7 +17,7 @@ echo "source $envHelpersPath;" >> $BASH_ENV;
|
||||
####################################################################################################
|
||||
setPublicVar CI "$CI"
|
||||
setPublicVar PROJECT_ROOT "$projectDir";
|
||||
setPublicVar CI_AIO_MIN_PWA_SCORE "95";
|
||||
setPublicVar CI_AIO_MIN_PWA_SCORE "62";
|
||||
# This is the branch being built; e.g. `pull/12345` for PR builds.
|
||||
setPublicVar CI_BRANCH "$CIRCLE_BRANCH";
|
||||
setPublicVar CI_BUILD_URL "$CIRCLE_BUILD_URL";
|
||||
|
69
.github/ISSUE_TEMPLATE/1-bug-report.md
vendored
69
.github/ISSUE_TEMPLATE/1-bug-report.md
vendored
@ -1,69 +0,0 @@
|
||||
---
|
||||
name: "\U0001F41EBug report"
|
||||
about: Report a bug in the Angular Framework
|
||||
---
|
||||
<!--🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅
|
||||
|
||||
Oh hi there! 😄
|
||||
|
||||
To expedite issue processing please search open and closed issues before submitting a new one.
|
||||
Existing issues often contain information about workarounds, resolution, or progress updates.
|
||||
|
||||
🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅-->
|
||||
|
||||
|
||||
# 🐞 bug report
|
||||
|
||||
### Affected Package
|
||||
<!-- Can you pin-point one or more @angular/* packages as the source of the bug? -->
|
||||
<!-- ✍️edit: --> The issue is caused by package @angular/....
|
||||
|
||||
|
||||
### Is this a regression?
|
||||
|
||||
<!-- Did this behavior use to work in the previous version? -->
|
||||
<!-- ✍️--> Yes, the previous version in which this bug was not present was: ....
|
||||
|
||||
|
||||
### Description
|
||||
|
||||
<!-- ✍️--> A clear and concise description of the problem...
|
||||
|
||||
|
||||
## 🔬 Minimal Reproduction
|
||||
<!--
|
||||
Please create and share minimal reproduction of the issue starting with this template: https://stackblitz.com/fork/angular-ivy
|
||||
-->
|
||||
<!-- ✍️--> https://stackblitz.com/...
|
||||
|
||||
<!--
|
||||
If StackBlitz is not suitable for reproduction of your issue, please create a minimal GitHub repository with the reproduction of the issue.
|
||||
A good way to make a minimal reproduction is to create a new app via `ng new repro-app` and add the minimum possible code to show the problem.
|
||||
Share the link to the repo below along with step-by-step instructions to reproduce the problem, as well as expected and actual behavior.
|
||||
|
||||
Issues that don't have enough info and can't be reproduced will be closed.
|
||||
|
||||
You can read more about issue submission guidelines here: https://github.com/angular/angular/blob/master/CONTRIBUTING.md#-submitting-an-issue
|
||||
-->
|
||||
|
||||
## 🔥 Exception or Error
|
||||
<pre><code>
|
||||
<!-- If the issue is accompanied by an exception or an error, please share it below: -->
|
||||
<!-- ✍️-->
|
||||
|
||||
</code></pre>
|
||||
|
||||
|
||||
## 🌍 Your Environment
|
||||
|
||||
**Angular Version:**
|
||||
<pre><code>
|
||||
<!-- run `ng version` and paste output below -->
|
||||
<!-- ✍️-->
|
||||
|
||||
</code></pre>
|
||||
|
||||
**Anything else relevant?**
|
||||
<!-- ✍️Is this a browser specific issue? If so, please specify the browser and version. -->
|
||||
|
||||
<!-- ✍️Do any of these matter: operating system, IDE, package manager, HTTP server, ...? If so, please mention it below. -->
|
32
.github/ISSUE_TEMPLATE/2-feature-request.md
vendored
32
.github/ISSUE_TEMPLATE/2-feature-request.md
vendored
@ -1,32 +0,0 @@
|
||||
---
|
||||
name: "\U0001F680Feature request"
|
||||
about: Suggest a feature for Angular Framework
|
||||
|
||||
---
|
||||
<!--🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅
|
||||
|
||||
Oh hi there! 😄
|
||||
|
||||
To expedite issue processing please search open and closed issues before submitting a new one.
|
||||
Existing issues often contain information about workarounds, resolution, or progress updates.
|
||||
|
||||
🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅-->
|
||||
|
||||
|
||||
# 🚀 feature request
|
||||
|
||||
### Relevant Package
|
||||
<!-- Can you pin-point one or more @angular/* packages the are relevant for this feature request? -->
|
||||
<!-- ✍️edit: --> This feature request is for @angular/....
|
||||
|
||||
|
||||
### Description
|
||||
<!-- ✍️--> A clear and concise description of the problem or missing capability...
|
||||
|
||||
|
||||
### Describe the solution you'd like
|
||||
<!-- ✍️--> If you have a solution in mind, please describe it.
|
||||
|
||||
|
||||
### Describe alternatives you've considered
|
||||
<!-- ✍️--> Have you considered any alternative solutions or workarounds?
|
55
.github/ISSUE_TEMPLATE/3-docs-bug.md
vendored
55
.github/ISSUE_TEMPLATE/3-docs-bug.md
vendored
@ -1,55 +0,0 @@
|
||||
---
|
||||
name: "📚 Docs or angular.io issue report"
|
||||
about: Report an issue in Angular's documentation or angular.io application
|
||||
|
||||
---
|
||||
<!--🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅
|
||||
|
||||
Oh hi there! 😄
|
||||
|
||||
To expedite issue processing please search open and closed issues before submitting a new one.
|
||||
Existing issues often contain information about workarounds, resolution, or progress updates.
|
||||
|
||||
🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅-->
|
||||
|
||||
# 📚 Docs or angular.io bug report
|
||||
|
||||
### Description
|
||||
|
||||
<!-- ✍️edit:--> A clear and concise description of the problem...
|
||||
|
||||
|
||||
## 🔬 Minimal Reproduction
|
||||
|
||||
### What's the affected URL?**
|
||||
<!-- ✍️edit:--> https://angular.io/...
|
||||
|
||||
### Reproduction Steps**
|
||||
<!-- If applicable please list the steps to take to reproduce the issue -->
|
||||
<!-- ✍️edit:-->
|
||||
|
||||
### Expected vs Actual Behavior**
|
||||
<!-- If applicable please describe the difference between the expected and actual behavior after following the repro steps. -->
|
||||
<!-- ✍️edit:-->
|
||||
|
||||
|
||||
## 📷Screenshot
|
||||
<!-- Often a screenshot can help to capture the issue better than a long description. -->
|
||||
<!-- ✍️upload a screenshot:-->
|
||||
|
||||
|
||||
## 🔥 Exception or Error
|
||||
<pre><code>
|
||||
<!-- If the issue is accompanied by an exception or an error, please share it below: -->
|
||||
<!-- ✍️-->
|
||||
|
||||
</code></pre>
|
||||
|
||||
|
||||
## 🌍 Your Environment
|
||||
|
||||
### Browser info
|
||||
<!-- ✍️Is this a browser specific issue? If so, please specify the device, browser, and version. -->
|
||||
|
||||
### Anything else relevant?
|
||||
<!-- ✍️Please provide additional info if necessary. -->
|
@ -1,11 +0,0 @@
|
||||
---
|
||||
name: ⚠️ Security issue disclosure
|
||||
about: Report a security issue in Angular Framework, Material, or CLI
|
||||
|
||||
---
|
||||
|
||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
||||
|
||||
Please read https://angular.io/guide/security#report-issues on how to disclose security related issues.
|
||||
|
||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
16
.github/ISSUE_TEMPLATE/5-support-request.md
vendored
16
.github/ISSUE_TEMPLATE/5-support-request.md
vendored
@ -1,16 +0,0 @@
|
||||
---
|
||||
name: "❓Support request"
|
||||
about: Questions and requests for support
|
||||
|
||||
---
|
||||
|
||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
||||
|
||||
Please do not file questions or support requests on the GitHub issues tracker.
|
||||
|
||||
You can get your questions answered using other communication channels. Please see:
|
||||
https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
|
||||
|
||||
Thank you!
|
||||
|
||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
13
.github/ISSUE_TEMPLATE/6-angular-cli.md
vendored
13
.github/ISSUE_TEMPLATE/6-angular-cli.md
vendored
@ -1,13 +0,0 @@
|
||||
---
|
||||
name: "\U0001F6E0️Angular CLI"
|
||||
about: Issues and feature requests for Angular CLI
|
||||
|
||||
---
|
||||
|
||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
||||
|
||||
Please file any Angular CLI issues at: https://github.com/angular/angular-cli/issues/new
|
||||
|
||||
For the time being, we keep Angular CLI issues in a separate repository.
|
||||
|
||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
13
.github/ISSUE_TEMPLATE/7-angular-components.md
vendored
13
.github/ISSUE_TEMPLATE/7-angular-components.md
vendored
@ -1,13 +0,0 @@
|
||||
---
|
||||
name: "\U0001F48EAngular Components"
|
||||
about: Issues and feature requests for Angular Components
|
||||
|
||||
---
|
||||
|
||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
||||
|
||||
Please file any Angular Components issues at: https://github.com/angular/components/issues/new
|
||||
|
||||
For the time being, we keep Angular Components issues in a separate repository.
|
||||
|
||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
22
.github/ISSUE_TEMPLATE/8-translate-docs.md
vendored
Normal file
22
.github/ISSUE_TEMPLATE/8-translate-docs.md
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
---
|
||||
name: "📚Traducir doc al español"
|
||||
about: Solicitud para traducir ciertos docs al español
|
||||
|
||||
---
|
||||
|
||||
📚Traducir: <!-- ✍️ editar: --> creating-libraries.md
|
||||
|
||||
<!--🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅
|
||||
|
||||
Traducción de la documentación oficial de Angular a español
|
||||
|
||||
🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅-->
|
||||
|
||||
|
||||
## Nombre del archivo:
|
||||
<!-- ✍️ editar: --> creating-libraries.md
|
||||
|
||||
|
||||
## Ruta donde se encuentra el archivo dentro del proyecto de Angular
|
||||
|
||||
<!-- ✍️ editar: --> https://github.com/angular-hispano/angular/blob/master/aio/content/guide/creating-libraries.md
|
62
.github/PULL_REQUEST_TEMPLATE.md
vendored
62
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,43 +1,35 @@
|
||||
## PR Checklist
|
||||
Please check if your PR fulfills the following requirements:
|
||||
## Lista de Verificación del PR
|
||||
Comprueba si tu PR cumple los siguientes requisitos:
|
||||
|
||||
- [ ] The commit message follows our guidelines: https://github.com/angular/angular/blob/master/CONTRIBUTING.md#commit
|
||||
- [ ] Tests for the changes have been added (for bug fixes / features)
|
||||
- [ ] Docs have been added / updated (for bug fixes / features)
|
||||
- [ ] El mensaje de commit esta conforme con [nuestras reglas](https://github.com/angular-hispano/angular/blob/master/CONTRIBUTING.md#-formato-para-el-mensaje-de-los-commits)
|
||||
- [ ] Probe los cambios que agregué (arreglo de bugs / funcionalidades)
|
||||
- [ ] Revisé previamente las traducciones o cambios de contenido
|
||||
- [ ] Consulté el [diccionario de términos](https://github.com/angular-hispano/angular/blob/master/aio/diccionario-de-términos.md) en español
|
||||
- [ ] He creado dos archivos con la extensión correspondiente(.en.md para el archivo en inglés y .md para el Archivo en español)
|
||||
- [ ] He enlazado el commit con el issue correspondiente <!-- ejemplo Fixes #X -->
|
||||
|
||||
|
||||
## PR Type
|
||||
What kind of change does this PR introduce?
|
||||
## Tipo de PR
|
||||
¿Qué tipo de cambio introduce este PR?
|
||||
|
||||
<!-- Please check the one that applies to this PR using "x". -->
|
||||
<!-- Marca con una "x" las opciones que aplican. -->
|
||||
|
||||
- [ ] Bugfix
|
||||
- [ ] Feature
|
||||
- [ ] Code style update (formatting, local variables)
|
||||
- [ ] Refactoring (no functional changes, no api changes)
|
||||
- [ ] Build related changes
|
||||
- [ ] CI related changes
|
||||
- [ ] Documentation content changes
|
||||
- [ ] angular.io application / infrastructure changes
|
||||
- [ ] Other... Please describe:
|
||||
- [ ] Funcionalidad
|
||||
- [ ] Actualización de el estilo del código (formato, variables locales)
|
||||
- [ ] Refactorización (no cambios en la funcionalidad, no cambios en el api)
|
||||
- [ ] Cambios relacionados al build
|
||||
- [ ] Cambios relacionados al CI (Integración continua)
|
||||
- [ ] Cambios en el contenido de la documentación
|
||||
- [ ] Cambios en la aplicación / infraestructura de angular.io
|
||||
- [ ] Otro... Por favor describe la:
|
||||
|
||||
## ¿Cuál es el comportamiento actual?
|
||||
<!-- Describe el comportamiento actual que está modificando o vincule a un problema relevante.
|
||||
-->
|
||||
|
||||
|
||||
## What is the current behavior?
|
||||
<!-- Please describe the current behavior that you are modifying, or link to a relevant issue. -->
|
||||
|
||||
Issue Number: N/A
|
||||
|
||||
|
||||
## What is the new behavior?
|
||||
|
||||
|
||||
## Does this PR introduce a breaking change?
|
||||
|
||||
- [ ] Yes
|
||||
- [ ] No
|
||||
|
||||
|
||||
<!-- If this PR contains a breaking change, please describe the impact and migration path for existing applications below. -->
|
||||
|
||||
|
||||
## Other information
|
||||
## ¿Cuál es el nuevo comportamiento?
|
||||
<!--
|
||||
Ejemplo: Archivo en inglés traducido al español
|
||||
-->
|
||||
|
@ -6,7 +6,7 @@ import {CommitMessageConfig} from '../dev-infra/commit-message/config';
|
||||
export const commitMessage: CommitMessageConfig = {
|
||||
maxLineLength: 120,
|
||||
minBodyLength: 20,
|
||||
minBodyLengthTypeExcludes: ['docs'],
|
||||
minBodyLengthTypeExcludes: ['docs', 'upstream'],
|
||||
types: [
|
||||
'build',
|
||||
'ci',
|
||||
@ -18,6 +18,7 @@ export const commitMessage: CommitMessageConfig = {
|
||||
'release',
|
||||
'style',
|
||||
'test',
|
||||
'upstream',
|
||||
],
|
||||
scopes: [
|
||||
'animations',
|
||||
|
@ -1,12 +1,72 @@
|
||||
# Contributor Code of Conduct
|
||||
## Version 0.3b-angular
|
||||
# Código de Conducta
|
||||
|
||||
As contributors and maintainers of the Angular project, we pledge to respect everyone who contributes by posting issues, updating documentation, submitting pull requests, providing feedback in comments, and any other activities.
|
||||
## 1. Propósito
|
||||
|
||||
Communication through any of Angular's channels (GitHub, Gitter, IRC, mailing lists, Google+, Twitter, etc.) must be constructive and never resort to personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
|
||||
“Prometemos brindar cortesía y respeto a cualquier persona involucrada en esta comunidad, sin importar el género con el que se identifique, su orientación sexual, limitación física, edad, raza, etnia, religión o nivel de conocimiento. Esperamos que cualquiera que desee contribuir en este proyecto brinde el mismo comportamiento”
|
||||
|
||||
We promise to extend courtesy and respect to everyone involved in this project regardless of gender, gender identity, sexual orientation, disability, age, race, ethnicity, religion, or level of experience. We expect anyone contributing to the Angular project to do the same.
|
||||
Bajo ese principio queremos enfocar esta comunidad, una comunidad de respeto por el otro, donde cualquiera que sienta pasión por Angular y desee involucrarse con cualquier tipo de actividad deberá ayudar a mantener una atmósfera de cortesía por el otro, respetando los pensamientos, acciones, ideales y propuestas del otro.
|
||||
|
||||
If any member of the community violates this code of conduct, the maintainers of the Angular project may take action, removing issues, comments, and PRs or blocking accounts as deemed appropriate.
|
||||
## 2. Comportamiento esperado
|
||||
|
||||
If you are subject to or witness unacceptable behavior, or have any other concerns, please email us at [conduct@angular.io](mailto:conduct@angular.io).
|
||||
- Evitar usar expresiones o gestos insultantes, humillantes o intimidatorios para referirnos a otros.
|
||||
- Ejercita la consideración y el respeto en tus comunicaciones y acciones.
|
||||
- Absténte de adoptar una conducta y un lenguaje degradantes, discriminatorios, abusivos o acosadores.
|
||||
- Evitar comportamientos que agredan las expresiones de identidad, género, creencias religiosas, acciones que lastimen o los aíslen a otros.
|
||||
- Evitar comentarios sobre ideas políticas.
|
||||
- No se toleran conductas físicas y actitudes dirigidas al descrédito personal, físico o emocional de cualquier persona.
|
||||
- No se toleran chistes y comentarios excluyentes, sexistas y racistas.
|
||||
- Se rechaza actitudes de hostigamiento.
|
||||
- Se rechaza el acoso: este se entiende como cualquier tipo de comentario verbal que refuerce discriminación por género, identidad y expresión de género, orientación sexual, discapacidad, apariencia física, tamaño corporal, raza, edad o religión en contextos laborales o sociales.
|
||||
- No se tolera el contacto físico y/o la atención sexual no deseada.
|
||||
- Promover la igualdad de oportunidades de formación, educación, intercambio y retroalimentación antes, durante y después de los eventos.
|
||||
- Intenta colaborar en lugar de generar conflicto.
|
||||
- Sé consciente de tu entorno y de tus compañeros participantes. Alerta a líderes de la comunidad si notas una situación peligrosa, alguien en apuros, o violaciones de este Código de Conducta, incluso si parecen intrascendentes.
|
||||
|
||||
## 3. Comportamiento inaceptable
|
||||
Comportamientos inaceptables incluyen: intimidación, acoso, abuso, discriminación, comunicación despectiva o degradante o acciones por cualquier participante en nuestra comunidad ya sea virtual, o en las comunicaciones uno-a-uno que se realizan en el contexto de la comunidad. Por favor ser respetuoso con todos.
|
||||
|
||||
El acoso incluye: comentarios nocivos o perjudiciales, verbales o escritos relacionados con el género, la orientación sexual, raza, religión, discapacidad; uso inadecuado de desnudos y / o imágenes sexuales en espacios públicos (incluyendo la presentación diapositivas); intimidación deliberada, acecho o seguimiento; fotografías o grabaciones acosadoras; interrupción sostenida de charlas y otros eventos; contacto físico inapropiado, y atención sexual no deseada.
|
||||
|
||||
## 4. Consecuencias de comportamiento inaceptable
|
||||
Se espera que personas a quienes se les solicite que detengan su comportamiento inaceptable lo hagan de manera inmediata esto será válido para cualquier miembro de la comunidad.
|
||||
|
||||
En caso de presentarse una violación al código de conducta de manera repetida se tendrá cero tolerancia a este comportamiento por parte de los organizadores.
|
||||
|
||||
Si un miembro de la comunidad participa en una conducta inaceptable, los organizadores pueden tomar cualquier acción que consideren apropiada, hasta e incluyendo una prohibición temporal o expulsión permanente de la comunidad, sin previo aviso.
|
||||
|
||||
Priorizamos la seguridad de las personas marginadas sobre la comodidad de las personas privilegiadas. Nos reservamos el derecho de no actuar sobre las quejas relacionadas con:
|
||||
|
||||
- El "racismo inverso", "sexismo inverso" y "cisfobia".
|
||||
- Comunicación razonable de límites, como "déjame en paz", "vete" o "no estoy discutiendo esto contigo".
|
||||
- Al comunicarse en un "tono", no se encuentra agradable.
|
||||
- Identificando comportamientos o suposiciones racistas, sexistas, cissexistas u opresivas.
|
||||
|
||||
## 5. ¿Qué hacer si se incumple el código de conducta?
|
||||
Si eres víctima o testigo de una conducta inaceptable, o tienes cualquier inquietud, por favor comunícate con el equipo organizador lo antes posible:
|
||||
|
||||
- Mensaje directo: Michael Prentice (@splaktar)
|
||||
- Mensaje directo: Jorge Cano (@jorgeucano)
|
||||
- Mensaje directo: Andrés Villanueva (@villanuevand)
|
||||
- Email: [soporte@angular.lat](mailto:soporte@angular.lat)
|
||||
|
||||
### ¿Qué pasa después?
|
||||
- Una vez haya sido notificada el no cumplimiento de la norma, el equipo de liderazgo se reunirán y analizarán el caso.
|
||||
- Los incidentes presentados se manejarán con discreción.
|
||||
- Los organizadores se comunicarán con la persona que incumplió la norma y tomarán las medidas respectivas.
|
||||
- Se realizará un acompañamiento a la persona agredida y se apoyará.
|
||||
- Si el incidente se hace público, Angular Hispano no se hace responsable de los perjuicios que esto pueda ocasionar en el agresor o el agredido.
|
||||
|
||||
## 6. Alcance
|
||||
Esperamos que todos los participantes de la comunidad (organizadores, voluntarios, contribuyentes pagados o de otro modo; patrocinadores; y otros invitados) se atengan a este Código de Conducta en todos los espacios virtuales y presenciales, así como en todas las comunicaciones de uno-a-uno pertinentes la comunidad.
|
||||
|
||||
### Colaboradores
|
||||
|
||||
- Alejandra Giraldo
|
||||
- Vanessa Marely
|
||||
- Mariano Alvarez
|
||||
- Andrés Villanueva
|
||||
- Michael Prentice
|
||||
- javascript&friends
|
||||
- Angular
|
||||
- She Codes Angular
|
||||
- Colombia dev
|
359
CONTRIBUTING.en.md
Normal file
359
CONTRIBUTING.en.md
Normal file
@ -0,0 +1,359 @@
|
||||
# Contributing to Angular
|
||||
|
||||
We would love for you to contribute to Angular and help make it even better than it is today!
|
||||
As a contributor, here are the guidelines we would like you to follow:
|
||||
|
||||
- [Code of Conduct](#coc)
|
||||
- [Question or Problem?](#question)
|
||||
- [Issues and Bugs](#issue)
|
||||
- [Feature Requests](#feature)
|
||||
- [Submission Guidelines](#submit)
|
||||
- [Coding Rules](#rules)
|
||||
- [Commit Message Guidelines](#commit)
|
||||
- [Signing the CLA](#cla)
|
||||
|
||||
|
||||
## <a name="coc"></a> Code of Conduct
|
||||
|
||||
Help us keep Angular open and inclusive.
|
||||
Please read and follow our [Code of Conduct][coc].
|
||||
|
||||
|
||||
## <a name="question"></a> Got a Question or Problem?
|
||||
|
||||
Do not open issues for general support questions as we want to keep GitHub issues for bug reports and feature requests.
|
||||
Instead, we recommend using [Stack Overflow](https://stackoverflow.com/questions/tagged/angular) to ask support-related questions. When creating a new question on Stack Overflow, make sure to add the `angular` tag.
|
||||
|
||||
Stack Overflow is a much better place to ask questions since:
|
||||
|
||||
- there are thousands of people willing to help on Stack Overflow
|
||||
- questions and answers stay available for public viewing so your question/answer might help someone else
|
||||
- Stack Overflow's voting system assures that the best answers are prominently visible.
|
||||
|
||||
To save your and our time, we will systematically close all issues that are requests for general support and redirect people to Stack Overflow.
|
||||
|
||||
If you would like to chat about the question in real-time, you can reach out via [our gitter channel][gitter].
|
||||
|
||||
|
||||
## <a name="issue"></a> Found a Bug?
|
||||
|
||||
If you find a bug in the source code, you can help us by [submitting an issue](#submit-issue) to our [GitHub Repository][github].
|
||||
Even better, you can [submit a Pull Request](#submit-pr) with a fix.
|
||||
|
||||
|
||||
## <a name="feature"></a> Missing a Feature?
|
||||
You can *request* a new feature by [submitting an issue](#submit-issue) to our GitHub Repository.
|
||||
If you would like to *implement* a new feature, please consider the size of the change in order to determine the right steps to proceed:
|
||||
|
||||
* For a **Major Feature**, first open an issue and outline your proposal so that it can be discussed.
|
||||
This process allows us to better coordinate our efforts, prevent duplication of work, and help you to craft the change so that it is successfully accepted into the project.
|
||||
|
||||
**Note**: Adding a new topic to the documentation, or significantly re-writing a topic, counts as a major feature.
|
||||
|
||||
* **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr).
|
||||
|
||||
|
||||
## <a name="submit"></a> Submission Guidelines
|
||||
|
||||
|
||||
### <a name="submit-issue"></a> Submitting an Issue
|
||||
|
||||
Before you submit an issue, please search the issue tracker, maybe an issue for your problem already exists and the discussion might inform you of workarounds readily available.
|
||||
|
||||
We want to fix all the issues as soon as possible, but before fixing a bug we need to reproduce and confirm it.
|
||||
In order to reproduce bugs, we require that you provide a minimal reproduction.
|
||||
Having a minimal reproducible scenario gives us a wealth of important information without going back and forth to you with additional questions.
|
||||
|
||||
A minimal reproduction allows us to quickly confirm a bug (or point out a coding problem) as well as confirm that we are fixing the right problem.
|
||||
|
||||
We require a minimal reproduction to save maintainers' time and ultimately be able to fix more bugs.
|
||||
Often, developers find coding problems themselves while preparing a minimal reproduction.
|
||||
We understand that sometimes it might be hard to extract essential bits of code from a larger codebase but we really need to isolate the problem before we can fix it.
|
||||
|
||||
Unfortunately, we are not able to investigate / fix bugs without a minimal reproduction, so if we don't hear back from you, we are going to close an issue that doesn't have enough info to be reproduced.
|
||||
|
||||
You can file new issues by selecting from our [new issue templates](https://github.com/angular/angular/issues/new/choose) and filling out the issue template.
|
||||
|
||||
|
||||
### <a name="submit-pr"></a> Submitting a Pull Request (PR)
|
||||
|
||||
Before you submit your Pull Request (PR) consider the following guidelines:
|
||||
|
||||
1. Search [GitHub](https://github.com/angular/angular/pulls) for an open or closed PR that relates to your submission.
|
||||
You don't want to duplicate existing efforts.
|
||||
|
||||
2. Be sure that an issue describes the problem you're fixing, or documents the design for the feature you'd like to add.
|
||||
Discussing the design upfront helps to ensure that we're ready to accept your work.
|
||||
|
||||
3. Please sign our [Contributor License Agreement (CLA)](#cla) before sending PRs.
|
||||
We cannot accept code without a signed CLA.
|
||||
Make sure you author all contributed Git commits with email address associated with your CLA signature.
|
||||
|
||||
4. Fork the angular/angular repo.
|
||||
|
||||
5. Make your changes in a new git branch:
|
||||
|
||||
```shell
|
||||
git checkout -b my-fix-branch master
|
||||
```
|
||||
|
||||
6. Create your patch, **including appropriate test cases**.
|
||||
|
||||
7. Follow our [Coding Rules](#rules).
|
||||
|
||||
8. Run the full Angular test suite, as described in the [developer documentation][dev-doc], and ensure that all tests pass.
|
||||
|
||||
9. Commit your changes using a descriptive commit message that follows our [commit message conventions](#commit).
|
||||
Adherence to these conventions is necessary because release notes are automatically generated from these messages.
|
||||
|
||||
```shell
|
||||
git commit -a
|
||||
```
|
||||
Note: the optional commit `-a` command line option will automatically "add" and "rm" edited files.
|
||||
|
||||
10. Push your branch to GitHub:
|
||||
|
||||
```shell
|
||||
git push origin my-fix-branch
|
||||
```
|
||||
|
||||
11. In GitHub, send a pull request to `angular:master`.
|
||||
|
||||
If we ask for changes via code reviews then:
|
||||
|
||||
* Make the required updates.
|
||||
* Re-run the Angular test suites to ensure tests are still passing.
|
||||
* Rebase your branch and force push to your GitHub repository (this will update your Pull Request):
|
||||
|
||||
```shell
|
||||
git rebase master -i
|
||||
git push -f
|
||||
```
|
||||
|
||||
That's it! Thank you for your contribution!
|
||||
|
||||
|
||||
#### After your pull request is merged
|
||||
|
||||
After your pull request is merged, you can safely delete your branch and pull the changes from the main (upstream) repository:
|
||||
|
||||
* Delete the remote branch on GitHub either through the GitHub web UI or your local shell as follows:
|
||||
|
||||
```shell
|
||||
git push origin --delete my-fix-branch
|
||||
```
|
||||
|
||||
* Check out the master branch:
|
||||
|
||||
```shell
|
||||
git checkout master -f
|
||||
```
|
||||
|
||||
* Delete the local branch:
|
||||
|
||||
```shell
|
||||
git branch -D my-fix-branch
|
||||
```
|
||||
|
||||
* Update your master with the latest upstream version:
|
||||
|
||||
```shell
|
||||
git pull --ff upstream master
|
||||
```
|
||||
|
||||
|
||||
## <a name="rules"></a> Coding Rules
|
||||
To ensure consistency throughout the source code, keep these rules in mind as you are working:
|
||||
|
||||
* All features or bug fixes **must be tested** by one or more specs (unit-tests).
|
||||
* All public API methods **must be documented**.
|
||||
* We follow [Google's JavaScript Style Guide][js-style-guide], but wrap all code at **100 characters**.
|
||||
|
||||
An automated formatter is available, see [DEVELOPER.md](docs/DEVELOPER.md#clang-format).
|
||||
|
||||
|
||||
## <a name="commit"></a> Commit Message Format
|
||||
|
||||
*This specification is inspired and supersedes the [AngularJS commit message format][commit-message-format].*
|
||||
|
||||
We have very precise rules over how our Git commit messages must be formatted.
|
||||
This format leads to **easier to read commit history**.
|
||||
|
||||
Each commit message consists of a **header**, a **body**, and a **footer**.
|
||||
|
||||
|
||||
```
|
||||
<header>
|
||||
<BLANK LINE>
|
||||
<body>
|
||||
<BLANK LINE>
|
||||
<footer>
|
||||
```
|
||||
|
||||
The `header` is mandatory and must conform to the [Commit Message Header](#commit-header) format.
|
||||
|
||||
The `body` is mandatory for all commits except for those of scope "docs".
|
||||
When the body is required it must be at least 20 characters long.
|
||||
|
||||
The `footer` is optional.
|
||||
|
||||
Any line of the commit message cannot be longer than 100 characters.
|
||||
|
||||
|
||||
#### <a href="commit-header"></a>Commit Message Header
|
||||
|
||||
```
|
||||
<type>(<scope>): <short summary>
|
||||
│ │ │
|
||||
│ │ └─⫸ Summary in present tense. Not capitalized. No period at the end.
|
||||
│ │
|
||||
│ └─⫸ Commit Scope: animations|bazel|benchpress|common|compiler|compiler-cli|core|
|
||||
│ elements|forms|http|language-service|localize|platform-browser|
|
||||
│ platform-browser-dynamic|platform-server|platform-webworker|
|
||||
│ platform-webworker-dynamic|router|service-worker|upgrade|zone.js|
|
||||
│ packaging|changelog|dev-infra|docs-infra|migrations|ngcc|ve
|
||||
│
|
||||
└─⫸ Commit Type: build|ci|docs|feat|fix|perf|refactor|style|test
|
||||
```
|
||||
|
||||
The `<type>` and `<summary>` fields are mandatory, the `(<scope>)` field is optional.
|
||||
|
||||
|
||||
##### Type
|
||||
|
||||
Must be one of the following:
|
||||
|
||||
* **build**: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
|
||||
* **ci**: Changes to our CI configuration files and scripts (example scopes: Circle, BrowserStack, SauceLabs)
|
||||
* **docs**: Documentation only changes
|
||||
* **feat**: A new feature
|
||||
* **fix**: A bug fix
|
||||
* **perf**: A code change that improves performance
|
||||
* **refactor**: A code change that neither fixes a bug nor adds a feature
|
||||
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
|
||||
* **test**: Adding missing tests or correcting existing tests
|
||||
|
||||
|
||||
##### Scope
|
||||
The scope should be the name of the npm package affected (as perceived by the person reading the changelog generated from commit messages).
|
||||
|
||||
The following is the list of supported scopes:
|
||||
|
||||
* `animations`
|
||||
* `bazel`
|
||||
* `benchpress`
|
||||
* `common`
|
||||
* `compiler`
|
||||
* `compiler-cli`
|
||||
* `core`
|
||||
* `elements`
|
||||
* `forms`
|
||||
* `http`
|
||||
* `language-service`
|
||||
* `localize`
|
||||
* `platform-browser`
|
||||
* `platform-browser-dynamic`
|
||||
* `platform-server`
|
||||
* `platform-webworker`
|
||||
* `platform-webworker-dynamic`
|
||||
* `router`
|
||||
* `service-worker`
|
||||
* `upgrade`
|
||||
* `zone.js`
|
||||
|
||||
There are currently a few exceptions to the "use package name" rule:
|
||||
|
||||
* `packaging`: used for changes that change the npm package layout in all of our packages, e.g. public path changes, package.json changes done to all packages, d.ts file/format changes, changes to bundles, etc.
|
||||
|
||||
* `changelog`: used for updating the release notes in CHANGELOG.md
|
||||
|
||||
* `dev-infra`: used for dev-infra related changes within the directories /scripts, /tools and /dev-infra
|
||||
|
||||
* `docs-infra`: used for docs-app (angular.io) related changes within the /aio directory of the repo
|
||||
|
||||
* `migrations`: used for changes to the `ng update` migrations.
|
||||
|
||||
* `ngcc`: used for changes to the [Angular Compatibility Compiler](./packages/compiler-cli/ngcc/README.md)
|
||||
|
||||
* `ve`: used for changes specific to ViewEngine (legacy compiler/renderer).
|
||||
|
||||
* none/empty string: useful for `style`, `test` and `refactor` changes that are done across all packages (e.g. `style: add missing semicolons`) and for docs changes that are not related to a specific package (e.g. `docs: fix typo in tutorial`).
|
||||
|
||||
|
||||
##### Summary
|
||||
|
||||
Use the summary field to provide a succinct description of the change:
|
||||
|
||||
* use the imperative, present tense: "change" not "changed" nor "changes"
|
||||
* don't capitalize the first letter
|
||||
* no dot (.) at the end
|
||||
|
||||
|
||||
#### Commit Message Body
|
||||
|
||||
Just as in the summary, use the imperative, present tense: "fix" not "fixed" nor "fixes".
|
||||
|
||||
Explain the motivation for the change in the commit message body. This commit message should explain _why_ you are making the change.
|
||||
You can include a comparison of the previous behavior with the new behavior in order to illustrate the impact of the change.
|
||||
|
||||
|
||||
#### Commit Message Footer
|
||||
|
||||
The footer can contain information about breaking changes and is also the place to reference GitHub issues, Jira tickets, and other PRs that this commit closes or is related to.
|
||||
|
||||
```
|
||||
BREAKING CHANGE: <breaking change summary>
|
||||
<BLANK LINE>
|
||||
<breaking change description + migration instructions>
|
||||
<BLANK LINE>
|
||||
<BLANK LINE>
|
||||
Fixes #<issue number>
|
||||
```
|
||||
|
||||
Breaking Change section should start with the phrase "BREAKING CHANGE: " followed by a summary of the breaking change, a blank line, and a detailed description of the breaking change that also includes migration instructions.
|
||||
|
||||
|
||||
### Revert commits
|
||||
|
||||
If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit.
|
||||
|
||||
The content of the commit message body should contain:
|
||||
|
||||
- information about the SHA of the commit being reverted in the following format: `This reverts commit <SHA>`,
|
||||
- a clear description of the reason for reverting the commit message.
|
||||
|
||||
|
||||
## <a name="cla"></a> Signing the CLA
|
||||
|
||||
Please sign our Contributor License Agreement (CLA) before sending pull requests. For any code
|
||||
changes to be accepted, the CLA must be signed. It's a quick process, we promise!
|
||||
|
||||
* For individuals, we have a [simple click-through form][individual-cla].
|
||||
* For corporations, we'll need you to
|
||||
[print, sign and one of scan+email, fax or mail the form][corporate-cla].
|
||||
|
||||
If you have more than one GitHub accounts, or multiple email addresses associated with a single GitHub account, you must sign the CLA using the primary email address of the GitHub account used to author Git commits and send pull requests.
|
||||
|
||||
The following documents can help you sort out issues with GitHub accounts and multiple email addresses:
|
||||
|
||||
* https://help.github.com/articles/setting-your-commit-email-address-in-git/
|
||||
* https://stackoverflow.com/questions/37245303/what-does-usera-committed-with-userb-13-days-ago-on-github-mean
|
||||
* https://help.github.com/articles/about-commit-email-addresses/
|
||||
* https://help.github.com/articles/blocking-command-line-pushes-that-expose-your-personal-email-address/
|
||||
|
||||
|
||||
|
||||
|
||||
[angular-group]: https://groups.google.com/forum/#!forum/angular
|
||||
[coc]: https://github.com/angular/code-of-conduct/blob/master/CODE_OF_CONDUCT.md
|
||||
[commit-message-format]: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#
|
||||
[corporate-cla]: http://code.google.com/legal/corporate-cla-v1.0.html
|
||||
[dev-doc]: https://github.com/angular/angular/blob/master/docs/DEVELOPER.md
|
||||
[github]: https://github.com/angular/angular
|
||||
[gitter]: https://gitter.im/angular/angular
|
||||
[individual-cla]: http://code.google.com/legal/individual-cla-v1.0.html
|
||||
[js-style-guide]: https://google.github.io/styleguide/jsguide.html
|
||||
[jsfiddle]: http://jsfiddle.net
|
||||
[plunker]: http://plnkr.co/edit
|
||||
[runnable]: http://runnable.com
|
||||
[stackoverflow]: http://stackoverflow.com/questions/tagged/angular
|
303
CONTRIBUTING.md
303
CONTRIBUTING.md
@ -1,243 +1,243 @@
|
||||
# Contributing to Angular
|
||||
# Contribuye a Angular
|
||||
|
||||
We would love for you to contribute to Angular and help make it even better than it is today!
|
||||
As a contributor, here are the guidelines we would like you to follow:
|
||||
¡Nos encantaría que contribuyeras a Angular y que ayudaras a hacerlo aún mejor de lo que es hoy!
|
||||
Como colaborador, estos son los lineamientos que nos gustaría que siguieras:
|
||||
|
||||
- [Code of Conduct](#coc)
|
||||
- [Question or Problem?](#question)
|
||||
- [Issues and Bugs](#issue)
|
||||
- [Feature Requests](#feature)
|
||||
- [Submission Guidelines](#submit)
|
||||
- [Coding Rules](#rules)
|
||||
- [Commit Message Guidelines](#commit)
|
||||
- [Signing the CLA](#cla)
|
||||
- [Código de conducta](#coc)
|
||||
- [¿Preguntas o problemas?](#question)
|
||||
- [_Issues_ y _bugs_](#issue)
|
||||
- [Solicitud de funcionalidades](#feature)
|
||||
- [Guía para la creación de issues y PRs](#submit)
|
||||
- [Reglas del código](#rules)
|
||||
- [Convención para el mensaje de los _commits_](#commit)
|
||||
- [Firma del Acuerdo de Licencia de Colaborador (CLA)](#cla)
|
||||
|
||||
|
||||
## <a name="coc"></a> Code of Conduct
|
||||
## <a name="coc"></a> Código de conducta
|
||||
|
||||
Help us keep Angular open and inclusive.
|
||||
Please read and follow our [Code of Conduct][coc].
|
||||
Ayúdanos a mantener Angular abierto e inclusivo.
|
||||
Por favor lee y sigue nuestro [Código de conducta][coc].
|
||||
|
||||
|
||||
## <a name="question"></a> Got a Question or Problem?
|
||||
## <a name="question"></a> ¿Tienes alguna pregunta o problema?
|
||||
|
||||
Do not open issues for general support questions as we want to keep GitHub issues for bug reports and feature requests.
|
||||
Instead, we recommend using [Stack Overflow](https://stackoverflow.com/questions/tagged/angular) to ask support-related questions. When creating a new question on Stack Overflow, make sure to add the `angular` tag.
|
||||
No abras *issues* para preguntas de soporte general ya que queremos mantener los *issues* de GitHub para reporte de *bugs* y solicitud de funcionalidades.
|
||||
En su lugar, recomendamos utilizar [Stack Overflow](https://stackoverflow.com/questions/tagged/angular) para hacer preguntas relacionadas con soporte. Al crear una nueva pregunta en Stack Overflow, asegúrate de agregar el etiqueta (tag) de `angular`.
|
||||
|
||||
Stack Overflow is a much better place to ask questions since:
|
||||
Stack Overflow es mucho mejor para hacer preguntas ya que:
|
||||
|
||||
- there are thousands of people willing to help on Stack Overflow
|
||||
- questions and answers stay available for public viewing so your question/answer might help someone else
|
||||
- Stack Overflow's voting system assures that the best answers are prominently visible.
|
||||
- Hay miles de personas dispuestas a ayudar en preguntas y respuestas de Stack Overflow
|
||||
que permanecen disponibles para el público, por lo que tu pregunta o respuesta podría ayudar a otra persona.
|
||||
- El sistema de votación de Stack Overflow asegura que las mejores respuestas sobresalgan y sean visibles.
|
||||
|
||||
To save your and our time, we will systematically close all issues that are requests for general support and redirect people to Stack Overflow.
|
||||
Para ahorrar tu tiempo y el nuestro, cerraremos sistemáticamente todos los *issues* que sean solicitudes de soporte general y redirigiremos a las personas a Stack Overflow.
|
||||
|
||||
If you would like to chat about the question in real-time, you can reach out via [our gitter channel][gitter].
|
||||
Si deseas chatear sobre alguna pregunta en tiempo real, puedes hacerlo a través de nuestro [canal de Gitter][gitter].
|
||||
|
||||
|
||||
## <a name="issue"></a> Found a Bug?
|
||||
## <a name="issue"></a> ¿Encontraste un Bug?
|
||||
|
||||
If you find a bug in the source code, you can help us by [submitting an issue](#submit-issue) to our [GitHub Repository][github].
|
||||
Even better, you can [submit a Pull Request](#submit-pr) with a fix.
|
||||
Si encontraste un error en el código fuente, puedes ayudarnos [creando un *issue*](#submit-issue) en nuestro [repositorio de GitHub][github].
|
||||
O incluso mejor, puedes [crear un *Pull Request*](#submit-pr) con la solución.
|
||||
|
||||
|
||||
## <a name="feature"></a> Missing a Feature?
|
||||
You can *request* a new feature by [submitting an issue](#submit-issue) to our GitHub Repository.
|
||||
If you would like to *implement* a new feature, please consider the size of the change in order to determine the right steps to proceed:
|
||||
## <a name="feature"></a> ¿Falta alguna funcionalidad?
|
||||
Puedes solicitar una nueva funcionalidad [creando un *issue*](#submit-issue) en nuestro repositorio de GitHub.
|
||||
Si deseas implementar una nueva funcionalidad, por favor considera el tamaño del cambio para determinar los pasos correctos para continuar:
|
||||
|
||||
* For a **Major Feature**, first open an issue and outline your proposal so that it can be discussed.
|
||||
This process allows us to better coordinate our efforts, prevent duplication of work, and help you to craft the change so that it is successfully accepted into the project.
|
||||
* Para un **cambio significativo**, primero abre un *issue* y describe tu propuesta para que pueda ser discutida.
|
||||
Este proceso nos permite coordinar mejor nuestros esfuerzos, evitar trabajo duplicado y ayudarte a diseñar el cambio para que sea aceptado con éxito en el proyecto.
|
||||
|
||||
**Note**: Adding a new topic to the documentation, or significantly re-writing a topic, counts as a major feature.
|
||||
**Nota**: Agregar un nuevo tema a la documentación o reescribir significativamente un tema, también cuenta como *cambio significativo*.
|
||||
|
||||
* **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr).
|
||||
* **Cambios pequeños** pueden ser elaborados y directamente [creados como un _pull request_](#submit-pr).
|
||||
|
||||
|
||||
## <a name="submit"></a> Submission Guidelines
|
||||
## <a name="submit"></a> Guía para la creación de issues y PRs
|
||||
|
||||
|
||||
### <a name="submit-issue"></a> Submitting an Issue
|
||||
### <a name="submit-issue"></a> Creación de _issues_
|
||||
|
||||
Before you submit an issue, please search the issue tracker, maybe an issue for your problem already exists and the discussion might inform you of workarounds readily available.
|
||||
Antes de crear un *issue*, por favor busca en el el *issue tracker*, quizá un *issue* para tu problema ya existe y la discusión puede informarte sobre soluciones alternativas disponibles.
|
||||
|
||||
We want to fix all the issues as soon as possible, but before fixing a bug we need to reproduce and confirm it.
|
||||
In order to reproduce bugs, we require that you provide a minimal reproduction.
|
||||
Having a minimal reproducible scenario gives us a wealth of important information without going back and forth to you with additional questions.
|
||||
Queremos solucionar todos los problemas lo antes posible, pero antes de corregir un bug necesitamos reproducirlo y confirmarlo.
|
||||
Para reproducir errores, requerimos que proporciones una reproducción mínima.
|
||||
Tener un escenario reproducible mínimo nos brinda una gran cantidad de información importante sin tener que ir y venir con preguntas adicionales.
|
||||
|
||||
A minimal reproduction allows us to quickly confirm a bug (or point out a coding problem) as well as confirm that we are fixing the right problem.
|
||||
Una reproducción mínima nos permite confirmar rápidamente un bug (o señalar un problema de código), así también confirmar que estamos solucionando el problema correcto.
|
||||
|
||||
We require a minimal reproduction to save maintainers' time and ultimately be able to fix more bugs.
|
||||
Often, developers find coding problems themselves while preparing a minimal reproduction.
|
||||
We understand that sometimes it might be hard to extract essential bits of code from a larger codebase but we really need to isolate the problem before we can fix it.
|
||||
Requerimos una reproducción mínima para ahorrar tiempo a los encargados del mantenimiento y en última instancia, poder corregir más bugs.
|
||||
A menudo los desarrolladores encuentran problemas de código mientras preparan una reproducción mínima.
|
||||
Entendemos que a veces puede ser difícil extraer porciones esenciales de código de un código más grande, pero realmente necesitamos aislar el problema antes de poder solucionarlo.
|
||||
|
||||
Unfortunately, we are not able to investigate / fix bugs without a minimal reproduction, so if we don't hear back from you, we are going to close an issue that doesn't have enough info to be reproduced.
|
||||
Desafortunadamente no podemos investigar/corregir errores sin una reproducción mínima, por lo que si no tenemos tu retroalimentación del bug, vamos a cerrar el *issue* ya que no tiene suficiente información para reproducirse.
|
||||
|
||||
You can file new issues by selecting from our [new issue templates](https://github.com/angular/angular/issues/new/choose) and filling out the issue template.
|
||||
Puedes presentar nuevos *issues* seleccionando nuestra [plantilla de _issues_](https://github.com/angular/angular/issues/new/choose) y complentando la plantilla.
|
||||
|
||||
|
||||
### <a name="submit-pr"></a> Submitting a Pull Request (PR)
|
||||
### <a name="submit-pr"></a> Creación de un Pull Requests (PR)
|
||||
|
||||
Before you submit your Pull Request (PR) consider the following guidelines:
|
||||
Antes de crear tu Pull Request (PR) considera los siguientes lineamientos:
|
||||
|
||||
1. Search [GitHub](https://github.com/angular/angular/pulls) for an open or closed PR that relates to your submission.
|
||||
You don't want to duplicate existing efforts.
|
||||
1. Busca en [GitHub](https://github.com/angular/angular/pulls) PRs que estén abiertos o cerrados y que estén relacionados con el que vas a crear.
|
||||
No deseas duplicar los esfuerzos existentes.
|
||||
|
||||
2. Be sure that an issue describes the problem you're fixing, or documents the design for the feature you'd like to add.
|
||||
Discussing the design upfront helps to ensure that we're ready to accept your work.
|
||||
2. Asegúrate de que el PR describa el problema que estás solucionando o que documente el diseño de la funcionalidad que deseas agregar.
|
||||
Discutir el diseño por adelantado ayuda a garantizar que estemos listos para aceptar tu trabajo.
|
||||
|
||||
3. Please sign our [Contributor License Agreement (CLA)](#cla) before sending PRs.
|
||||
We cannot accept code without a signed CLA.
|
||||
Make sure you author all contributed Git commits with email address associated with your CLA signature.
|
||||
3. Por favor firma nuestro [Acuerdo de Licencia de Colaborador (CLA)](#cla) antes de crear PRs.
|
||||
No podemos aceptar el código sin el Acuerdo de Licencia de Colaborador (CLA) firmado.
|
||||
Asegúrate de crear todas las contribuciones de Git con la dirección de correo electrónico asociada con tu firma del Acuerdo de Licencia de Colaborador (CLA).
|
||||
|
||||
4. Fork the angular/angular repo.
|
||||
4. Haz *fork* del repositorio angular/angular.
|
||||
|
||||
5. Make your changes in a new git branch:
|
||||
5. Haz tus cambios en una nueva rama de Git:
|
||||
|
||||
```shell
|
||||
git checkout -b my-fix-branch master
|
||||
```
|
||||
|
||||
6. Create your patch, **including appropriate test cases**.
|
||||
6. Crea tu correción, **incluyendo casos de prueba apropiados**.
|
||||
|
||||
7. Follow our [Coding Rules](#rules).
|
||||
7. Sigue nuestras [Reglas de código](#rules).
|
||||
|
||||
8. Run the full Angular test suite, as described in the [developer documentation][dev-doc], and ensure that all tests pass.
|
||||
8. Ejecuta todo el conjunto de pruebas de Angular, tal como está descrito en la [documentación del desarrollador][dev-doc], y asegúrate de que todas las pruebas pasen.
|
||||
|
||||
9. Commit your changes using a descriptive commit message that follows our [commit message conventions](#commit).
|
||||
Adherence to these conventions is necessary because release notes are automatically generated from these messages.
|
||||
9. Crea un commit de tus cambios utilizando un mensaje de commit descriptivo que siga nuestra [convención para el mensaje de los commits](#commit).
|
||||
Es necesario cumplir con estas convenciones porque las notas de las versiones se generan automáticamente a partir de estos mensajes.
|
||||
|
||||
```shell
|
||||
git commit -a
|
||||
```
|
||||
Note: the optional commit `-a` command line option will automatically "add" and "rm" edited files.
|
||||
Nota: la opción de la línea de comandos de Git `-a` automaticamente hará "add" y "rm" a los archivos editados.
|
||||
|
||||
10. Push your branch to GitHub:
|
||||
10. Haz push de tu rama a GitHub:
|
||||
|
||||
```shell
|
||||
git push origin my-fix-branch
|
||||
```
|
||||
|
||||
11. In GitHub, send a pull request to `angular:master`.
|
||||
11. En GitHub, crea un pull request a `angular:master`.
|
||||
|
||||
If we ask for changes via code reviews then:
|
||||
Si solicitamos cambios a través de revisiones de código, sigue las siguientes indicaciones:
|
||||
|
||||
* Make the required updates.
|
||||
* Re-run the Angular test suites to ensure tests are still passing.
|
||||
* Rebase your branch and force push to your GitHub repository (this will update your Pull Request):
|
||||
* Haz los cambios requeridos.
|
||||
* Ejecuta nuevamente el conjunto de pruebas de Angular para asegurar que todas las pruebas aún están pasando.
|
||||
* Haz rebase de tu rama a la rama master y haz push con la opción `-f` a tu repositorio de Github (esto actualizará tu Pull Request):
|
||||
|
||||
```shell
|
||||
git rebase master -i
|
||||
git push -f
|
||||
```
|
||||
|
||||
That's it! Thank you for your contribution!
|
||||
¡Es todo! ¡Muchas gracias por tu contribución!
|
||||
|
||||
|
||||
#### After your pull request is merged
|
||||
#### Después del merge de tu pull request
|
||||
|
||||
After your pull request is merged, you can safely delete your branch and pull the changes from the main (upstream) repository:
|
||||
Después de que se hizo merge de tu pull request, puedes eliminar de forma segura tu rama y hacer pull de los cambios del repositorio principal (upstream):
|
||||
|
||||
* Delete the remote branch on GitHub either through the GitHub web UI or your local shell as follows:
|
||||
* Elimina la rama remota en GitHub a través de la interfaz de usuario web de GitHub o en tu línea de comandos de la siguiente manera:
|
||||
|
||||
```shell
|
||||
git push origin --delete my-fix-branch
|
||||
```
|
||||
|
||||
* Check out the master branch:
|
||||
* Muévete a la rama master:
|
||||
|
||||
```shell
|
||||
git checkout master -f
|
||||
```
|
||||
|
||||
* Delete the local branch:
|
||||
* Elimina tu rama local:
|
||||
|
||||
```shell
|
||||
git branch -D my-fix-branch
|
||||
```
|
||||
|
||||
* Update your master with the latest upstream version:
|
||||
* Actualiza tu rama master con la última versión del fork (upstream):
|
||||
|
||||
```shell
|
||||
git pull --ff upstream master
|
||||
```
|
||||
|
||||
|
||||
## <a name="rules"></a> Coding Rules
|
||||
To ensure consistency throughout the source code, keep these rules in mind as you are working:
|
||||
## <a name="rules"></a> Reglas del código
|
||||
Para garantizar la coherencia en todo el código fuente, ten en cuenta estas reglas mientras trabajas:
|
||||
|
||||
* All features or bug fixes **must be tested** by one or more specs (unit-tests).
|
||||
* All public API methods **must be documented**.
|
||||
* We follow [Google's JavaScript Style Guide][js-style-guide], but wrap all code at **100 characters**.
|
||||
* Todas las funcionalidades o solución de bugs **deben ser probadas** por una o más pruebas (pruebas unitarias).
|
||||
* Todos los métodos públicos del API **deben ser documentados**.
|
||||
* Seguimos la [guía de estilo JavaScript de Google][js-style-guide], pero cada línea no debe exceder **100 caracteres**.
|
||||
|
||||
An automated formatter is available, see [DEVELOPER.md](docs/DEVELOPER.md#clang-format).
|
||||
Un formateador automatizado está disponible, revisar [DEVELOPER.md](docs/DEVELOPER.md#clang-format).
|
||||
|
||||
|
||||
## <a name="commit"></a> Commit Message Format
|
||||
## <a name="commit"></a> Formato para el mensaje de los commits
|
||||
|
||||
*This specification is inspired and supersedes the [AngularJS commit message format][commit-message-format].*
|
||||
*Esta especificación está inspirada y reemplaza el [Formato de mensaje de commits de AngularJS][commit-message-format].*
|
||||
|
||||
We have very precise rules over how our Git commit messages must be formatted.
|
||||
This format leads to **easier to read commit history**.
|
||||
Tenemos reglas muy precisas sobre cómo deben formatearse nuestros mensajes de los commits de Git.
|
||||
Este formato permite tener **un historial de commits más facil de leer**.
|
||||
|
||||
Each commit message consists of a **header**, a **body**, and a **footer**.
|
||||
Cada mensaje de un commit consta del **header**, el **body**, y el **footer**.
|
||||
|
||||
|
||||
```
|
||||
<header>
|
||||
<BLANK LINE>
|
||||
<LINEA VACIA>
|
||||
<body>
|
||||
<BLANK LINE>
|
||||
<LINEA VACIA>
|
||||
<footer>
|
||||
```
|
||||
|
||||
The `header` is mandatory and must conform to the [Commit Message Header](#commit-header) format.
|
||||
El `header` es obligatorio y debe ajustarse al formato del [mensaje del header del commit](#commit-header).
|
||||
|
||||
The `body` is mandatory for all commits except for those of scope "docs".
|
||||
When the body is required it must be at least 20 characters long.
|
||||
El `body` es obligatorio para todos los commits excepto los que tenga scope "docs".
|
||||
Cuando el body es requerido debe tener al menos 20 caracteres.
|
||||
|
||||
The `footer` is optional.
|
||||
El `footer` es opcional.
|
||||
|
||||
Any line of the commit message cannot be longer than 100 characters.
|
||||
Cualquier línea del mensaje del commit no puede tener más de 100 caracteres.
|
||||
|
||||
|
||||
#### <a href="commit-header"></a>Commit Message Header
|
||||
#### <a href="commit-header"></a>Mensaje del header del commit
|
||||
|
||||
```
|
||||
<type>(<scope>): <short summary>
|
||||
<tipo>(<alcance>): <resumen>
|
||||
│ │ │
|
||||
│ │ └─⫸ Summary in present tense. Not capitalized. No period at the end.
|
||||
│ │ └─⫸ Resumen corto escrito en modo imperativo, tiempo presente. Sin mayúsculas. Sin punto final.
|
||||
│ │
|
||||
│ └─⫸ Commit Scope: animations|bazel|benchpress|common|compiler|compiler-cli|core|
|
||||
│ └─⫸ Alcance del commit: animations|bazel|benchpress|common|compiler|compiler-cli|core|
|
||||
│ elements|forms|http|language-service|localize|platform-browser|
|
||||
│ platform-browser-dynamic|platform-server|platform-webworker|
|
||||
│ platform-webworker-dynamic|router|service-worker|upgrade|zone.js|
|
||||
│ packaging|changelog|dev-infra|docs-infra|migrations|ngcc|ve
|
||||
│
|
||||
└─⫸ Commit Type: build|ci|docs|feat|fix|perf|refactor|style|test
|
||||
└─⫸ Tipo de commit: build|ci|docs|feat|fix|perf|refactor|style|test
|
||||
```
|
||||
|
||||
The `<type>` and `<summary>` fields are mandatory, the `(<scope>)` field is optional.
|
||||
El `<tipo>` y `<resumen>` son obligatorios, el `(<alcance>)` es opcional.
|
||||
|
||||
|
||||
##### Type
|
||||
##### Tipo
|
||||
|
||||
Must be one of the following:
|
||||
El tipo debe ser uno de los siguientes:
|
||||
|
||||
* **build**: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
|
||||
* **ci**: Changes to our CI configuration files and scripts (example scopes: Circle, BrowserStack, SauceLabs)
|
||||
* **docs**: Documentation only changes
|
||||
* **feat**: A new feature
|
||||
* **fix**: A bug fix
|
||||
* **perf**: A code change that improves performance
|
||||
* **refactor**: A code change that neither fixes a bug nor adds a feature
|
||||
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
|
||||
* **test**: Adding missing tests or correcting existing tests
|
||||
* **build**: cambios que afectan el sistema de compilación o dependencias externas (ejemplos de scopes: gulp, broccoli, npm)
|
||||
* **ci**: cambios en nuestros archivos y scripts de configuración de CI (ejemplos de scopes: Circle, BrowserStack, SauceLabs)
|
||||
* **docs**: cambios en la documentación
|
||||
* **feat**: una nueva funcionalidad
|
||||
* **fix**: una solución de un bug
|
||||
* **perf**: un cambio de código que mejora el rendimiento.
|
||||
* **refactor**: un cambio de código que no corrige ningún error ni agrega ninguna funcionalidad
|
||||
* **style**: cambios que no afectan el significado del código (espacios en blanco, formato, falta de punto y coma, etc.)
|
||||
* **test**: se agregan pruebas faltantes o se corrigen pruebas existentes
|
||||
|
||||
|
||||
##### Scope
|
||||
The scope should be the name of the npm package affected (as perceived by the person reading the changelog generated from commit messages).
|
||||
##### Alcance
|
||||
El alcance debe ser el nombre del paquete npm afectado (tal como lo percibe la persona que lee el registro de cambios generado a partir de los mensajes de commit).
|
||||
|
||||
The following is the list of supported scopes:
|
||||
La siguiente es la lista de alcances permitidos:
|
||||
|
||||
* `animations`
|
||||
* `bazel`
|
||||
@ -261,80 +261,73 @@ The following is the list of supported scopes:
|
||||
* `upgrade`
|
||||
* `zone.js`
|
||||
|
||||
There are currently a few exceptions to the "use package name" rule:
|
||||
Actualmente hay algunas excepciones a la regla "usar el nombre de paquete":
|
||||
|
||||
* `packaging`: used for changes that change the npm package layout in all of our packages, e.g. public path changes, package.json changes done to all packages, d.ts file/format changes, changes to bundles, etc.
|
||||
* `packaging`: usado para cambios que cambian el diseño de los paquetes de npm en todos nuestros paquetes. Ejemplos: cambios de la ruta públic, package.json cambios hechos a todos los paquetes, cambios a archivos o formatos d.ts, cambios a bundles, etc.
|
||||
|
||||
* `changelog`: used for updating the release notes in CHANGELOG.md
|
||||
* `changelog`: utilizado para actualizar las notas de la versión en CHANGELOG.md
|
||||
|
||||
* `dev-infra`: used for dev-infra related changes within the directories /scripts, /tools and /dev-infra
|
||||
* `dev-infra`: utilizado para cambios relacionados con dev-infra dentro de los directorios /scripts, /tools y /dev-infra
|
||||
|
||||
* `docs-infra`: used for docs-app (angular.io) related changes within the /aio directory of the repo
|
||||
* `docs-infra`: utilizado para cambios relacionados con la documentación (angular.io) dentro del directorio /aio del repositorio
|
||||
|
||||
* `migrations`: used for changes to the `ng update` migrations.
|
||||
* `migrations`: utilizado para los cambios en las migraciones `ng update`.
|
||||
|
||||
* `ngcc`: used for changes to the [Angular Compatibility Compiler](./packages/compiler-cli/ngcc/README.md)
|
||||
* `ngcc`: usado para los cambios del [Compilador de compatibilidad de Angular](./packages/compiler-cli/ngcc/README.md)
|
||||
|
||||
* `ve`: used for changes specific to ViewEngine (legacy compiler/renderer).
|
||||
* `ve`: utilizado para cambios específicos de ViewEngine (legacy compiler/renderer).
|
||||
|
||||
* none/empty string: useful for `style`, `test` and `refactor` changes that are done across all packages (e.g. `style: add missing semicolons`) and for docs changes that are not related to a specific package (e.g. `docs: fix typo in tutorial`).
|
||||
* alcance vacío: útil para cambios de `style`, `test` y `refactor` que se realizan en todos los paquetes (ejemplo: `style: add missing semicolons`) y para cambios de la documentación que no están relacionados a un paquete en específico(ejemplo: `docs: corrige error gramatical en el tutorial`).
|
||||
|
||||
|
||||
##### Summary
|
||||
##### Resumen
|
||||
|
||||
Use the summary field to provide a succinct description of the change:
|
||||
Usa el campo resumen para proporcionar una descripción breve del cambio:
|
||||
|
||||
* use the imperative, present tense: "change" not "changed" nor "changes"
|
||||
* don't capitalize the first letter
|
||||
* no dot (.) at the end
|
||||
* usa el modo imperativo, tiempo presente: "cambia" no "cambió" o "cambios"
|
||||
* no debe de contener ninguna letra mayúscula
|
||||
* no debe de conter punto (.) al final
|
||||
|
||||
|
||||
#### Commit Message Body
|
||||
#### Mensaje del cuerpo del commit
|
||||
|
||||
Just as in the summary, use the imperative, present tense: "fix" not "fixed" nor "fixes".
|
||||
Tal como en el resumen, usa el modo imperativo, tiempo presente: "cambia" no "cambió" o "cambios".
|
||||
|
||||
Explain the motivation for the change in the commit message body. This commit message should explain _why_ you are making the change.
|
||||
You can include a comparison of the previous behavior with the new behavior in order to illustrate the impact of the change.
|
||||
Explica la razón del cambio en el el mensaje del cuerpo del commit. Este mensaje de confirmación debe explicar _por qué_ está realizando el cambio.
|
||||
Puedes incluir una comparación del comportamiento anterior con el nuevo comportamiento para ilustrar el impacto del cambio.
|
||||
|
||||
|
||||
#### Commit Message Footer
|
||||
#### Mensaje del footer del commit
|
||||
|
||||
The footer can contain information about breaking changes and is also the place to reference GitHub issues, Jira tickets, and other PRs that this commit closes or is related to.
|
||||
El footer puede contener información sobre cambios significativos y también es el lugar para hacer referencia a issues de GitHub, tickets de Jira y otros PRs que están relacionados con el commit.
|
||||
|
||||
```
|
||||
BREAKING CHANGE: <breaking change summary>
|
||||
<BLANK LINE>
|
||||
<breaking change description + migration instructions>
|
||||
<BLANK LINE>
|
||||
<BLANK LINE>
|
||||
Fixes #<issue number>
|
||||
CAMBIO SIGNIFICATIVO: <resumen del cambio significativo>
|
||||
<LINEA VACIA>
|
||||
<descripción del cambio significativo + instrucciones para la migración>
|
||||
<LINEA VACIA>
|
||||
<LINEA VACIA>
|
||||
Fix #<issue número>
|
||||
```
|
||||
|
||||
Breaking Change section should start with the phrase "BREAKING CHANGE: " followed by a summary of the breaking change, a blank line, and a detailed description of the breaking change that also includes migration instructions.
|
||||
La sección de cambios significativos debería comenzar con la frase "CAMBIO SIGNIFICATIVO: " seguido de un resumen del cambio significativo, una línea en blanco y una descripción detallada del cambio significativo que también incluya instrucciones de migración.
|
||||
|
||||
|
||||
### Revert commits
|
||||
### Revirtiendo commits
|
||||
|
||||
If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit.
|
||||
Si el commit revierte un commit previo, el commit debería comenzar con `revert: `, seguido por el header del commit revertido.
|
||||
|
||||
The content of the commit message body should contain:
|
||||
El contenido del mensaje del commit debería contener:
|
||||
|
||||
- information about the SHA of the commit being reverted in the following format: `This reverts commit <SHA>`,
|
||||
- a clear description of the reason for reverting the commit message.
|
||||
- Información sobre el SHA del commit que se revierte en el siguiente formato: `Esto revierte el commit <SHA>`,
|
||||
- Una descripción clara de la razón para revertir el mensaje del _commit_.
|
||||
|
||||
|
||||
## <a name="cla"></a> Signing the CLA
|
||||
## <a name="cla"></a> Firma del Acuerdo de Licencia de Colaborador (CLA)
|
||||
|
||||
Please sign our Contributor License Agreement (CLA) before sending pull requests. For any code
|
||||
changes to be accepted, the CLA must be signed. It's a quick process, we promise!
|
||||
Por favor firma nuestro Acuerdo de Licencia de Colaborador (CLA) cuando creas tu primer pull request. Para que cualquier cambio de código sea aceptado, el Acuerdo de Licencia de Colaborador (CLA) debe ser firmado. Es un proceso rápido con nuestro CLA assistant que está integrado con nuestro CI.
|
||||
|
||||
* For individuals, we have a [simple click-through form][individual-cla].
|
||||
* For corporations, we'll need you to
|
||||
[print, sign and one of scan+email, fax or mail the form][corporate-cla].
|
||||
|
||||
If you have more than one GitHub accounts, or multiple email addresses associated with a single GitHub account, you must sign the CLA using the primary email address of the GitHub account used to author Git commits and send pull requests.
|
||||
|
||||
The following documents can help you sort out issues with GitHub accounts and multiple email addresses:
|
||||
Los siguientes documentos pueden ayudarte a resolver problemas con cuentas de GitHub y múltiples direcciones de correo electrónico:
|
||||
|
||||
* https://help.github.com/articles/setting-your-commit-email-address-in-git/
|
||||
* https://stackoverflow.com/questions/37245303/what-does-usera-committed-with-userb-13-days-ago-on-github-mean
|
||||
|
26
README.en.md
Normal file
26
README.en.md
Normal file
@ -0,0 +1,26 @@
|
||||
[](https://circleci.com/gh/angular/workflows/angular/tree/master)
|
||||
[](https://gitter.im/angular/angular?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://www.npmjs.com/@angular/core)
|
||||
|
||||
|
||||
# Angular
|
||||
|
||||
Angular is a development platform for building mobile and desktop web applications using TypeScript/JavaScript and other languages.
|
||||
|
||||
## Quickstart
|
||||
|
||||
[Get started in 5 minutes][quickstart].
|
||||
|
||||
## Changelog
|
||||
|
||||
[Learn about the latest improvements][changelog].
|
||||
|
||||
## Want to help?
|
||||
|
||||
Want to file a bug, contribute some code, or improve documentation? Excellent! Read up on our
|
||||
guidelines for [contributing][contributing] and then check out one of our issues in the [hotlist: community-help](https://github.com/angular/angular/labels/hotlist%3A%20community-help).
|
||||
|
||||
[contributing]: https://github.com/angular/angular/blob/master/CONTRIBUTING.md
|
||||
[quickstart]: https://angular.io/start
|
||||
[changelog]: https://github.com/angular/angular/blob/master/CHANGELOG.md
|
||||
[ng]: https://angular.io
|
31
README.md
31
README.md
@ -1,26 +1,25 @@
|
||||
[](https://circleci.com/gh/angular/workflows/angular/tree/master)
|
||||
[](https://gitter.im/angular/angular?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://www.npmjs.com/@angular/core)
|
||||
# Angular en español
|
||||
|
||||
Angular es una plataforma de desarrollo para construir aplicaciones web y móviles que usa
|
||||
TypeScript/JavaScript y otros lenguajes de programación.
|
||||
|
||||
# Angular
|
||||
## ¿Quieres ayudar?
|
||||
|
||||
Angular is a development platform for building mobile and desktop web applications using TypeScript/JavaScript and other languages.
|
||||
### Documentación en español
|
||||
|
||||
## Quickstart
|
||||
¿Quieres mejorar la documentación? ¡Excelente! Lee nuestras pautas para
|
||||
[colaborar](CONTRIBUTING.md) y luego revisa algunos de nuestras
|
||||
[issues](https://github.com/angular-hispano/angular/issues).
|
||||
|
||||
[Get started in 5 minutes][quickstart].
|
||||
### El framework
|
||||
|
||||
## Changelog
|
||||
La colaboración para corregir errores y agregar funciones en el framework debe realizarse en inglés a través
|
||||
del repositorio [angular/angular](https://github.com/angular/angular) upstream.
|
||||
|
||||
[Learn about the latest improvements][changelog].
|
||||
## Guía rápida
|
||||
|
||||
## Want to help?
|
||||
[Comienza a usarlo en 5 minutos](https://docs.angular.lat/start).
|
||||
|
||||
Want to file a bug, contribute some code, or improve documentation? Excellent! Read up on our
|
||||
guidelines for [contributing][contributing] and then check out one of our issues in the [hotlist: community-help](https://github.com/angular/angular/labels/hotlist%3A%20community-help).
|
||||
## Registro de cambios (Changelog)
|
||||
|
||||
[contributing]: https://github.com/angular/angular/blob/master/CONTRIBUTING.md
|
||||
[quickstart]: https://angular.io/start
|
||||
[changelog]: https://github.com/angular/angular/blob/master/CHANGELOG.md
|
||||
[ng]: https://angular.io
|
||||
[Últimas mejoras realizadas](CHANGELOG.md).
|
||||
|
167
aio/README.md
167
aio/README.md
@ -1,140 +1,131 @@
|
||||
# Angular documentation project (https://angular.io)
|
||||
# Proyecto de documentación Angular (https://docs.angular.lat)
|
||||
|
||||
Everything in this folder is part of the documentation project. This includes
|
||||
Todo en esta carpeta es parte del proyecto de documentación. Esto incluye:
|
||||
|
||||
* the web site for displaying the documentation
|
||||
* the dgeni configuration for converting source files to rendered files that can be viewed in the web site.
|
||||
* the tooling for setting up examples for development; and generating live-example and zip files from the examples.
|
||||
* El sitio web para mostrar la documentación
|
||||
* La configuración de dgeni para convertir los archivos de origen a archivos renderizados que se pueden vizualizar en el sitio web.
|
||||
* Las herramientas para establecer ejemplos para el desarrollo; y generar archivos en tiempo real y archivos zip desde los ejemplos.
|
||||
|
||||
## Developer tasks
|
||||
## Tareas de desarrollador
|
||||
|
||||
We use [Yarn](https://yarnpkg.com) to manage the dependencies and to run build tasks.
|
||||
You should run all these tasks from the `angular/aio` folder.
|
||||
Here are the most important tasks you might need to use:
|
||||
Nosotros usamos [Yarn](https://yarnpkg.com) para gestionar las dependencias y crear tareas de compilación.
|
||||
Debes ejecutar todas estas tareas desde la carpeta `angular/aio`.
|
||||
Aquí están las tareas más importantes que podrías necesitar usar:
|
||||
|
||||
* `yarn` - install all the dependencies.
|
||||
* `yarn setup` - install all the dependencies, boilerplate, stackblitz, zips and run dgeni on the docs.
|
||||
* `yarn setup-local` - same as `setup`, but build the Angular packages from the source code and use these locally built versions (instead of the ones fetched from npm) for aio and docs examples boilerplate.
|
||||
* `yarn` - instalar todas las dependencias.
|
||||
* `yarn setup` - instalar todas las dependencias, boilerplate, stackblitz, zips y ejecuta dgeni en los documentos.
|
||||
* `yarn setup-local` - igual que `setup`, pero crea los paquetes de Angular a partir del código y usa estas versiones construidas localmente (en lugar de las recuperadas desde npm) para aio y ejemplos de documentos boilerplate.
|
||||
|
||||
* `yarn build` - create a production build of the application (after installing dependencies, boilerplate, etc).
|
||||
* `yarn build-local` - same as `build`, but use `setup-local` instead of `setup`.
|
||||
* `yarn build-local-with-viewengine` - same as `build-local`, but in addition also turns on `ViewEngine` (pre-Ivy) mode in aio.
|
||||
(Note: To turn on `ViewEngine` mode in docs examples, see `yarn boilerplate:add:viewengine` below.)
|
||||
* `yarn build` - crear una compilación de producción de la aplicación (después de instalar dependencias, boilerplate, etc).
|
||||
* `yarn build-local` - igual que `build`, pero usa `setup-local` en lugar de `setup`.
|
||||
* `yarn build-local-with-viewengine` - igual que `build-local`, pero además también enciende el modo `ViewEngine` (pre-Ivy) en aio.
|
||||
(Nota: Encender el modo `ViewEngine` en ejemplos de documentos, ver `yarn boilerplate:add:viewengine` abajo.)
|
||||
|
||||
* `yarn start` - run a development web server that watches the files; then builds the doc-viewer and reloads the page, as necessary.
|
||||
* `yarn serve-and-sync` - run both the `docs-watch` and `start` in the same console.
|
||||
* `yarn lint` - check that the doc-viewer code follows our style rules.
|
||||
* `yarn test` - watch all the source files, for the doc-viewer, and run all the unit tests when any change.
|
||||
* `yarn test --watch=false` - run all the unit tests once.
|
||||
* `yarn e2e` - run all the e2e tests for the doc-viewer.
|
||||
* `yarn start` - ejecutar un servidor web de desarrollo que observa los archivos; luego crea el doc-viewer y vuelve a cargar la página, según sea necesario.
|
||||
* `yarn serve-and-sync` - ejecutar ambos, el `docs-watch` y `start` en la misma consola.
|
||||
* `yarn lint` - comprobar que el código del doc-viewer sigue nuestras reglas de estilo.
|
||||
* `yarn test` - observar todos los archivos de origen, para el doc-viewer, y ejecuta todas las pruebas unitarias cuando haya algún cambio.
|
||||
* `yarn test --watch=false` -ejecutar todas las pruebas unitarias una sola vez.
|
||||
* `yarn e2e` - ejecutar todas las pruebas de e2e para el doc-viewer.
|
||||
|
||||
* `yarn docs` - generate all the docs from the source files.
|
||||
* `yarn docs-watch` - watch the Angular source and the docs files and run a short-circuited doc-gen for the docs that changed.
|
||||
* `yarn docs-lint` - check that the doc gen code follows our style rules.
|
||||
* `yarn docs-test` - run the unit tests for the doc generation code.
|
||||
* `yarn docs` - generar toda la documentación desde los archivos fuente.
|
||||
* `yarn docs-watch` - observar el código Angular, los archivos de documentación y ejecutar un 'doc-gen' en corto circuito para los documentos que fueron cambiados.
|
||||
* `yarn docs-lint` - comprobar que el código del documento generado sigue nuestras reglas de estilo.
|
||||
* `yarn docs-test` - ejecutar las pruebas unitarias para el código de generación de doc.
|
||||
|
||||
* `yarn boilerplate:add` - generate all the boilerplate code for the examples, so that they can be run locally.
|
||||
* `yarn boilerplate:add:viewengine` - same as `boilerplate:add` but also turns on `ViewEngine` (pre-Ivy) mode.
|
||||
* `yarn boilerplate:add` - generar todo el código boilerplate para los ejemplos, para que puedan ejecutarse localmente.
|
||||
* `yarn boilerplate:add:viewengine` - igual que `boilerplate:add` pero también enciende el modo `ViewEngine` (pre-Ivy).
|
||||
|
||||
* `yarn boilerplate:remove` - remove all the boilerplate code that was added via `yarn boilerplate:add`.
|
||||
* `yarn generate-stackblitz` - generate the stackblitz files that are used by the `live-example` tags in the docs.
|
||||
* `yarn generate-zips` - generate the zip files from the examples. Zip available via the `live-example` tags in the docs.
|
||||
* `yarn boilerplate:remove` - eliminar todo el código boilerplate que fue añadido a través`yarn boilerplate:add`.
|
||||
* `yarn generate-stackblitz` - generar los archivos stackblitz que están usados por la etiqueta `live-example` en documentos.
|
||||
* `yarn generate-zips` - generar los archivos zip desde los ejemplos. Zip está disponible a través de la etiqueta `live-example` en los documentos.
|
||||
|
||||
* `yarn example-e2e` - run all e2e tests for examples. Available options:
|
||||
- `--setup`: generate boilerplate, force webdriver update & other setup, then run tests.
|
||||
- `--local`: run e2e tests with the local version of Angular contained in the "dist" folder.
|
||||
_Requires `--setup` in order to take effect._
|
||||
- `--viewengine`: run e2e tests in `ViewEngine` (pre-Ivy) mode.
|
||||
- `--filter=foo`: limit e2e tests to those containing the word "foo".
|
||||
* `yarn example-e2e` - ejecutar todas las pruebas e2e para ejemplos. Opciones disponibles:
|
||||
- `--setup`: generar boilerplate, forzar la actualización del controlador web y otras configuraciones, luego ejecutar las pruebas.
|
||||
- `--local`: ejecutar pruebas e2e con la versión local de Angular contenida en la carpeta "dist".
|
||||
_Requiere `--setup` para que surta efecto._
|
||||
- `--viewengine`: ejecutar pruebas e2e en modo `ViewEngine` (pre-Ivy).
|
||||
- `--filter=foo`: limitar pruebas e2e a las que contienen la palabra "foo".
|
||||
|
||||
> **Note for Windows users**
|
||||
> **Nota para usuarios Windows**
|
||||
>
|
||||
> Setting up the examples involves creating some [symbolic links](https://en.wikipedia.org/wiki/Symbolic_link) (see [here](./tools/examples/README.md#symlinked-node_modules) for details). On Windows, this requires to either have [Developer Mode enabled](https://blogs.windows.com/windowsdeveloper/2016/12/02/symlinks-windows-10) (supported on Windows 10 or newer) or run the setup commands as administrator.
|
||||
> Configurar los ejemplos implica crear algunos [enlaces simbólicos](https://es.wikipedia.org/wiki/Enlace_simb%C3%B3lico) (ver [Aquí](./tools/examples/README.md#symlinked-node_modules) para más detalles). En Windows, esto requiere tener [Habilitado el Modo de desarrollador ](https://blogs.windows.com/windowsdeveloper/2016/12/02/symlinks-windows-10) (compatible con Windows 10 o más reciente) o ejecutar los comandos de configuración cómo administrador.
|
||||
>
|
||||
> The affected commands are:
|
||||
> Los comandos afectados son:
|
||||
> - `yarn setup` / `yarn setup-*`
|
||||
> - `yarn build` / `yarn build-*`
|
||||
> - `yarn boilerplate:add`
|
||||
> - `yarn example-e2e --setup`
|
||||
|
||||
## Using ServiceWorker locally
|
||||
## Usando ServiceWorker localmente
|
||||
|
||||
Running `yarn start` (even when explicitly targeting production mode) does not set up the
|
||||
ServiceWorker. If you want to test the ServiceWorker locally, you can use `yarn build` and then
|
||||
serve the files in `dist/` with `yarn http-server dist -p 4200`.
|
||||
Ejecutando `yarn start` (incluso cuando se apunta explícitamente al modo de producción) no configura el
|
||||
ServiceWorker. Si quieres probar el ServiceWorker localmente, puedes usar `yarn build` y luego
|
||||
ejecutar los archivos en `dist/` con `yarn http-server dist -p 4200`.
|
||||
|
||||
|
||||
## Guide to authoring
|
||||
## Guía de autoría
|
||||
Existen dos tipos de contenido en la documentación:
|
||||
|
||||
There are two types of content in the documentation:
|
||||
* **Documentación de API**: descripciones de los módulos, clases, interfaces, decoradores, etc que son parte de la plataforma Angular.
|
||||
La documentacion de API está generada directamente desde el código fuente.
|
||||
El código fuente está contenido en archivos TypeScript , almacenados en la carpeta `angular/packages`.
|
||||
Cada elemento de la API puede tener un comentario anterior, el cual contiene etiquetas y contenido de estilos JSDoc.
|
||||
El contenido está escrito en markdown.
|
||||
|
||||
* **API docs**: descriptions of the modules, classes, interfaces, decorators, etc that make up the Angular platform.
|
||||
API docs are generated directly from the source code.
|
||||
The source code is contained in TypeScript files, located in the `angular/packages` folder.
|
||||
Each API item may have a preceding comment, which contains JSDoc style tags and content.
|
||||
The content is written in markdown.
|
||||
* **Otro contenido**: guias, tutoriales, y otro material de marketing.
|
||||
Todos los demás contenidos se escriben utilizando markdown en archivos de texto, ubicados en la carpeta `angular/aio/content`.
|
||||
Más específicamente, hay subcarpetas que contienen tipos particulares de contenido: guías, tutoriales y marketing.
|
||||
|
||||
* **Other content**: guides, tutorials, and other marketing material.
|
||||
All other content is written using markdown in text files, located in the `angular/aio/content` folder.
|
||||
More specifically, there are sub-folders that contain particular types of content: guides, tutorial and marketing.
|
||||
* **Ejempos de código**: los ejemplos de código deben ser comprobables para garantizar su precisión.
|
||||
Además, nuestros ejemplos tienen un aspecto específico y permiten al usuario copiar el código fuente. Para mayor
|
||||
ejemplos se representan en una interfaz con pestañas (e.g. template, HTML, y TypeScript en pestañas separadas). Adicionalmente, algunos son ejemplos en acción, que proporcionan enlaces donde se puede editar el código, ejecutar, y/o descargar. Para obtener más detalles sobre cómo trabajar con ejemplos de código, lea los [fragmentos de código](https://docs.angular.lat/guide/docs-style-guide#code-snippets), [código fuente de marcado ](https://docs.angular.lat/guide/docs-style-guide#source-code-markup), y [ ejemplos en acción ](https://docs.angular.lat/guide/docs-style-guide#live-examples) paginas de los [ autores de guías de estilo ](https://docs.angular.lat/guide/docs-style-guide).
|
||||
|
||||
* **Code examples**: code examples need to be testable to ensure their accuracy.
|
||||
Also, our examples have a specific look and feel and allow the user to copy the source code. For larger
|
||||
examples they are rendered in a tabbed interface (e.g. template, HTML, and TypeScript on separate
|
||||
tabs). Additionally, some are live examples, which provide links where the code can be edited, executed, and/or downloaded. For details on working with code examples, please read the [Code snippets](https://angular.io/guide/docs-style-guide#code-snippets), [Source code markup](https://angular.io/guide/docs-style-guide#source-code-markup), and [Live examples](https://angular.io/guide/docs-style-guide#live-examples) pages of the [Authors Style Guide](https://angular.io/guide/docs-style-guide).
|
||||
Usamos la herramienta [dgeni](https://github.com/angular/dgeni) para convertir estos archivos en docs que se pueden ver en el doc-viewer.
|
||||
Las [guías de estilo para Autores](https://docs.angular.lat/guide/docs-style-guide) prescriben pautas para
|
||||
escribir páginas de guía, explica cómo usar la documentación de clases y componentes, y cómo marcar el código fuente para producir fragmentos de código.
|
||||
|
||||
We use the [dgeni](https://github.com/angular/dgeni) tool to convert these files into docs that can be viewed in the doc-viewer.
|
||||
### Generando documentos completos
|
||||
|
||||
The [Authors Style Guide](https://angular.io/guide/docs-style-guide) prescribes guidelines for
|
||||
writing guide pages, explains how to use the documentation classes and components, and how to markup sample source code to produce code snippets.
|
||||
La principal tarea para generar los documentos es `yarn docs`. Esto procesará todos los archivos fuente (API y otros), extrayendo la documentación y generando archivos JSON que pueden ser consumidos por el doc-viewer.
|
||||
|
||||
### Generating the complete docs
|
||||
### Generación parcial de doc para editores
|
||||
|
||||
The main task for generating the docs is `yarn docs`. This will process all the source files (API and other),
|
||||
extracting the documentation and generating JSON files that can be consumed by the doc-viewer.
|
||||
La generación completa de documentos puede llevar hasta un minuto. Eso es demasiado lento para la creación y edición eficiente de documentos.
|
||||
|
||||
### Partial doc generation for editors
|
||||
Puedes ealizar pequeños cambios en un editor inteligente que muestre un markdown con formato:
|
||||
>En VS Code, _Cmd-K, V_ abre la vista previa de markdown en el panel lateral; _Cmd-B_ alterna la barra izquierda
|
||||
|
||||
Full doc generation can take up to one minute. That's too slow for efficient document creation and editing.
|
||||
Puedes también mirar los cambios que se muestran correctamente en el doc-viewer
|
||||
con un tiempo de ciclo rápido de edición / visualización.
|
||||
|
||||
You can make small changes in a smart editor that displays formatted markdown:
|
||||
>In VS Code, _Cmd-K, V_ opens markdown preview in side pane; _Cmd-B_ toggles left sidebar
|
||||
Para este propósito, usa la tarea `yarn docs-watch`, que observa los cambios en los archivos de origen y solo vuelve a procesar los archivos necesarios para generar los documentos relacionados con el archivo que ha cambiado.
|
||||
Dado que esta tarea tiene accesos directos, es mucho más rápido (a menudo menos de 1 segundo) pero no producirá contenido de fidelidad completa. Por ejemplo, los enlaces a otros documentoss y ejemplos de código pueden no mostrarse correctamente. Esto se nota especialmente en los enlaces a otros documentos y en los ejemplos incrustados, que no siempre se representan correctamente.
|
||||
|
||||
You also want to see those changes displayed properly in the doc viewer
|
||||
with a quick, edit/view cycle time.
|
||||
La configuración general es la siguiente:
|
||||
|
||||
For this purpose, use the `yarn docs-watch` task, which watches for changes to source files and only
|
||||
re-processes the files necessary to generate the docs that are related to the file that has changed.
|
||||
Since this task takes shortcuts, it is much faster (often less than 1 second) but it won't produce full
|
||||
fidelity content. For example, links to other docs and code examples may not render correctly. This is
|
||||
most particularly noticed in links to other docs and in the embedded examples, which may not always render
|
||||
correctly.
|
||||
|
||||
The general setup is as follows:
|
||||
|
||||
* Open a terminal, ensure the dependencies are installed; run an initial doc generation; then start the doc-viewer:
|
||||
* Abrir una terminal, estar seguro que las dependencias están instaladas; ejecutar una generación inicial del doc; luego iniciar el doc-viewer:
|
||||
|
||||
```bash
|
||||
yarn setup
|
||||
yarn start
|
||||
```
|
||||
|
||||
* Open a second terminal and start watching the docs
|
||||
* Abrir una segunda terminal e iniciar el observador de documentos.
|
||||
|
||||
```bash
|
||||
yarn docs-watch
|
||||
```
|
||||
|
||||
>Alternatively, try the consolidated `serve-and-sync` command that builds, watches and serves in the same terminal window
|
||||
>Alternativamente, prueba el comando fusionado `serve-and-sync` que crea, observa y ejecuta en la misma ventana de la terminal
|
||||
```bash
|
||||
yarn serve-and-sync
|
||||
```
|
||||
|
||||
* Open a browser at https://localhost:4200/ and navigate to the document on which you want to work.
|
||||
You can automatically open the browser by using `yarn start -o` in the first terminal.
|
||||
* Abre un navegador con la siguiente dirección https://localhost:4200/ y navega hasta el documento en el que quieras trabajar.
|
||||
Puedes automáticamente abrir el navegador utilizando `yarn start -o` en la primera terminal.
|
||||
|
||||
* Make changes to the page's associated doc or example files. Every time a file is saved, the doc will
|
||||
be regenerated, the app will rebuild and the page will reload.
|
||||
* Realiza cambios en la página de documentación asociada o en los archivos de ejemplo. Cada vez que un archivo es guardado, la documentación se regenerará, la aplicación se reconstruirá y la página se volverá a cargar.
|
||||
|
||||
* If you get a build error complaining about examples or any other odd behavior, be sure to consult
|
||||
the [Authors Style Guide](https://angular.io/guide/docs-style-guide).
|
||||
*Si recibes un error de compilación acerca de los ejemplos o cualquier otro error, asegúrate de consultar las
|
||||
[guías de estilo para Autores](https://angular.io/guide/docs-style-guide) para más información.
|
||||
|
@ -1,111 +1,112 @@
|
||||
# Accessibility in Angular
|
||||
# Accesibilidad en Angular
|
||||
|
||||
The web is used by a wide variety of people, including those who have visual or motor impairments.
|
||||
A variety of assistive technologies are available that make it much easier for these groups to
|
||||
interact with web-based software applications.
|
||||
In addition, designing an application to be more accessible generally improves the user experience for all users.
|
||||
Hay una amplia variedad de personas que utilizan la web, algunas de ellas con discapacidad visual o motora.
|
||||
Existen diferentes tecnologías de apoyo que hacen que sea mucho más fácil para estos grupos
|
||||
interactuar con aplicaciones de software basadas en la web.
|
||||
Además, diseñar una aplicación para que sea más accesible, normalmente mejora la experiencia de usuario en general.
|
||||
|
||||
For an in-depth introduction to issues and techniques for designing accessible applications, see the [Accessibility](https://developers.google.com/web/fundamentals/accessibility/#what_is_accessibility) section of the Google's [Web Fundamentals](https://developers.google.com/web/fundamentals/).
|
||||
Para una introducción en profundidad a los problemas y técnicas sobre el diseño de aplicaciones accesibles, puede consultar la sección de [Accesibilidad](https://developers.google.com/web/fundamentals/accessibility/#what_is_accessibility) de Google [Fundamentos Web](https://developers.google.com/web/fundamentals/).
|
||||
|
||||
This page discusses best practices for designing Angular applications that
|
||||
work well for all users, including those who rely on assistive technologies.
|
||||
Esta página habla de las mejores prácticas para diseñar aplicaciones en Angular que funcionan
|
||||
bien para todos los usuarios, incluyendo aquéllos que necesitan tecnologías de apoyo.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For the sample app that this page describes, see the <live-example></live-example>.
|
||||
Para ver la aplicación de ejemplo que describe esta página, ir a <live-example></live-example>.
|
||||
|
||||
</div>
|
||||
|
||||
## Accessibility attributes
|
||||
## Atributos de accesibilidad
|
||||
|
||||
Building accessible web experience often involves setting [ARIA attributes](https://developers.google.com/web/fundamentals/accessibility/semantics-aria)
|
||||
to provide semantic meaning where it might otherwise be missing.
|
||||
Use [attribute binding](guide/attribute-binding) template syntax to control the values of accessibility-related attributes.
|
||||
Crear una web accesible a menudo implica establecer los [atributos ARIA](https://developers.google.com/web/fundamentals/accessibility/semantics-aria)
|
||||
para proporcionar la semántica que, de otro modo, podría no estar presente.
|
||||
Usa la plantilla de sintaxis del [enlace de atributos](attribute binding) (guide/attribute-binding) para controlar los valores de los atributos relacionados con la accesibilidad.
|
||||
|
||||
When binding to ARIA attributes in Angular, you must use the `attr.` prefix, as the ARIA
|
||||
specification depends specifically on HTML attributes rather than properties of DOM elements.
|
||||
Para enlazar los atributos ARIA en Angular, debes usar el prefijo `attr.`, ya que la especificación ARIA
|
||||
depende de los atributos HTML y no de las propiedades de los elementos del DOM.
|
||||
|
||||
```html
|
||||
<!-- Use attr. when binding to an ARIA attribute -->
|
||||
<button [attr.aria-label]="myActionLabel">...</button>
|
||||
```
|
||||
|
||||
Note that this syntax is only necessary for attribute _bindings_.
|
||||
Static ARIA attributes require no extra syntax.
|
||||
Observa que esta sintaxis solo es necesaria para los _enlaces_ de atributos.
|
||||
Los atributos ARIA estáticos no requieren de ninguna sintaxis adicional.
|
||||
|
||||
```html
|
||||
<!-- Static ARIA attributes require no extra syntax -->
|
||||
<button aria-label="Save document">...</button>
|
||||
```
|
||||
|
||||
NOTE:
|
||||
NOTA:
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
By convention, HTML attributes use lowercase names (`tabindex`), while properties use camelCase names (`tabIndex`).
|
||||
Por convenio, los atributos HTML se escriben en minúscula (`tabindex`), mientras que para las propiedades se usa *camelCase* (`tabIndex`).
|
||||
|
||||
See the [Binding syntax](guide/binding-syntax#html-attribute-vs-dom-property) guide for more background on the difference between attributes and properties.
|
||||
Consulta la guía [Sintaxis del enlace](guide/binding-syntax#html-attribute-vs-dom-property) para saber más sobre las diferencias entre atributos y propiedades.
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
## Angular UI components
|
||||
## Componentes del interfaz de usuario de Angular
|
||||
|
||||
The [Angular Material](https://material.angular.io/) library, which is maintained by the Angular team, is a suite of reusable UI components that aims to be fully accessible.
|
||||
The [Component Development Kit (CDK)](https://material.angular.io/cdk/categories) includes the `a11y` package that provides tools to support various areas of accessibility.
|
||||
For example:
|
||||
La librería [Angular Material](https://material.angular.io/), que es mantenida por el equipo Angular, es un conjunto de componentes reutilizables para la interfaz de usuario que pretende ser totalmente accesible.
|
||||
El [Kit de Desarrollo de Componentes (CDK)](https://material.angular.io/cdk/categories) (Component Development Kit) incluye el paquete `a11y` que proporciona herramientas para dar soporte a distintos aspectos de la accesibilidad.
|
||||
Por ejemplo:
|
||||
|
||||
* `LiveAnnouncer` is used to announce messages for screen-reader users using an `aria-live` region. See the W3C documentation for more information on [aria-live regions](https://www.w3.org/WAI/PF/aria-1.1/states_and_properties#aria-live).
|
||||
* `LiveAnnouncer` se utiliza para comunicar mensajes a los usuarios de lectores de pantalla que usan la region `aria-live`. Se puede consultar la documentación de la W3C para obtener más información sobre [regiones aria-live](https://www.w3.org/WAI/PF/aria-1.1/states_and_properties#aria-live).
|
||||
|
||||
* The `cdkTrapFocus` directive traps Tab-key focus within an element. Use it to create accessible experience for components like modal dialogs, where focus must be constrained.
|
||||
* La directiva `cdkTrapFocus` limita el foco de la tecla de tabulación para que se quede dentro de un elemento. Úsala para crear una experiencia accesible en componentes como las ventanas modales, donde el foco debe estar limitado.
|
||||
|
||||
For full details of these and other tools, see the [Angular CDK accessibility overview](https://material.angular.io/cdk/a11y/overview).
|
||||
Para obtener más detalles sobre esta y otras herramientas, consulta el [resumen de accesibilidad del Angular CDK](https://material.angular.io/cdk/a11y/overview).
|
||||
|
||||
|
||||
### Augmenting native elements
|
||||
### Aumento de elementos nativos
|
||||
|
||||
Native HTML elements capture a number of standard interaction patterns that are important to accessibility.
|
||||
When authoring Angular components, you should re-use these native elements directly when possible, rather than re-implementing well-supported behaviors.
|
||||
Los elementos HTML nativos capturan una serie de patrones de interacción estándar que son importantes para la accesibilidad.
|
||||
Al crear componentes de Angular, deberías reutilizar estos elementos nativos directamente cuando sea posible, en lugar de volver a implementar comportamientos bien soportados.
|
||||
|
||||
For example, instead of creating a custom element for a new variety of button, you can create a component that uses an attribute selector with a native `<button>` element.
|
||||
This most commonly applies to `<button>` and `<a>`, but can be used with many other types of element.
|
||||
Por ejemplo, en lugar de crear un elemento personalizado para un nuevo tipo de botón, puedes crear un componente que use un selector de atributos con un elemento nativo `<button>`.
|
||||
Esto se aplica sobre todo a `<button>` y `<a>`, pero se puede usar con muchos otros tipos de elementos.
|
||||
|
||||
You can see examples of this pattern in Angular Material: [`MatButton`](https://github.com/angular/components/blob/master/src/material/button/button.ts#L66-L68), [`MatTabNav`](https://github.com/angular/components/blob/master/src/material/tabs/tab-nav-bar/tab-nav-bar.ts#L67), [`MatTable`](https://github.com/angular/components/blob/master/src/material/table/table.ts#L17).
|
||||
|
||||
### Using containers for native elements
|
||||
### Uso de contenedores para elementos nativos
|
||||
|
||||
Sometimes using the appropriate native element requires a container element.
|
||||
For example, the native `<input>` element cannot have children, so any custom text entry components need
|
||||
to wrap an `<input>` with additional elements.
|
||||
While you might just include the `<input>` in your custom component's template,
|
||||
this makes it impossible for users of the component to set arbitrary properties and attributes to the input element.
|
||||
Instead, you can create a container component that uses content projection to include the native control in the
|
||||
component's API.
|
||||
A veces, para usar el elemento nativo apropiado hace falta un contenedor.
|
||||
Por ejemplo, el elemento nativo `<input>` no puede tener hijos, por lo que cualquier componente de entrada de texto personalizado necesita envolver un `<input>` con elementos adicionales.
|
||||
|
||||
You can see [`MatFormField`](https://material.angular.io/components/form-field/overview) as an example of this pattern.
|
||||
Si bien puedes incluir el `<input>` en la plantilla de tu componente personalizado,
|
||||
esto hace que sea imposible para los usuarios de dicho componente establecer propiedades y atributos arbitrarios para el elemento de entrada.
|
||||
En su lugar, puedes crear un componente contenedor que utilice la proyección de contenido para incluir el control nativo en el
|
||||
API del componente.
|
||||
|
||||
## Case study: Building a custom progress bar
|
||||
Puedes consultar [`MatFormField`](https://material.angular.io/components/form-field/overview) para ver un ejemplo de este patrón.
|
||||
|
||||
The following example shows how to make a simple progress bar accessible by using host binding to control accessibility-related attributes.
|
||||
## Caso práctico: creación de una barra de progreso personalizada
|
||||
|
||||
* The component defines an accessibility-enabled element with both the standard HTML attribute `role`, and ARIA attributes. The ARIA attribute `aria-valuenow` is bound to the user's input.
|
||||
El siguiente ejemplo muestra cómo hacer que una barra de progreso simple sea accesible utilizando el *host binding* para controlar los atributos relacionados con la accesibilidad.
|
||||
|
||||
* El componente define un elemento habilitado para accesibilidad con el atributo HTML estándar `role` y los atributos ARIA. El atributo ARIA `aria-valuenow` está vinculado a la entrada del usuario.
|
||||
|
||||
<code-example path="accessibility/src/app/progress-bar.component.ts" header="src/app/progress-bar.component.ts" region="progressbar-component"></code-example>
|
||||
|
||||
|
||||
* In the template, the `aria-label` attribute ensures that the control is accessible to screen readers.
|
||||
* En la plantilla, el atributo `aria-label` asegura que el control sea accesible para los lectores de pantalla.
|
||||
|
||||
<code-example path="accessibility/src/app/app.component.html" header="src/app/app.component.html" region="template"></code-example>
|
||||
|
||||
|
||||
## Routing and focus management
|
||||
## Enrutamiento y gestión del foco
|
||||
|
||||
Tracking and controlling [focus](https://developers.google.com/web/fundamentals/accessibility/focus/) in a UI is an important consideration in designing for accessibility.
|
||||
When using Angular routing, you should decide where page focus goes upon navigation.
|
||||
El seguimiento y el control del [foco](https://developers.google.com/web/fundamentals/accessibility/focus/) en una interfaz de usuario son aspectos muy importantes en el diseño si queremos tener en cuenta la accesibilidad.
|
||||
Al usar el enrutamiento de Angular, debes decidir dónde va el foco de la página al navegar.
|
||||
|
||||
To avoid relying solely on visual cues, you need to make sure your routing code updates focus after page navigation.
|
||||
Use the `NavigationEnd` event from the `Router` service to know when to update
|
||||
focus.
|
||||
Para evitar depender únicamente de señales visuales, te debes asegurar de que el código de enrutamiento actualiza el foco después de la navegación de la página.
|
||||
Usa el evento `NavigationEnd` del servicio` Router` para saber cuándo actualizar el foco.
|
||||
|
||||
El siguiente ejemplo muestra cómo encontrar y poner el foco en el contenido principal de la cabecera (el elemento `#main-content-header`) dentro del DOM después de la navegación.
|
||||
|
||||
The following example shows how to find and focus the main content header in the DOM after navigation.
|
||||
|
||||
@ -119,13 +120,12 @@ router.events.pipe(filter(e => e instanceof NavigationEnd)).subscribe(() => {
|
||||
});
|
||||
|
||||
```
|
||||
In a real application, the element that receives focus will depend on your specific
|
||||
application structure and layout.
|
||||
The focused element should put users in a position to immediately move into the main content that has just been routed into view.
|
||||
You should avoid situations where focus returns to the `body` element after a route change.
|
||||
En una aplicación real, el elemento que recibe el foco dependerá de la estructura específica y del diseño que tenga tu aplicación.
|
||||
El elemento enfocado debe colocar a los usuarios en una posición en la que pasen inmediatamente al contenido principal que acaba de ser visualizado.
|
||||
Debe evitar situaciones en las que el foco vuelva al elemento `body` después de un cambio de ruta.
|
||||
|
||||
|
||||
## Additional resources
|
||||
## Recursos adicionales
|
||||
|
||||
* [Accessibility - Google Web Fundamentals](https://developers.google.com/web/fundamentals/accessibility)
|
||||
|
||||
@ -145,13 +145,13 @@ You should avoid situations where focus returns to the `body` element after a ro
|
||||
|
||||
* [Codelyzer](http://codelyzer.com/rules/) provides linting rules that can help you make sure your code meets accessibility standards.
|
||||
|
||||
Books
|
||||
Libros
|
||||
|
||||
* "A Web for Everyone: Designing Accessible User Experiences", Sarah Horton and Whitney Quesenbery
|
||||
|
||||
* "Inclusive Design Patterns", Heydon Pickering
|
||||
|
||||
## More on accessibility
|
||||
## Más sobre accesibilidad
|
||||
|
||||
You may also be interested in the following:
|
||||
Podrías estar interesado en lo siguiente:
|
||||
* [Audit your Angular app's accessibility with codelyzer](https://web.dev/accessible-angular-with-codelyzer/).
|
||||
|
@ -341,7 +341,7 @@ The following are some of the key AngularJS built-in directives and their equiva
|
||||
In Angular, the template no longer specifies its associated controller.
|
||||
Rather, the component specifies its associated template as part of the component class decorator.
|
||||
|
||||
For more information, see [Architecture Overview](guide/architecture#components).
|
||||
For more information, see [Architecture Overview](guide/architecture#componentes).
|
||||
|
||||
</td>
|
||||
|
||||
@ -1035,7 +1035,7 @@ The Angular code is shown using TypeScript.
|
||||
This is a nonissue in Angular because ES 2015 modules
|
||||
handle the namespacing for you.
|
||||
|
||||
For more information on modules, see the [Modules](guide/architecture#modules) section of the
|
||||
For more information on modules, see the [Modules](guide/architecture#módulos) section of the
|
||||
[Architecture Overview](guide/architecture).
|
||||
</td>
|
||||
|
||||
@ -1112,7 +1112,7 @@ The Angular code is shown using TypeScript.
|
||||
|
||||
This is how you associate a template with logic, which is defined in the component class.
|
||||
|
||||
For more information, see the [Components](guide/architecture#components)
|
||||
For more information, see the [Components](guide/architecture#componentes)
|
||||
section of the [Architecture Overview](guide/architecture) page.
|
||||
</td>
|
||||
|
||||
@ -1144,7 +1144,7 @@ The Angular code is shown using TypeScript.
|
||||
|
||||
In Angular, you create a component class to contain the data model and control methods. Use the TypeScript <code>export</code> keyword to export the class so that the functionality can be imported into NgModules.
|
||||
|
||||
For more information, see the [Components](guide/architecture#components)
|
||||
For more information, see the [Components](guide/architecture#componentes)
|
||||
section of the [Architecture Overview](guide/architecture) page.
|
||||
</td>
|
||||
|
||||
|
@ -1,32 +1,32 @@
|
||||
# App shell
|
||||
|
||||
App shell is a way to render a portion of your application via a route at build time.
|
||||
It can improve the user experience by quickly launching a static rendered page (a skeleton common to all pages) while the browser downloads the full client version and switches to it automatically after the code loads.
|
||||
App shell es una manera de renderizar una porción de tu aplicación a través de una ruta en tiempo de compilación (build time).
|
||||
Puede mejorar la experiencia de usuario lanzando rápidamente una página estática renderizada (un esqueleto común a todas las páginas) mientras el navegador descarga la versión completa del cliente y la muestra automáticamente al finalizar su carga.
|
||||
|
||||
This gives users a meaningful first paint of your application that appears quickly because the browser can simply render the HTML and CSS without the need to initialize any JavaScript.
|
||||
Esto da a los usuarios una primera visualización significativa de su aplicación que aparece rápidamente porque el navegador simplemente puede renderizar HTML y CSS sin la necesidad de inicializar JavaScript.
|
||||
|
||||
Learn more in [The App Shell Model](https://developers.google.com/web/fundamentals/architecture/app-shell).
|
||||
Obténga más información en [El modelo de aplicación Shell](https://developers.google.com/web/fundamentals/architecture/app-shell).
|
||||
|
||||
## Step 1: Prepare the application
|
||||
## Paso 1: Prepara la aplicación
|
||||
|
||||
You can do this with the following CLI command:
|
||||
Puedes hacer esto con el siguiente comando CLI:
|
||||
<code-example language="bash">
|
||||
ng new my-app --routing
|
||||
</code-example>
|
||||
|
||||
For an existing application, you have to manually add the `RouterModule` and defining a `<router-outlet>` within your application.
|
||||
Para una aplicación existente, debes agregar manualmente el `RouterModule` y definir un` <router-outlet> `dentro de tu aplicación.
|
||||
|
||||
## Step 2: Create the app shell
|
||||
## Paso 2: Crea el shell de la aplicación
|
||||
|
||||
Use the CLI to automatically create the app shell.
|
||||
Usa la CLI para crear automáticamente el shell de la aplicación.
|
||||
|
||||
<code-example language="bash">
|
||||
ng generate app-shell
|
||||
</code-example>
|
||||
|
||||
* `client-project` takes the name of your client application.
|
||||
* `client-project` toma el nombre de tu aplicación cliente.
|
||||
|
||||
After running this command you will notice that the `angular.json` configuration file has been updated to add two new targets, with a few other changes.
|
||||
Después de ejecutar este comando, notará que el archivo de configuración `angular.json` se ha actualizado para agregar dos nuevos targets, con algunos otros cambios.
|
||||
|
||||
<code-example language="json">
|
||||
"server": {
|
||||
@ -53,20 +53,18 @@ After running this command you will notice that the `angular.json` configuration
|
||||
}
|
||||
</code-example>
|
||||
|
||||
## Step 3: Verify the app is built with the shell content
|
||||
## Paso 3: Verifica que la aplicación está construida con el contenido del shell
|
||||
|
||||
Use the CLI to build the `app-shell` target.
|
||||
Usa la CLI para construir el `app-shell` target.
|
||||
|
||||
<code-example language="bash">
|
||||
ng run my-app:app-shell
|
||||
</code-example>
|
||||
|
||||
Or to use the production configuration.
|
||||
O usa la configuración de producción.
|
||||
|
||||
<code-example language="bash">
|
||||
ng run my-app:app-shell:production
|
||||
</code-example>
|
||||
|
||||
To verify the build output, open `dist/my-app/index.html`. Look for default text `app-shell works!` to show that the app shell route was rendered as part of the output.
|
||||
|
||||
|
||||
Para verificar el resultado de la compilación, abre `dist/my-app/index.html`. Busca el texto por defecto `app-shell works!` para mostrar que la ruta del shell de la aplicación se ha renderizado como parte de la carpeta de distribución.
|
||||
|
104
aio/content/guide/architecture-modules.en.md
Normal file
104
aio/content/guide/architecture-modules.en.md
Normal file
@ -0,0 +1,104 @@
|
||||
# Introduction to modules
|
||||
|
||||
Angular apps are modular and Angular has its own modularity system called *NgModules*.
|
||||
NgModules are containers for a cohesive block of code dedicated to an application domain, a workflow, or a closely related set of capabilities. They can contain components, service providers, and other code files whose scope is defined by the containing NgModule. They can import functionality that is exported from other NgModules, and export selected functionality for use by other NgModules.
|
||||
|
||||
Every Angular app has at least one NgModule class, [the *root module*](guide/bootstrapping), which is conventionally named `AppModule` and resides in a file named `app.module.ts`. You launch your app by *bootstrapping* the root NgModule.
|
||||
|
||||
While a small application might have only one NgModule, most apps have many more *feature modules*. The *root* NgModule for an app is so named because it can include child NgModules in a hierarchy of any depth.
|
||||
|
||||
## NgModule metadata
|
||||
|
||||
An NgModule is defined by a class decorated with `@NgModule()`. The `@NgModule()` decorator is a function that takes a single metadata object, whose properties describe the module. The most important properties are as follows.
|
||||
|
||||
* `declarations`: The [components](guide/architecture-components), *directives*, and *pipes* that belong to this NgModule.
|
||||
|
||||
* `exports`: The subset of declarations that should be visible and usable in the *component templates* of other NgModules.
|
||||
|
||||
* `imports`: Other modules whose exported classes are needed by component templates declared in *this* NgModule.
|
||||
|
||||
* `providers`: Creators of [services](guide/architecture-services) that this NgModule contributes to the global collection of services; they become accessible in all parts of the app. (You can also specify providers at the component level, which is often preferred.)
|
||||
|
||||
* `bootstrap`: The main application view, called the *root component*, which hosts all other app views. Only the *root NgModule* should set the `bootstrap` property.
|
||||
|
||||
Here's a simple root NgModule definition.
|
||||
|
||||
<code-example path="architecture/src/app/mini-app.ts" region="module" header="src/app/app.module.ts"></code-example>
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
`AppComponent` is included in the `exports` list here for illustration; it isn't actually necessary in this example. A root NgModule has no reason to *export* anything because other modules don't need to *import* the root NgModule.
|
||||
|
||||
</div>
|
||||
|
||||
## NgModules and components
|
||||
|
||||
NgModules provide a *compilation context* for their components. A root NgModule always has a root component that is created during bootstrap, but any NgModule can include any number of additional components, which can be loaded through the router or created through the template. The components that belong to an NgModule share a compilation context.
|
||||
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/architecture/compilation-context.png" alt="Component compilation context" class="left">
|
||||
</div>
|
||||
|
||||
<br class="clear">
|
||||
|
||||
A component and its template together define a *view*. A component can contain a *view hierarchy*, which allows you to define arbitrarily complex areas of the screen that can be created, modified, and destroyed as a unit. A view hierarchy can mix views defined in components that belong to different NgModules. This is often the case, especially for UI libraries.
|
||||
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/architecture/view-hierarchy.png" alt="View hierarchy" class="left">
|
||||
</div>
|
||||
|
||||
<br class="clear">
|
||||
|
||||
When you create a component, it's associated directly with a single view, called the *host view*. The host view can be the root of a view hierarchy, which can contain *embedded views*, which are in turn the host views of other components. Those components can be in the same NgModule, or can be imported from other NgModules. Views in the tree can be nested to any depth.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
**Note:** The hierarchical structure of views is a key factor in the way Angular detects and responds to changes in the DOM and app data.
|
||||
|
||||
</div>
|
||||
|
||||
## NgModules and JavaScript modules
|
||||
|
||||
The NgModule system is different from and unrelated to the JavaScript (ES2015) module system for managing collections of JavaScript objects. These are *complementary* module systems that you can use together to write your apps.
|
||||
|
||||
In JavaScript each *file* is a module and all objects defined in the file belong to that module.
|
||||
The module declares some objects to be public by marking them with the `export` key word.
|
||||
Other JavaScript modules use *import statements* to access public objects from other modules.
|
||||
|
||||
<code-example path="architecture/src/app/app.module.ts" region="imports"></code-example>
|
||||
|
||||
<code-example path="architecture/src/app/app.module.ts" region="export"></code-example>
|
||||
|
||||
<div class="alert is-helpful">
|
||||
<a href="http://exploringjs.com/es6/ch_modules.html">Learn more about the JavaScript module system on the web.</a>
|
||||
</div>
|
||||
|
||||
## Angular libraries
|
||||
|
||||
<img src="generated/images/guide/architecture/library-module.png" alt="Component" class="left">
|
||||
|
||||
Angular loads as a collection of JavaScript modules. You can think of them as library modules. Each Angular library name begins with the `@angular` prefix. Install them with the node package manager `npm` and import parts of them with JavaScript `import` statements.
|
||||
|
||||
<br class="clear">
|
||||
|
||||
For example, import Angular's `Component` decorator from the `@angular/core` library like this.
|
||||
|
||||
<code-example path="architecture/src/app/app.component.ts" region="import"></code-example>
|
||||
|
||||
You also import NgModules from Angular *libraries* using JavaScript import statements.
|
||||
For example, the following code imports the `BrowserModule` NgModule from the `platform-browser` library.
|
||||
|
||||
<code-example path="architecture/src/app/mini-app.ts" region="import-browser-module"></code-example>
|
||||
|
||||
In the example of the simple root module above, the application module needs material from within
|
||||
`BrowserModule`. To access that material, add it to the `@NgModule` metadata `imports` like this.
|
||||
|
||||
<code-example path="architecture/src/app/mini-app.ts" region="ngmodule-imports"></code-example>
|
||||
|
||||
In this way you're using the Angular and JavaScript module systems *together*. Although it's easy to confuse the two systems, which share the common vocabulary of "imports" and "exports", you will become familiar with the different contexts in which they are used.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
Learn more from the [NgModules](guide/ngmodules) guide.
|
||||
|
||||
</div>
|
@ -1,39 +1,39 @@
|
||||
# Introduction to modules
|
||||
# Introducción a módulos
|
||||
|
||||
Angular apps are modular and Angular has its own modularity system called *NgModules*.
|
||||
NgModules are containers for a cohesive block of code dedicated to an application domain, a workflow, or a closely related set of capabilities. They can contain components, service providers, and other code files whose scope is defined by the containing NgModule. They can import functionality that is exported from other NgModules, and export selected functionality for use by other NgModules.
|
||||
Las aplicaciones Angular son modulares y Angular tiene su propio sistema de modularidad llamado *NgModules*.
|
||||
Los NgModules son contenedores para un bloque cohesivo de código dedicado a un dominio de aplicación, un flujo de trabajo o un conjunto de capacidades estrechamente relacionadas. Pueden contener componentes, proveedores de servicios y otros archivos de código cuyo alcance está definido por el NgModule que los contiene. Pueden importar la funcionalidad que se exporta desde otros NgModules y exportar la funcionalidad seleccionada para que la utilicen otros NgModules.
|
||||
|
||||
Every Angular app has at least one NgModule class, [the *root module*](guide/bootstrapping), which is conventionally named `AppModule` and resides in a file named `app.module.ts`. You launch your app by *bootstrapping* the root NgModule.
|
||||
Cada aplicación Angular tiene al menos una clase NgModule, [el *módulo raíz*](guide/bootstrapping), que se llama convencionalmente `AppModule` y reside en un archivo llamado `app.module.ts`. Inicia tu aplicación *cargando* el NgModule raíz.
|
||||
|
||||
While a small application might have only one NgModule, most apps have many more *feature modules*. The *root* NgModule for an app is so named because it can include child NgModules in a hierarchy of any depth.
|
||||
Si bien una aplicación pequeña puede tener sólo un NgModule, la mayoría de las aplicaciones tienen muchos más *módulos de funcionalidad*. El NgModule *raíz* para una aplicación se llama así porque puede incluir NgModules secundarios en una jerarquía de cualquier profundidad.
|
||||
|
||||
## NgModule metadata
|
||||
## Metadatos de NgModule
|
||||
|
||||
An NgModule is defined by a class decorated with `@NgModule()`. The `@NgModule()` decorator is a function that takes a single metadata object, whose properties describe the module. The most important properties are as follows.
|
||||
Un NgModule está definido por una clase decorada con `@NgModule()`. El decorador `@NgModule()` es una función que toma un único objeto de metadatos, cuyas propiedades describen el módulo. Las propiedades más importantes son las siguientes.
|
||||
|
||||
* `declarations`: The [components](guide/architecture-components), *directives*, and *pipes* that belong to this NgModule.
|
||||
* `declarations`: Los [componentes](guide/architecture-components), *directivas*, y *pipes* que pertenecen a este NgModule.
|
||||
|
||||
* `exports`: The subset of declarations that should be visible and usable in the *component templates* of other NgModules.
|
||||
* `exports`: El subconjunto de declaraciones que deberían ser visibles y utilizables en las *plantillas de componentes* de otros NgModules.
|
||||
|
||||
* `imports`: Other modules whose exported classes are needed by component templates declared in *this* NgModule.
|
||||
* `imports`: Otros módulos cuyas clases exportadas son necesarias para las plantillas de componentes declaradas en *este* NgModule.
|
||||
|
||||
* `providers`: Creators of [services](guide/architecture-services) that this NgModule contributes to the global collection of services; they become accessible in all parts of the app. (You can also specify providers at the component level, which is often preferred.)
|
||||
* `providers`: Creadores de [servicios](guide/architecture-services) que este NgModule aporta a la colección global de servicios; se vuelven accesibles en todas las partes de la aplicación. (También puedes especificar proveedores a nivel de componente, que a menudo es preferido).
|
||||
|
||||
* `bootstrap`: The main application view, called the *root component*, which hosts all other app views. Only the *root NgModule* should set the `bootstrap` property.
|
||||
* `bootstrap`: La vista principal de la aplicación, llamado el *componente raíz*, que aloja todas las demás vistas de la aplicación. Sólo el *NgModule raíz* debe establecer la propiedad `bootstrap`.
|
||||
|
||||
Here's a simple root NgModule definition.
|
||||
Aquí hay una definición simple del NgModule raíz.
|
||||
|
||||
<code-example path="architecture/src/app/mini-app.ts" region="module" header="src/app/app.module.ts"></code-example>
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
`AppComponent` is included in the `exports` list here for illustration; it isn't actually necessary in this example. A root NgModule has no reason to *export* anything because other modules don't need to *import* the root NgModule.
|
||||
Aquí se incluye `AppComponent` en la lista de `exports` como ilustración; en realidad no es necesario en este ejemplo. Un NgModule raíz no tiene ninguna razón para *exportar* nada porque otros módulos no necesitan *importar* el NgModule raíz.
|
||||
|
||||
</div>
|
||||
|
||||
## NgModules and components
|
||||
## NgModules y componentes
|
||||
|
||||
NgModules provide a *compilation context* for their components. A root NgModule always has a root component that is created during bootstrap, but any NgModule can include any number of additional components, which can be loaded through the router or created through the template. The components that belong to an NgModule share a compilation context.
|
||||
NgModules proporciona un *contexto de compilación* para sus componentes. Un NgModule raíz siempre tiene un componente raíz que se crea durante el arranque, pero cualquier NgModule puede incluir cualquier cantidad de componentes adicionales, que se pueden cargar a través del enrutador o crear a través de la plantilla. Los componentes que pertenecen a un NgModule comparten un contexto de compilación.
|
||||
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/architecture/compilation-context.png" alt="Component compilation context" class="left">
|
||||
@ -41,7 +41,7 @@ NgModules provide a *compilation context* for their components. A root NgModule
|
||||
|
||||
<br class="clear">
|
||||
|
||||
A component and its template together define a *view*. A component can contain a *view hierarchy*, which allows you to define arbitrarily complex areas of the screen that can be created, modified, and destroyed as a unit. A view hierarchy can mix views defined in components that belong to different NgModules. This is often the case, especially for UI libraries.
|
||||
Juntos, un componente y su plantilla definen una *vista*. Un componente puede contener una *jerarquía de vista*, que te permiten definir áreas arbitrariamente complejas de la pantalla que se pueden crear, modificar y destruir como una unidad. Una jerarquía de vistas puede mezclar vistas definidas en componentes que pertenecen a diferentes NgModules. Este suele ser el caso, especialmente para las bibliotecas de interfaz de usuario.
|
||||
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/architecture/view-hierarchy.png" alt="View hierarchy" class="left">
|
||||
@ -49,56 +49,56 @@ A component and its template together define a *view*. A component can contain a
|
||||
|
||||
<br class="clear">
|
||||
|
||||
When you create a component, it's associated directly with a single view, called the *host view*. The host view can be the root of a view hierarchy, which can contain *embedded views*, which are in turn the host views of other components. Those components can be in the same NgModule, or can be imported from other NgModules. Views in the tree can be nested to any depth.
|
||||
Cuando creas un componente, se asocia directamente con una sola vista, llamada *vista host*. La vista host puede ser la raíz de una jerarquía de vistas, que puede contener *vistas incrustadas*, que a su vez son las vistas de host de otros componentes. Esos componentes pueden estar en el mismo NgModule o pueden importarse desde otros NgModules. Las vistas en el árbol se pueden anidar a cualquier profundidad.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
**Note:** The hierarchical structure of views is a key factor in the way Angular detects and responds to changes in the DOM and app data.
|
||||
**Nota:** La estructura jerárquica de las vistas es un factor clave en la forma en que Angular detecta y responde a los cambios en el DOM y los datos de la aplicación.
|
||||
|
||||
</div>
|
||||
|
||||
## NgModules and JavaScript modules
|
||||
## NgModules y módulos JavaScript
|
||||
|
||||
The NgModule system is different from and unrelated to the JavaScript (ES2015) module system for managing collections of JavaScript objects. These are *complementary* module systems that you can use together to write your apps.
|
||||
El sistema NgModule es diferente y no está relacionado con el sistema de módulos JavaScript (ES2015) para administrar colecciones de objetos JavaScript. Estos son sistemas de módulos *complementarios* que puedes usar juntos para escribir tus aplicaciones.
|
||||
|
||||
In JavaScript each *file* is a module and all objects defined in the file belong to that module.
|
||||
The module declares some objects to be public by marking them with the `export` key word.
|
||||
Other JavaScript modules use *import statements* to access public objects from other modules.
|
||||
En JavaScript, cada *archivo* es un módulo y todos los objetos definidos en el archivo pertenecen a ese módulo.
|
||||
El módulo declara que algunos objetos son públicos marcándolos con la palabra clave `export`.
|
||||
Otros módulos de JavaScript usan *declaraciones de importación* para acceder a objetos públicos de otros módulos.
|
||||
|
||||
<code-example path="architecture/src/app/app.module.ts" region="imports"></code-example>
|
||||
|
||||
<code-example path="architecture/src/app/app.module.ts" region="export"></code-example>
|
||||
|
||||
<div class="alert is-helpful">
|
||||
<a href="http://exploringjs.com/es6/ch_modules.html">Learn more about the JavaScript module system on the web.</a>
|
||||
<a href="http://exploringjs.com/es6/ch_modules.html">Obtén más información sobre el sistema de módulos de JavaScript en la web.</a>
|
||||
</div>
|
||||
|
||||
## Angular libraries
|
||||
## Bibliotecas Angular
|
||||
|
||||
<img src="generated/images/guide/architecture/library-module.png" alt="Component" class="left">
|
||||
|
||||
Angular loads as a collection of JavaScript modules. You can think of them as library modules. Each Angular library name begins with the `@angular` prefix. Install them with the node package manager `npm` and import parts of them with JavaScript `import` statements.
|
||||
Angular se carga como una colección de módulos JavaScript. Puedes pensar en ellos como módulos de biblioteca. Cada nombre de biblioteca de Angular comienza con el prefijo `@angular`. Instálalos con el gestor de paquetes `npm` e importa partes de ellos con declaraciones `import` de JavaScript.
|
||||
|
||||
<br class="clear">
|
||||
|
||||
For example, import Angular's `Component` decorator from the `@angular/core` library like this.
|
||||
Por ejemplo, importa el decorador `Component` de Angular de la biblioteca `@angular/core` como esta.
|
||||
|
||||
<code-example path="architecture/src/app/app.component.ts" region="import"></code-example>
|
||||
|
||||
You also import NgModules from Angular *libraries* using JavaScript import statements.
|
||||
For example, the following code imports the `BrowserModule` NgModule from the `platform-browser` library.
|
||||
También importa NgModules desde las *bibliotecas* Angular usando declaraciones de importación de JavaScript.
|
||||
Por ejemplo, el siguiente código importa el NgModule `BrowserModule` de la biblioteca `platform-browser`.
|
||||
|
||||
<code-example path="architecture/src/app/mini-app.ts" region="import-browser-module"></code-example>
|
||||
|
||||
In the example of the simple root module above, the application module needs material from within
|
||||
`BrowserModule`. To access that material, add it to the `@NgModule` metadata `imports` like this.
|
||||
En el ejemplo del módulo raíz simple anterior, el módulo de la aplicación necesita material de
|
||||
`BrowserModule`. Para acceder a ese material, agrégalo a los metadatos `imports` de `@NgModule` de esta manera.
|
||||
|
||||
<code-example path="architecture/src/app/mini-app.ts" region="ngmodule-imports"></code-example>
|
||||
|
||||
In this way you're using the Angular and JavaScript module systems *together*. Although it's easy to confuse the two systems, which share the common vocabulary of "imports" and "exports", you will become familiar with the different contexts in which they are used.
|
||||
De esta manera, estás utilizando los sistemas de módulos Angular y JavaScript *juntos*. Aunque es fácil confundir los dos sistemas, que comparten el vocabulario común de "importaciones" y "exportaciones", te familiarizarás con los diferentes contextos en los que se utilizan.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
Learn more from the [NgModules](guide/ngmodules) guide.
|
||||
Obtén más información en la guía [NgModules](guide/ngmodules).
|
||||
|
||||
</div>
|
||||
|
90
aio/content/guide/architecture-next-steps.en.md
Normal file
90
aio/content/guide/architecture-next-steps.en.md
Normal file
@ -0,0 +1,90 @@
|
||||
# Next steps: tools and techniques
|
||||
|
||||
After you understand the basic Angular building blocks, you can learn more
|
||||
about the features and tools that can help you develop and deliver Angular applications.
|
||||
|
||||
* Work through the [Tour of Heroes](tutorial) tutorial to get a feel for how to fit the basic building blocks together to create a well-designed application.
|
||||
|
||||
* Check out the [Glossary](guide/glossary) to understand Angular-specific terms and usage.
|
||||
|
||||
* Use the documentation to learn about key features in more depth, according to your stage of development and areas of interest.
|
||||
|
||||
## Application architecture
|
||||
|
||||
* The [Components and templates](guide/displaying-data) guide explains how to connect the application data in your [components](guide/glossary#component) to your page-display [templates](guide/glossary#template), to create a complete interactive application.
|
||||
|
||||
* The [NgModules](guide/ngmodules) guide provides in-depth information on the modular structure of an Angular application.
|
||||
|
||||
* The [Routing and navigation](guide/router) guide provides in-depth information on how to construct applications that allow a user to navigate to different [views](guide/glossary#view) within your single-page app.
|
||||
|
||||
* The [Dependency injection](guide/dependency-injection) guide provides in-depth information on how to construct an application such that each component class can acquire the services and objects it needs to perform its function.
|
||||
|
||||
## Responsive programming
|
||||
|
||||
The **Components and Templates** guide provides guidance and details of the [template syntax](guide/template-syntax) that you use to display your component data when and where you want it within a view, and to collect input from users that you can respond to.
|
||||
|
||||
Additional pages and sections describe some basic programming techniques for Angular apps.
|
||||
|
||||
* [Lifecycle hooks](guide/lifecycle-hooks): Tap into key moments in the lifetime of a component, from its creation to its destruction, by implementing the lifecycle hook interfaces.
|
||||
|
||||
* [Observables and event processing](guide/observables): How to use observables with components and services to publish and subscribe to messages of any type, such as user-interaction events and asynchronous operation results.
|
||||
|
||||
* [Angular elements](guide/elements): How to package components as *custom elements* using Web Components, a web standard for defining new HTML elements in a framework-agnostic way.
|
||||
|
||||
* [Forms](guide/forms-overview): Support complex data entry scenarios with HTML-based input validation.
|
||||
|
||||
* [Animations](guide/animations): Use Angular's animation library to animate component behavior
|
||||
without deep knowledge of animation techniques or CSS.
|
||||
|
||||
## Client-server interaction
|
||||
|
||||
Angular provides a framework for single-page apps, where most of the logic and data resides on the client.
|
||||
Most apps still need to access a server using the `HttpClient` to access and save data.
|
||||
For some platforms and applications, you might also want to use the PWA (Progressive Web App) model to improve the user experience.
|
||||
|
||||
* [HTTP](guide/http): Communicate with a server to get data, save data, and invoke server-side actions with an HTTP client.
|
||||
|
||||
* [Server-side rendering](guide/universal): Angular Universal generates static application pages on the server through server-side rendering (SSR). This allows you to run your Angular app on the server in order to improve performance and show the first page quickly on mobile and low-powered devices, and also facilitate web crawlers.
|
||||
|
||||
* [Service workers and PWA](guide/service-worker-intro): Use a service worker to reduce dependency on the network and significantly improve the user experience.
|
||||
|
||||
* [Web workers](guide/web-worker): Learn how to run CPU-intensive computations in a background thread.
|
||||
|
||||
## Support for the development cycle
|
||||
|
||||
The **Development Workflow** section describes the tools and processes you use to compile, test, and deploy Angular applications.
|
||||
|
||||
* [CLI Command Reference](cli): The Angular CLI is a command-line tool that you use to create projects, generate application and library code, and perform a variety of ongoing development tasks such as testing, bundling, and deployment.
|
||||
|
||||
* [Compilation](guide/aot-compiler): Angular provides just-in-time (JIT) compilation for the development environment, and ahead-of-time (AOT) compilation for the production environment.
|
||||
|
||||
* [Testing platform](guide/testing): Run unit tests on your application parts as they interact with the Angular framework.
|
||||
|
||||
* [Deployment](guide/deployment): Learn techniques for deploying your Angular application to a remote server.
|
||||
|
||||
* [Security guidelines](guide/security): Learn about Angular's built-in protections against common web-app vulnerabilities and attacks such as cross-site scripting attacks.
|
||||
|
||||
* [Internationalization](guide/i18n): Make your app available in multiple languages with Angular's internationalization (i18n) tools.
|
||||
|
||||
* [Accessibility](guide/accessibility): Make your app accessible to all users.
|
||||
|
||||
|
||||
## File structure, configuration, and dependencies
|
||||
|
||||
* [Workspace and file structure](guide/file-structure): Understand the structure of Angular workspace and project folders.
|
||||
|
||||
* [Building and serving](guide/build): Learn to define different build and proxy server configurations for your project, such as development, staging, and production.
|
||||
|
||||
* [npm packages](guide/npm-packages): The Angular Framework, Angular CLI, and components used by Angular applications are packaged as [npm](https://docs.npmjs.com/) packages and distributed via the npm registry. The Angular CLI creates a default `package.json` file, which specifies a starter set of packages that work well together and jointly support many common application scenarios.
|
||||
|
||||
* [TypeScript configuration](guide/typescript-configuration): TypeScript is the primary language for Angular application development.
|
||||
|
||||
* [Browser support](guide/browser-support): Make your apps compatible across a wide range of browsers.
|
||||
|
||||
## Extending Angular
|
||||
|
||||
* [Angular libraries](guide/libraries): Learn about using and creating re-usable libraries.
|
||||
|
||||
* [Schematics](guide/schematics): Learn about customizing and extending the CLI's generation capabilities.
|
||||
|
||||
* [CLI builders](guide/cli-builder): Learn about customizing and extending the CLI's ability to apply tools to perform complex tasks, such as building and testing applications.
|
@ -1,90 +1,88 @@
|
||||
# Next steps: tools and techniques
|
||||
# Próximos Pasos: Herramientas y Técnicas
|
||||
|
||||
After you understand the basic Angular building blocks, you can learn more
|
||||
about the features and tools that can help you develop and deliver Angular applications.
|
||||
Una vez que comprendas los conceptos básicos de Angular, puedes aprender más sobre las funcionalidades y herramientas que pueden ayudarte a desarrollar y entregar aplicaciones Angular.
|
||||
|
||||
* Work through the [Tour of Heroes](tutorial) tutorial to get a feel for how to fit the basic building blocks together to create a well-designed application.
|
||||
* Realiza el tutorial [Tour de Héroes](tutorial) para familiarizarte con los conceptos básicos necesarios para crear una aplicación bien diseñada.
|
||||
|
||||
* Check out the [Glossary](guide/glossary) to understand Angular-specific terms and usage.
|
||||
* Consulta el [Glosario](guide/glossary) para comprender los términos específicos de Angular y su correspondiente utilización.
|
||||
|
||||
* Use the documentation to learn about key features in more depth, according to your stage of development and areas of interest.
|
||||
* Utiliza la documentación te permite conocer en detalle las funcionalidades claves, según tu etapa de desarrollo y tus áreas de interés.
|
||||
|
||||
## Application architecture
|
||||
## Arquitectura de la aplicación
|
||||
|
||||
* The [Components and templates](guide/displaying-data) guide explains how to connect the application data in your [components](guide/glossary#component) to your page-display [templates](guide/glossary#template), to create a complete interactive application.
|
||||
* La guía de [Componentes y Plantillas](guide/displaying-data) explica como conectar los datos de la aplicación de sus [componentes](guide/glossary#componente) con las [plantillas](guide/glossary#plantilla) de las pantallas, para crear una aplicación completamente interactiva.
|
||||
|
||||
* The [NgModules](guide/ngmodules) guide provides in-depth information on the modular structure of an Angular application.
|
||||
* La guía de [NgModules](guide/ngmodules) proporciona información detallada sobre la estructura de módulos utilizada en una aplicación Angular.
|
||||
|
||||
* The [Routing and navigation](guide/router) guide provides in-depth information on how to construct applications that allow a user to navigate to different [views](guide/glossary#view) within your single-page app.
|
||||
* La guía de [Enrutamiento y navigación](guide/router) describe como crear aplicaciones que permitan al usuario navegar entre las diferentes [vistas](guide/glossary#vista) dentro de su aplicación de una sola página (SPA).
|
||||
|
||||
* The [Dependency injection](guide/dependency-injection) guide provides in-depth information on how to construct an application such that each component class can acquire the services and objects it needs to perform its function.
|
||||
* La guía de [Injección de dependencias](guide/dependency-injection) brinda información detallada sobre cómo construir una aplicación de modo que cada clase de componente pueda adquirir los servicios y objetos que necesita para realizar su función.
|
||||
|
||||
## Responsive programming
|
||||
## Programación responsive
|
||||
|
||||
The **Components and Templates** guide provides guidance and details of the [template syntax](guide/template-syntax) that you use to display your component data when and where you want it within a view, and to collect input from users that you can respond to.
|
||||
La guía de **Componentes y Plantillas** brinda orientación y detalles de la [sintaxis de plantilla](guide/template-syntax) que se utilizan para mostrar la información de sus componentes, cuando y donde lo desees dentro de una vista y para obtener entradas (inputs) de los usuarios a las que puedas responder.
|
||||
|
||||
Additional pages and sections describe some basic programming techniques for Angular apps.
|
||||
Las páginas y secciones adicionales describen algunas técnicas básicas de programación para aplicaciones Angular.
|
||||
|
||||
* [Lifecycle hooks](guide/lifecycle-hooks): Tap into key moments in the lifetime of a component, from its creation to its destruction, by implementing the lifecycle hook interfaces.
|
||||
* [Lifecycle Hooks](guide/lifecycle-hooks): Aprovecha los momentos claves de la vida de un componente, desde su creación hasta su destrucción, implementando las interfaces de los `lifecycle hooks`.
|
||||
|
||||
* [Observables and event processing](guide/observables): How to use observables with components and services to publish and subscribe to messages of any type, such as user-interaction events and asynchronous operation results.
|
||||
* [Observables y procesamiento de eventos](guide/observables): Cómo utilizar observables con componentes y servicios para publicar y suscribirse a mensajes de cualquier tipo, tales como los eventos de interacción del usuario y los resultados de operaciones asincrónicas.
|
||||
|
||||
* [Angular elements](guide/elements): How to package components as *custom elements* using Web Components, a web standard for defining new HTML elements in a framework-agnostic way.
|
||||
* [Elementos Angular](guide/elements): Cómo empaquetar componentes como *elementos personalizados* utilizando Web Components, un estándar web para definir nuevos elementos HTML de una manera agnóstica a cualquier framework.
|
||||
|
||||
* [Forms](guide/forms-overview): Support complex data entry scenarios with HTML-based input validation.
|
||||
* [Formularios](guide/forms-overview): Soporta escenarios complejos de entrada de datos con validación de entradas (inputs) basadas en HTML.
|
||||
|
||||
* [Animations](guide/animations): Use Angular's animation library to animate component behavior
|
||||
without deep knowledge of animation techniques or CSS.
|
||||
* [Animaciones](guide/animations): Utiliza la librería de animación de Angular para animar el comportamiento de los componentes sin necesidad de conocer en profundidad las técnicas de animación o CSS.
|
||||
|
||||
## Client-server interaction
|
||||
## Interacción Cliente-Servidor
|
||||
|
||||
Angular provides a framework for single-page apps, where most of the logic and data resides on the client.
|
||||
Most apps still need to access a server using the `HttpClient` to access and save data.
|
||||
For some platforms and applications, you might also want to use the PWA (Progressive Web App) model to improve the user experience.
|
||||
Angular ofrece un framework para aplicaciones de una sola página (SPA), donde la mayoría de la lógica y los datos se encuentran en el cliente.
|
||||
La mayoría de las aplicaciones todavía necesitan acceder a un servidor usando el `HttpClient` para acceder y guardar datos.
|
||||
Para algunas plataformas y aplicaciones, se puede también querer utilizar el modelo PWA (Aplicaciones Web Progresivas) para mejorar la experiencia de usuario.
|
||||
|
||||
* [HTTP](guide/http): Communicate with a server to get data, save data, and invoke server-side actions with an HTTP client.
|
||||
* [HTTP](guide/http): Comunícate con un servidor para obtener datos, guardarlos e invocar acciones del lado del servidor con un cliente HTTP.
|
||||
|
||||
* [Server-side rendering](guide/universal): Angular Universal generates static application pages on the server through server-side rendering (SSR). This allows you to run your Angular app on the server in order to improve performance and show the first page quickly on mobile and low-powered devices, and also facilitate web crawlers.
|
||||
* [Renderizado del lado del servidor](guide/universal): Angular Universal genera páginas de aplicación estáticas en el servidor a través de la renderización del lado del servidor (SSR). Esto te permite ejecutar tu aplicación Angular en el servidor para mejorar el rendimiento y mostrar la primera página rápidamente en dispositivos móviles y de baja potencia, y también facilitar los rastreadores web.
|
||||
|
||||
* [Service workers and PWA](guide/service-worker-intro): Use a service worker to reduce dependency on the network and significantly improve the user experience.
|
||||
* [Service workers y PWA](guide/service-worker-intro): Utiliza un service worker para reducir la dependencia de la red y mejorar significativamente la experiencia del usuario.
|
||||
|
||||
* [Web workers](guide/web-worker): Learn how to run CPU-intensive computations in a background thread.
|
||||
* [Web workers](guide/web-worker): Aprende a ejecutar cálculos con uso intensivo de la CPU en un hilo en segundo plano.
|
||||
|
||||
## Support for the development cycle
|
||||
## Soporte del Ciclo de Desarrollo
|
||||
|
||||
The **Development Workflow** section describes the tools and processes you use to compile, test, and deploy Angular applications.
|
||||
La sección **Workflow de Desarrollo** detalla las herramientas y los procesos utilizados para compilar, probar y desplegar aplicaciones Angular.
|
||||
|
||||
* [CLI Command Reference](cli): The Angular CLI is a command-line tool that you use to create projects, generate application and library code, and perform a variety of ongoing development tasks such as testing, bundling, and deployment.
|
||||
* [CLI Referencia de Comando](cli): La CLI de Angular es una interfaz de línea de comandos utilizada para crear proyectos, generar código de aplicaciones y librerías y realizar un conjunto de tareas de desarrollo tales como pruebas, empaquetamiento y despliegue de aplicaciones.
|
||||
|
||||
* [Compilation](guide/aot-compiler): Angular provides just-in-time (JIT) compilation for the development environment, and ahead-of-time (AOT) compilation for the production environment.
|
||||
* [Compilación](guide/aot-compiler): Angular proporciona compilación `just-in-time` (JIT) para el entorno de desarrollo y compilación `ahead-of-time` (AOT) para el entorno de producción.
|
||||
|
||||
* [Testing platform](guide/testing): Run unit tests on your application parts as they interact with the Angular framework.
|
||||
* [Plataforma de pruebas](guide/testing): Ejecuta pruebas unitarias sobre las distintas partes de tu aplicación a medida que interactúan con el framework de Angular.
|
||||
|
||||
* [Deployment](guide/deployment): Learn techniques for deploying your Angular application to a remote server.
|
||||
* [Despliegue](guide/deployment): Aprende técnicas para desplegar tu aplicación Angular en un servidor remoto.
|
||||
|
||||
* [Security guidelines](guide/security): Learn about Angular's built-in protections against common web-app vulnerabilities and attacks such as cross-site scripting attacks.
|
||||
* [Lineamientos de Seguridad](guide/security): Aprende sobre las protecciones integradas por Angular contra las vulnerabilidades y los ataques comunes a las aplicaciones web, como por ejemplo, ataques de cross-site scripting.
|
||||
|
||||
* [Internationalization](guide/i18n): Make your app available in multiple languages with Angular's internationalization (i18n) tools.
|
||||
* [Internacionalización](guide/i18n): Haz que tu aplicación soporte múltiples lenguajes con las herramientas de internacionalización de Angular (i18n).
|
||||
|
||||
* [Accessibility](guide/accessibility): Make your app accessible to all users.
|
||||
* [Accesibilidad](guide/accessibility): Haz que tu aplicación sea accesible a todos los usuarios.
|
||||
|
||||
|
||||
## File structure, configuration, and dependencies
|
||||
## Estructura de Archivos, Configuración y Dependencias
|
||||
|
||||
* [Workspace and file structure](guide/file-structure): Understand the structure of Angular workspace and project folders.
|
||||
* [Espacio de trabajo y estructura de archivos](guide/file-structure): Comprende la estructura del espacio de trabajo y las carpetas de proyectos en Angular.
|
||||
|
||||
* [Building and serving](guide/build): Learn to define different build and proxy server configurations for your project, such as development, staging, and production.
|
||||
* [Construcción y servicio](guide/build): Aprende a definir diferentes configuraciones de servidores proxy y construcción para tu proyecto, como por ejemplo desarrollo, staging y producción.
|
||||
|
||||
* [npm packages](guide/npm-packages): The Angular Framework, Angular CLI, and components used by Angular applications are packaged as [npm](https://docs.npmjs.com/) packages and distributed via the npm registry. The Angular CLI creates a default `package.json` file, which specifies a starter set of packages that work well together and jointly support many common application scenarios.
|
||||
* [Paquetes npm](guide/npm-packages): El Framework de Angular, la CLI de Angular y los componentes usados por las aplicaciones Angular se empaquetan como paquetes [npm](https://docs.npmjs.com/) y se distribuyen a través del registro de `npm`. La CLI de Angular crea por defecto un archivo `package.json`, que especifica un conjunto inicial de paquetes que funcionan bien en conjunto y dan soporte a muchos escenarios de aplicaciones comunes.
|
||||
|
||||
* [TypeScript configuration](guide/typescript-configuration): TypeScript is the primary language for Angular application development.
|
||||
* [Configuración de Typescript](guide/typescript-configuration): TypeScript es el lenguaje principal utilizado para el desarrollo de aplicaciones Angular.
|
||||
|
||||
* [Browser support](guide/browser-support): Make your apps compatible across a wide range of browsers.
|
||||
* [Soporte de Navegadores](guide/browser-support): Haz que tus aplicaciones sean compatibles en una amplia gama de navegadores.
|
||||
|
||||
## Extending Angular
|
||||
## Extendiendo Angular
|
||||
|
||||
* [Angular libraries](guide/libraries): Learn about using and creating re-usable libraries.
|
||||
* [Librerías Angular](guide/libraries): Aprende a usar y crear librerías reutilizables.
|
||||
|
||||
* [Schematics](guide/schematics): Learn about customizing and extending the CLI's generation capabilities.
|
||||
* [Esquemas](guide/schematics): Aprende como personalizar y extender las capacidades de generación de la CLI.
|
||||
|
||||
* [CLI builders](guide/cli-builder): Learn about customizing and extending the CLI's ability to apply tools to perform complex tasks, such as building and testing applications.
|
||||
* [Constructores de la CLI](guide/cli-builder): Aprende a personalizar y extender la capacidad de la CLI de aplicar herramientas para realizar tareas complejas, como la construcción y pruebas de aplicaciones.
|
||||
|
116
aio/content/guide/architecture-services.en.md
Normal file
116
aio/content/guide/architecture-services.en.md
Normal file
@ -0,0 +1,116 @@
|
||||
# Introduction to services and dependency injection
|
||||
|
||||
*Service* is a broad category encompassing any value, function, or feature that an app needs.
|
||||
A service is typically a class with a narrow, well-defined purpose.
|
||||
It should do something specific and do it well.
|
||||
|
||||
Angular distinguishes components from services to increase modularity and reusability.
|
||||
By separating a component's view-related functionality from other kinds of processing,
|
||||
you can make your component classes lean and efficient.
|
||||
|
||||
Ideally, a component's job is to enable the user experience and nothing more.
|
||||
A component should present properties and methods for data binding,
|
||||
in order to mediate between the view (rendered by the template)
|
||||
and the application logic (which often includes some notion of a *model*).
|
||||
|
||||
A component can delegate certain tasks to services, such as fetching data from the server,
|
||||
validating user input, or logging directly to the console.
|
||||
By defining such processing tasks in an *injectable service class*, you make those tasks
|
||||
available to any component.
|
||||
You can also make your app more adaptable by injecting different providers of the same kind of service,
|
||||
as appropriate in different circumstances.
|
||||
|
||||
Angular doesn't *enforce* these principles. Angular does help you *follow* these principles
|
||||
by making it easy to factor your application logic into services and make those services
|
||||
available to components through *dependency injection*.
|
||||
|
||||
## Service examples
|
||||
|
||||
Here's an example of a service class that logs to the browser console.
|
||||
|
||||
<code-example path="architecture/src/app/logger.service.ts" header="src/app/logger.service.ts (class)" region="class"></code-example>
|
||||
|
||||
Services can depend on other services. For example, here's a `HeroService` that depends on the `Logger` service, and also uses `BackendService` to get heroes. That service in turn might depend on the `HttpClient` service to fetch heroes asynchronously from a server.
|
||||
|
||||
<code-example path="architecture/src/app/hero.service.ts" header="src/app/hero.service.ts (class)" region="class"></code-example>
|
||||
|
||||
## Dependency injection (DI)
|
||||
|
||||
<img src="generated/images/guide/architecture/dependency-injection.png" alt="Service" class="left">
|
||||
|
||||
DI is wired into the Angular framework and used everywhere to provide new components with the services or other things they need.
|
||||
Components consume services; that is, you can *inject* a service into a component, giving the component access to that service class.
|
||||
|
||||
To define a class as a service in Angular, use the `@Injectable()` decorator to provide the metadata that allows Angular to inject it into a component as a *dependency*.
|
||||
Similarly, use the `@Injectable()` decorator to indicate that a component or other class (such as another service, a pipe, or an NgModule) *has* a dependency.
|
||||
|
||||
* The *injector* is the main mechanism. Angular creates an application-wide injector for you during the bootstrap process, and additional injectors as needed. You don't have to create injectors.
|
||||
|
||||
* An injector creates dependencies, and maintains a *container* of dependency instances that it reuses if possible.
|
||||
|
||||
* A *provider* is an object that tells an injector how to obtain or create a dependency.
|
||||
|
||||
For any dependency that you need in your app, you must register a provider with the app's injector,
|
||||
so that the injector can use the provider to create new instances.
|
||||
For a service, the provider is typically the service class itself.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
A dependency doesn't have to be a service—it could be a function, for example, or a value.
|
||||
|
||||
</div>
|
||||
|
||||
When Angular creates a new instance of a component class, it determines which services or other dependencies that component needs by looking at the constructor parameter types. For example, the constructor of `HeroListComponent` needs `HeroService`.
|
||||
|
||||
<code-example path="architecture/src/app/hero-list.component.ts" header="src/app/hero-list.component.ts (constructor)" region="ctor"></code-example>
|
||||
|
||||
When Angular discovers that a component depends on a service, it first checks if the injector has any existing instances of that service. If a requested service instance doesn't yet exist, the injector makes one using the registered provider, and adds it to the injector before returning the service to Angular.
|
||||
|
||||
When all requested services have been resolved and returned, Angular can call the component's constructor with those services as arguments.
|
||||
|
||||
The process of `HeroService` injection looks something like this.
|
||||
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/architecture/injector-injects.png" alt="Service" class="left">
|
||||
</div>
|
||||
|
||||
### Providing services
|
||||
|
||||
You must register at least one *provider* of any service you are going to use.
|
||||
The provider can be part of the service's own metadata, making that service available everywhere,
|
||||
or you can register providers with specific modules or components.
|
||||
You register providers in the metadata of the service (in the `@Injectable()` decorator),
|
||||
or in the `@NgModule()` or `@Component()` metadata
|
||||
|
||||
* By default, the Angular CLI command [`ng generate service`](cli/generate) registers a provider with the root injector for your service by including provider metadata in the `@Injectable()` decorator. The tutorial uses this method to register the provider of HeroService class definition.
|
||||
|
||||
```
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
```
|
||||
|
||||
When you provide the service at the root level, Angular creates a single, shared instance of `HeroService`
|
||||
and injects it into any class that asks for it.
|
||||
Registering the provider in the `@Injectable()` metadata also allows Angular to optimize an app
|
||||
by removing the service from the compiled app if it isn't used.
|
||||
|
||||
* When you register a provider with a [specific NgModule](guide/architecture-modules), the same instance of a service is available to all components in that NgModule. To register at this level, use the `providers` property of the `@NgModule()` decorator,
|
||||
|
||||
```
|
||||
@NgModule({
|
||||
providers: [
|
||||
BackendService,
|
||||
Logger
|
||||
],
|
||||
...
|
||||
})
|
||||
```
|
||||
|
||||
* When you register a provider at the component level, you get a new instance of the
|
||||
service with each new instance of that component.
|
||||
At the component level, register a service provider in the `providers` property of the `@Component()` metadata.
|
||||
|
||||
<code-example path="architecture/src/app/hero-list.component.ts" header="src/app/hero-list.component.ts (component providers)" region="providers"></code-example>
|
||||
|
||||
For more detailed information, see the [Dependency Injection](guide/dependency-injection) section.
|
@ -1,88 +1,81 @@
|
||||
# Introduction to services and dependency injection
|
||||
# Introducción a servicios e inyección de dependencias
|
||||
|
||||
*Service* is a broad category encompassing any value, function, or feature that an app needs.
|
||||
A service is typically a class with a narrow, well-defined purpose.
|
||||
It should do something specific and do it well.
|
||||
*Servicio* es una categoría amplia que abarca cualquier valor, función o característica que necesite una aplicación.
|
||||
Un servicio es típicamente una clase con un propósito limitado y bien definido.
|
||||
Debe hacer algo específico y hacerlo bien.
|
||||
|
||||
Angular distinguishes components from services to increase modularity and reusability.
|
||||
By separating a component's view-related functionality from other kinds of processing,
|
||||
you can make your component classes lean and efficient.
|
||||
Angular distingue los componentes de los servicios para aumentar la modularidad y la reutilización.
|
||||
Al separar la funcionalidad relacionada con la vista de un componente de otros tipos de procesamiento, puedes hacer que tus componentes sean ágiles y eficientes.
|
||||
|
||||
Ideally, a component's job is to enable the user experience and nothing more.
|
||||
A component should present properties and methods for data binding,
|
||||
in order to mediate between the view (rendered by the template)
|
||||
and the application logic (which often includes some notion of a *model*).
|
||||
Idealmente, el trabajo de un componente es permitir la experiencia del usuario y nada más.
|
||||
Un componente debe presentar propiedades y métodos para el enlace de datos,
|
||||
para mediar entre la vista (representada por la plantilla)
|
||||
y la lógica de la aplicación (que a menudo incluye alguna noción de * modelo *).
|
||||
|
||||
A component can delegate certain tasks to services, such as fetching data from the server,
|
||||
validating user input, or logging directly to the console.
|
||||
By defining such processing tasks in an *injectable service class*, you make those tasks
|
||||
available to any component.
|
||||
You can also make your app more adaptable by injecting different providers of the same kind of service,
|
||||
as appropriate in different circumstances.
|
||||
Un componente puede delegar ciertas tareas a los servicios, como obtener datos del servidor, validar la entrada del usuario o registrar información directamente en la consola.
|
||||
Al definir tales tareas de procesamiento en una * clase de servicio inyectable *, hace que esas tareas sean disponibles para cualquier componente.
|
||||
También puedes hacer que tu aplicación sea más adaptable inyectando diferentes proveedores del mismo tipo de servicio, según corresponda en diferentes circunstancias.
|
||||
|
||||
Angular doesn't *enforce* these principles. Angular does help you *follow* these principles
|
||||
by making it easy to factor your application logic into services and make those services
|
||||
available to components through *dependency injection*.
|
||||
Angular no * impone * estos principios. Angular te ayuda a * seguir * estos principios
|
||||
al facilitar la integración de la lógica de tu aplicación en los servicios y hacer que esos servicios sean disponibles para los componentes a través de * inyección de dependencia *.
|
||||
|
||||
## Service examples
|
||||
## Ejemplos de servicios
|
||||
|
||||
Here's an example of a service class that logs to the browser console.
|
||||
A continuación, se muestra un ejemplo de una clase de servicio que registra información en la consola del navegador.
|
||||
|
||||
<code-example path="architecture/src/app/logger.service.ts" header="src/app/logger.service.ts (class)" region="class"></code-example>
|
||||
|
||||
Services can depend on other services. For example, here's a `HeroService` that depends on the `Logger` service, and also uses `BackendService` to get heroes. That service in turn might depend on the `HttpClient` service to fetch heroes asynchronously from a server.
|
||||
Los servicios pueden depender de otros servicios. Por ejemplo, hay un `HeroService` que depende del `Logger` service, y también usa `BackendService` para obtener héroes. Ese servicio, a su vez, podría depender del servicio `HttpClient` para buscar héroes de forma asíncrona desde un servidor.
|
||||
|
||||
<code-example path="architecture/src/app/hero.service.ts" header="src/app/hero.service.ts (class)" region="class"></code-example>
|
||||
|
||||
## Dependency injection (DI)
|
||||
## Inyección de dependencia (ID)
|
||||
|
||||
<img src="generated/images/guide/architecture/dependency-injection.png" alt="Service" class="left">
|
||||
|
||||
DI is wired into the Angular framework and used everywhere to provide new components with the services or other things they need.
|
||||
Components consume services; that is, you can *inject* a service into a component, giving the component access to that service class.
|
||||
Inyección de dependencia está conectado al framework de Angular y se usa en todas partes para proporcionar nuevos componentes con los servicios u otras cosas que necesitan.
|
||||
Los componentes consumen servicios; es decir, puede * inyectar * un servicio en un componente, dándole acceso al componente a ese servicio.
|
||||
|
||||
To define a class as a service in Angular, use the `@Injectable()` decorator to provide the metadata that allows Angular to inject it into a component as a *dependency*.
|
||||
Similarly, use the `@Injectable()` decorator to indicate that a component or other class (such as another service, a pipe, or an NgModule) *has* a dependency.
|
||||
Para definir una clase como un servicio en Angular, usa el decorador `@Injectable ()` para proporcionar los metadatos que le permitan a Angular inyectarlo en un componente como una * dependencia *.
|
||||
De manera similar, usa el decorador `@Injectable()` para indicar que un componente u otra clase (como otro servicio, un pipeline o un NgModule) * tiene * una dependencia.
|
||||
|
||||
* The *injector* is the main mechanism. Angular creates an application-wide injector for you during the bootstrap process, and additional injectors as needed. You don't have to create injectors.
|
||||
* El * inyector * es el mecanismo principal. Angular crea un inyector para toda la aplicación durante el proceso de arranque e inyectores adicionales según sea necesario. No es necesario crear inyectores.
|
||||
|
||||
* An injector creates dependencies, and maintains a *container* of dependency instances that it reuses if possible.
|
||||
* Un inyector crea dependencias y mantiene un * contenedor * de instancias de dependencia que reutiliza si es posible.
|
||||
|
||||
* A *provider* is an object that tells an injector how to obtain or create a dependency.
|
||||
* Un * proveedor * es un objeto que le dice a un inyector cómo obtener o crear una dependencia.
|
||||
|
||||
For any dependency that you need in your app, you must register a provider with the app's injector,
|
||||
so that the injector can use the provider to create new instances.
|
||||
For a service, the provider is typically the service class itself.
|
||||
Para cualquier dependencia que necesites en tu aplicación, debes registrar un proveedor con el inyector de la aplicación, con el fin de que el inyector pueda utilizar el proveedor para crear nuevas instancias.
|
||||
Para un servicio, el proveedor suele ser la propia clase de servicio.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
A dependency doesn't have to be a service—it could be a function, for example, or a value.
|
||||
Una dependencia no tiene que ser solamente un servicio—podría ser una función, por ejemplo, o un valor.
|
||||
|
||||
</div>
|
||||
|
||||
When Angular creates a new instance of a component class, it determines which services or other dependencies that component needs by looking at the constructor parameter types. For example, the constructor of `HeroListComponent` needs `HeroService`.
|
||||
Cuando Angular crea una nueva instancia de una clase de componente, determina qué servicios u otras dependencias necesita ese componente al observar los tipos de parámetros del constructor. Por ejemplo, el constructor de `HeroListComponent` necesita `HeroService`.
|
||||
|
||||
<code-example path="architecture/src/app/hero-list.component.ts" header="src/app/hero-list.component.ts (constructor)" region="ctor"></code-example>
|
||||
|
||||
When Angular discovers that a component depends on a service, it first checks if the injector has any existing instances of that service. If a requested service instance doesn't yet exist, the injector makes one using the registered provider, and adds it to the injector before returning the service to Angular.
|
||||
Cuando Angular descubre que un componente depende de un servicio, primero verifica si el inyector tiene instancias existentes de ese servicio. Si una instancia de servicio solicitada aún no existe, el inyector crea una utilizando el proveedor registrado y la agrega al inyector antes de devolver el servicio a Angular.
|
||||
|
||||
When all requested services have been resolved and returned, Angular can call the component's constructor with those services as arguments.
|
||||
Cuando todos los servicios solicitados se han resuelto y devuelto, Angular puede llamar al constructor del componente con esos servicios como argumentos.
|
||||
|
||||
The process of `HeroService` injection looks something like this.
|
||||
El proceso de inyección de "HeroService" se parece a esto.
|
||||
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/architecture/injector-injects.png" alt="Service" class="left">
|
||||
</div>
|
||||
|
||||
### Providing services
|
||||
### Proporcionar servicios
|
||||
|
||||
You must register at least one *provider* of any service you are going to use.
|
||||
The provider can be part of the service's own metadata, making that service available everywhere,
|
||||
or you can register providers with specific modules or components.
|
||||
You register providers in the metadata of the service (in the `@Injectable()` decorator),
|
||||
or in the `@NgModule()` or `@Component()` metadata
|
||||
Deberías registrar al menos un * proveedor * de cualquier servicio que vayas a utilizar.
|
||||
El proveedor puede formar parte de los propios metadatos del servicio, haciendo que ese servicio esté disponible en todas partes, o puede registrar proveedores con módulos o componentes específicos.
|
||||
Debes registrar proveedores en los metadatos del servicio (en el decorador `@Injectable()`),
|
||||
o en los metadatos `@NgModule()` o `@Component()`
|
||||
|
||||
* By default, the Angular CLI command [`ng generate service`](cli/generate) registers a provider with the root injector for your service by including provider metadata in the `@Injectable()` decorator. The tutorial uses this method to register the provider of HeroService class definition.
|
||||
* Por defecto, el comando CLI de Angular [`ng generate service`](cli/generate) registra un proveedor con el inyector raíz para tu servicio al incluir metadatos del proveedor en el decorador `@Injectable()`. El tutorial utiliza este método para registrar el proveedor de la definición de clase HeroService.
|
||||
|
||||
```
|
||||
@Injectable({
|
||||
@ -90,12 +83,10 @@ or in the `@NgModule()` or `@Component()` metadata
|
||||
})
|
||||
```
|
||||
|
||||
When you provide the service at the root level, Angular creates a single, shared instance of `HeroService`
|
||||
and injects it into any class that asks for it.
|
||||
Registering the provider in the `@Injectable()` metadata also allows Angular to optimize an app
|
||||
by removing the service from the compiled app if it isn't used.
|
||||
Cuando proporcionas el servicio en el nivel raíz, Angular crea una instancia única compartida de `HeroService` y lo inyecta en cualquier clase que lo solicite.
|
||||
El registro del proveedor en los metadatos `@Injectable()` también permite a Angular optimizar una aplicación eliminando el servicio de la aplicación compilada si no se utiliza.
|
||||
|
||||
* When you register a provider with a [specific NgModule](guide/architecture-modules), the same instance of a service is available to all components in that NgModule. To register at this level, use the `providers` property of the `@NgModule()` decorator,
|
||||
* Cuando registras un proveedor con un [NgModule específico](guide/architecture-modules), la misma instancia de un servicio está disponible para todos los componentes en ese NgModule. Para registrar en este nivel, usa la propiedad `Provider` del decorador `@NgModule()`.
|
||||
|
||||
```
|
||||
@NgModule({
|
||||
@ -107,10 +98,10 @@ or in the `@NgModule()` or `@Component()` metadata
|
||||
})
|
||||
```
|
||||
|
||||
* When you register a provider at the component level, you get a new instance of the
|
||||
service with each new instance of that component.
|
||||
At the component level, register a service provider in the `providers` property of the `@Component()` metadata.
|
||||
* Cuando registras un proveedor a nivel del componente, obtienes una nueva instancia del
|
||||
servicio con cada nueva instancia de ese componente.
|
||||
A nivel del componente, registra un proveedor de servicios en la propiedad `Providers` de los metadatos `@Component()`.
|
||||
|
||||
<code-example path="architecture/src/app/hero-list.component.ts" header="src/app/hero-list.component.ts (component providers)" region="providers"></code-example>
|
||||
|
||||
For more detailed information, see the [Dependency Injection](guide/dependency-injection) section.
|
||||
Para obtener información más detallada, consulta la sección [Inyección de dependencia](guide/dependency-injection).
|
||||
|
157
aio/content/guide/architecture.en.md
Normal file
157
aio/content/guide/architecture.en.md
Normal file
@ -0,0 +1,157 @@
|
||||
# Introduction to Angular concepts
|
||||
|
||||
Angular is a platform and framework for building single-page client applications using HTML and TypeScript.
|
||||
Angular is written in TypeScript.
|
||||
It implements core and optional functionality as a set of TypeScript libraries that you import into your apps.
|
||||
|
||||
The architecture of an Angular application relies on certain fundamental concepts.
|
||||
The basic building blocks are *NgModules*, which provide a compilation context for *components*. NgModules collect related code into functional sets; an Angular app is defined by a set of NgModules. An app always has at least a *root module* that enables bootstrapping, and typically has many more *feature modules*.
|
||||
|
||||
* Components define *views*, which are sets of screen elements that Angular can choose among and modify according to your program logic and data.
|
||||
|
||||
* Components use *services*, which provide specific functionality not directly related to views. Service providers can be *injected* into components as *dependencies*, making your code modular, reusable, and efficient.
|
||||
|
||||
Modules, components and services are classes that use *decorators*. These decorators mark their type and provide metadata that tells Angular how to use them.
|
||||
|
||||
* The metadata for a component class associates it with a *template* that defines a view. A template combines ordinary HTML with Angular *directives* and *binding markup* that allow Angular to modify the HTML before rendering it for display.
|
||||
|
||||
* The metadata for a service class provides the information Angular needs to make it available to components through *dependency injection (DI)*.
|
||||
|
||||
An app's components typically define many views, arranged hierarchically. Angular provides the `Router` service to help you define navigation paths among views. The router provides sophisticated in-browser navigational capabilities.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
See the [Angular Glossary](guide/glossary) for basic definitions of important Angular terms and usage.
|
||||
|
||||
</div>
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For the sample app that this page describes, see the <live-example></live-example>.
|
||||
</div>
|
||||
|
||||
## Modules
|
||||
|
||||
Angular *NgModules* differ from and complement JavaScript (ES2015) modules. An NgModule declares a compilation context for a set of components that is dedicated to an application domain, a workflow, or a closely related set of capabilities. An NgModule can associate its components with related code, such as services, to form functional units.
|
||||
|
||||
Every Angular app has a *root module*, conventionally named `AppModule`, which provides the bootstrap mechanism that launches the application. An app typically contains many functional modules.
|
||||
|
||||
Like JavaScript modules, NgModules can import functionality from other NgModules, and allow their own functionality to be exported and used by other NgModules. For example, to use the router service in your app, you import the `Router` NgModule.
|
||||
|
||||
Organizing your code into distinct functional modules helps in managing development of complex applications, and in designing for reusability. In addition, this technique lets you take advantage of *lazy-loading*—that is, loading modules on demand—to minimize the amount of code that needs to be loaded at startup.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For a more detailed discussion, see [Introduction to modules](guide/architecture-modules).
|
||||
|
||||
</div>
|
||||
|
||||
## Components
|
||||
|
||||
Every Angular application has at least one component, the *root component* that connects a component hierarchy with the page document object model (DOM). Each component defines a class that contains application data and logic, and is associated with an HTML *template* that defines a view to be displayed in a target environment.
|
||||
|
||||
The `@Component()` decorator identifies the class immediately below it as a component, and provides the template and related component-specific metadata.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
Decorators are functions that modify JavaScript classes. Angular defines a number of decorators that attach specific kinds of metadata to classes, so that the system knows what those classes mean and how they should work.
|
||||
|
||||
<a href="https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841#.x5c2ndtx0">Learn more about decorators on the web.</a>
|
||||
|
||||
</div>
|
||||
|
||||
### Templates, directives, and data binding
|
||||
|
||||
A template combines HTML with Angular markup that can modify HTML elements before they are displayed.
|
||||
Template *directives* provide program logic, and *binding markup* connects your application data and the DOM.
|
||||
There are two types of data binding:
|
||||
|
||||
* *Event binding* lets your app respond to user input in the target environment by updating your application data.
|
||||
* *Property binding* lets you interpolate values that are computed from your application data into the HTML.
|
||||
|
||||
Before a view is displayed, Angular evaluates the directives and resolves the binding syntax in the template to modify the HTML elements and the DOM, according to your program data and logic. Angular supports *two-way data binding*, meaning that changes in the DOM, such as user choices, are also reflected in your program data.
|
||||
|
||||
Your templates can use *pipes* to improve the user experience by transforming values for display.
|
||||
For example, use pipes to display dates and currency values that are appropriate for a user's locale.
|
||||
Angular provides predefined pipes for common transformations, and you can also define your own pipes.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For a more detailed discussion of these concepts, see [Introduction to components](guide/architecture-components).
|
||||
|
||||
</div>
|
||||
|
||||
{@a dependency-injection}
|
||||
|
||||
|
||||
## Services and dependency injection
|
||||
|
||||
For data or logic that isn't associated with a specific view, and that you want to share across components, you create a *service* class. A service class definition is immediately preceded by the `@Injectable()` decorator. The decorator provides the metadata that allows other providers to be **injected** as dependencies into your class.
|
||||
|
||||
*Dependency injection* (DI) lets you keep your component classes lean and efficient. They don't fetch data from the server, validate user input, or log directly to the console; they delegate such tasks to services.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For a more detailed discussion, see [Introduction to services and DI](guide/architecture-services).
|
||||
|
||||
</div>
|
||||
|
||||
### Routing
|
||||
|
||||
The Angular `Router` NgModule provides a service that lets you define a navigation path among the different application states and view hierarchies in your app. It is modeled on the familiar browser navigation conventions:
|
||||
|
||||
* Enter a URL in the address bar and the browser navigates to a corresponding page.
|
||||
|
||||
* Click links on the page and the browser navigates to a new page.
|
||||
|
||||
* Click the browser's back and forward buttons and the browser navigates backward and forward through the history of pages you've seen.
|
||||
|
||||
The router maps URL-like paths to views instead of pages. When a user performs an action, such as clicking a link, that would load a new page in the browser, the router intercepts the browser's behavior, and shows or hides view hierarchies.
|
||||
|
||||
If the router determines that the current application state requires particular functionality, and the module that defines it hasn't been loaded, the router can *lazy-load* the module on demand.
|
||||
|
||||
The router interprets a link URL according to your app's view navigation rules and data state. You can navigate to new views when the user clicks a button or selects from a drop box, or in response to some other stimulus from any source. The router logs activity in the browser's history, so the back and forward buttons work as well.
|
||||
|
||||
To define navigation rules, you associate *navigation paths* with your components. A path uses a URL-like syntax that integrates your program data, in much the same way that template syntax integrates your views with your program data. You can then apply program logic to choose which views to show or to hide, in response to user input and your own access rules.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For a more detailed discussion, see [Routing and navigation](guide/router).
|
||||
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
## What's next
|
||||
|
||||
You've learned the basics about the main building blocks of an Angular application. The following diagram shows how these basic pieces are related.
|
||||
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/architecture/overview2.png" alt="overview">
|
||||
</div>
|
||||
|
||||
* Together, a component and template define an Angular view.
|
||||
* A decorator on a component class adds the metadata, including a pointer to the associated template.
|
||||
* Directives and binding markup in a component's template modify views based on program data and logic.
|
||||
* The dependency injector provides services to a component, such as the router service that lets you define navigation among views.
|
||||
|
||||
Each of these subjects is introduced in more detail in the following pages.
|
||||
|
||||
* [Introduction to Modules](guide/architecture-modules)
|
||||
|
||||
* [Introduction to Components](guide/architecture-components)
|
||||
|
||||
* [Templates and views](guide/architecture-components#templates-and-views)
|
||||
|
||||
* [Component metadata](guide/architecture-components#component-metadata)
|
||||
|
||||
* [Data binding](guide/architecture-components#data-binding)
|
||||
|
||||
* [Directives](guide/architecture-components#directives)
|
||||
|
||||
* [Pipes](guide/architecture-components#pipes)
|
||||
|
||||
* [Introduction to services and dependency injection](guide/architecture-services)
|
||||
|
||||
When you're familiar with these fundamental building blocks, you can explore them in more detail in the documentation. To learn about more tools and techniques that are available to help you build and deploy Angular applications, see [Next steps: tools and techniques](guide/architecture-next-steps).
|
||||
</div>
|
@ -1,157 +1,157 @@
|
||||
# Introduction to Angular concepts
|
||||
# Introducción a los conceptos de Angular
|
||||
|
||||
Angular is a platform and framework for building single-page client applications using HTML and TypeScript.
|
||||
Angular is written in TypeScript.
|
||||
It implements core and optional functionality as a set of TypeScript libraries that you import into your apps.
|
||||
Angular es una plataforma y un framework para crear aplicaciones de una sola página en el lado del cliente usando HTML y TypeScript.
|
||||
Angular está escrito en TypeScript.
|
||||
Implementa la funcionalidad básica y opcional como un conjunto de bibliotecas TypeScript que importas en tus aplicaciones.
|
||||
|
||||
The architecture of an Angular application relies on certain fundamental concepts.
|
||||
The basic building blocks are *NgModules*, which provide a compilation context for *components*. NgModules collect related code into functional sets; an Angular app is defined by a set of NgModules. An app always has at least a *root module* that enables bootstrapping, and typically has many more *feature modules*.
|
||||
La arquitectura de una aplicación en Angular se basa en ciertos conceptos fundamentales.
|
||||
Los bloques de construcción básicos son los *NgModules*, que proporcionan un contexto de compilación para los *componentes*. Los NgModules recopilan código relacionado en conjuntos funcionales; una aplicación de Angular se define por un conjunto de NgModules. Una aplicación siempre tiene al menos un *módulo raíz* que permite el arranque y generalmente tiene muchos más *módulos de funcionalidad*.
|
||||
|
||||
* Components define *views*, which are sets of screen elements that Angular can choose among and modify according to your program logic and data.
|
||||
* Los componentes definen *vistas*, que son conjuntos de elementos de la pantalla que Angular puede elegir y modificar de acuerdo con la lógica y los datos de tu programa.
|
||||
|
||||
* Components use *services*, which provide specific functionality not directly related to views. Service providers can be *injected* into components as *dependencies*, making your code modular, reusable, and efficient.
|
||||
* Los componentes usan *servicios*, los cuales proporcionan una funcionalidad específica que no está directamente relacionada con las vistas. Los proveedores de servicios pueden *inyectarse* en componentes como *dependencias*, haciendo que tu código sea modular, reutilizable y eficiente.
|
||||
|
||||
Modules, components and services are classes that use *decorators*. These decorators mark their type and provide metadata that tells Angular how to use them.
|
||||
Los módulos, componentes y servicios son clases que usan *decoradores*. Estos decoradores indican su tipo y proporcionan metadatos que le indican a Angular cómo usarlos.
|
||||
|
||||
* The metadata for a component class associates it with a *template* that defines a view. A template combines ordinary HTML with Angular *directives* and *binding markup* that allow Angular to modify the HTML before rendering it for display.
|
||||
* Los metadatos para una clase componente son asociados con una *plantilla* que define una vista. Una plantilla combina HTML ordinario con *directivas* de Angular y *enlace markup* que permiten a Angular modificar el HTML antes de mostrarlo para su visualización.
|
||||
|
||||
* The metadata for a service class provides the information Angular needs to make it available to components through *dependency injection (DI)*.
|
||||
* Los metadatos para una clase servicio proporcionan la información que Angular necesita para que esté disponible para los componentes a través de la *Inyección de Dependencia (ID)*.
|
||||
|
||||
An app's components typically define many views, arranged hierarchically. Angular provides the `Router` service to help you define navigation paths among views. The router provides sophisticated in-browser navigational capabilities.
|
||||
Los componentes de una aplicación suelen definir muchas vistas, ordenadas jerárquicamente. Angular proporciona el servicio `Router` para ayudarte a definir rutas de navegación entre vistas. El enrutador proporciona capacidades de navegación sofisticadas en el navegador.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
See the [Angular Glossary](guide/glossary) for basic definitions of important Angular terms and usage.
|
||||
Visita el [Glosario de Angular](guide/glossary) para ver las definiciones básicas de términos importantes en Angular y su uso.
|
||||
|
||||
</div>
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For the sample app that this page describes, see the <live-example></live-example>.
|
||||
Para ver la aplicación de ejemplo que describe esta página, consulta el <live-example>ejemplo</live-example>.
|
||||
</div>
|
||||
|
||||
## Modules
|
||||
## Módulos
|
||||
|
||||
Angular *NgModules* differ from and complement JavaScript (ES2015) modules. An NgModule declares a compilation context for a set of components that is dedicated to an application domain, a workflow, or a closely related set of capabilities. An NgModule can associate its components with related code, such as services, to form functional units.
|
||||
Los *NgModules* de Angular difieren y complementan los módulos JavaScript (ES2015). Un NgModule declara un contexto de compilación para un conjunto de componentes que está dedicado a un dominio de aplicación, un flujo de trabajo o un conjunto de capacidades estrechamente relacionadas. Un NgModule puede asociar sus componentes con código relacionado, como servicios, para formar unidades funcionales.
|
||||
|
||||
Every Angular app has a *root module*, conventionally named `AppModule`, which provides the bootstrap mechanism that launches the application. An app typically contains many functional modules.
|
||||
Cada aplicación en Angular tiene un *módulo raíz*, convencionalmente nombrado `AppModule`, que proporciona el mecanismo de arranque que inicia la aplicación. Una aplicación generalmente contiene muchos módulos funcionales.
|
||||
|
||||
Like JavaScript modules, NgModules can import functionality from other NgModules, and allow their own functionality to be exported and used by other NgModules. For example, to use the router service in your app, you import the `Router` NgModule.
|
||||
Como en los módulos de JavaScript, los NgModules pueden importar la funcionalidad de otros, y permiten que su propia funcionalidad sea exportada y utilizada por otros NgModules. Por ejemplo, para utilizar el servicio de enrutamiento en su aplicación, importa el NgModule `Router`.
|
||||
|
||||
Organizing your code into distinct functional modules helps in managing development of complex applications, and in designing for reusability. In addition, this technique lets you take advantage of *lazy-loading*—that is, loading modules on demand—to minimize the amount of code that needs to be loaded at startup.
|
||||
Organizar tu código en distintos módulos funcionales ayuda a gestionar el desarrollo de aplicaciones complejas, y en el diseño para su reutilización. Además, esta técnica te permite aprovechar la *carga diferida*—es decir, cargar módulos bajo demanda—para minimizar la cantidad de código que debe cargarse al inicio.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For a more detailed discussion, see [Introduction to modules](guide/architecture-modules).
|
||||
Para más información, visita [Introducción a los módulos](guide/architecture-modules).
|
||||
|
||||
</div>
|
||||
|
||||
## Components
|
||||
## Componentes
|
||||
|
||||
Every Angular application has at least one component, the *root component* that connects a component hierarchy with the page document object model (DOM). Each component defines a class that contains application data and logic, and is associated with an HTML *template* that defines a view to be displayed in a target environment.
|
||||
Cada aplicación de Angular tiene al menos un componente, el *componente raíz* que conecta una jerarquía de componentes con el modelo de objetos del documento de la página (DOM). Cada componente define una clase que contiene datos y lógica de la aplicación, y está asociado con una *plantilla* HTML que define una vista que se mostrará en un entorno de destino.
|
||||
|
||||
The `@Component()` decorator identifies the class immediately below it as a component, and provides the template and related component-specific metadata.
|
||||
El decorador `@Component()` identifica la clase inmediatamente debajo de ella como un componente, y proporciona la plantilla y los metadatos específicos del componente relacionado.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
Decorators are functions that modify JavaScript classes. Angular defines a number of decorators that attach specific kinds of metadata to classes, so that the system knows what those classes mean and how they should work.
|
||||
Los decoradores son funciones que modifican las clases de JavaScript. Angular define una serie de decoradores que adjuntan tipos específicos de metadatos a las clases, para que el sistema sepa qué significan esas clases y cómo deberían funcionar.
|
||||
|
||||
<a href="https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841#.x5c2ndtx0">Learn more about decorators on the web.</a>
|
||||
<a href="https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841#.x5c2ndtx0">Obten más información sobre decoradores en la web.</a>
|
||||
|
||||
</div>
|
||||
|
||||
### Templates, directives, and data binding
|
||||
### Plantillas, directivas y enlace de datos
|
||||
|
||||
A template combines HTML with Angular markup that can modify HTML elements before they are displayed.
|
||||
Template *directives* provide program logic, and *binding markup* connects your application data and the DOM.
|
||||
There are two types of data binding:
|
||||
Una plantilla combina HTML con markup de Angular que puede modificar elementos HTML antes de que se muestren.
|
||||
Las *directivas* de la plantilla proporcionan la lógica de programa y el *enlace markup* conecta los datos de tu aplicación y el DOM.
|
||||
Hay dos tipos de enlace de datos:
|
||||
|
||||
* *Event binding* lets your app respond to user input in the target environment by updating your application data.
|
||||
* *Property binding* lets you interpolate values that are computed from your application data into the HTML.
|
||||
* *Manejador de eventos* permite que tu aplicación responda a la entrada del usuario en el entorno objetivo actualizando los datos de tu aplicación.
|
||||
* *Vincular propiedades* te permite interpolar valores que se calculan a partir de los datos de tu aplicación en HTML.
|
||||
|
||||
Before a view is displayed, Angular evaluates the directives and resolves the binding syntax in the template to modify the HTML elements and the DOM, according to your program data and logic. Angular supports *two-way data binding*, meaning that changes in the DOM, such as user choices, are also reflected in your program data.
|
||||
Antes de mostrar una vista, Angular evalúa las directivas y resuelve la sintaxis de enlace en la plantilla para modificar los elementos HTML y el DOM, de acuerdo con los datos y la lógica de tu programa. Angular soporta *enlace de datos en dos sentidos*, lo que significa que los cambios en el DOM, como las elecciones del usuario, también se reflejan en los datos de su programa.
|
||||
|
||||
Your templates can use *pipes* to improve the user experience by transforming values for display.
|
||||
For example, use pipes to display dates and currency values that are appropriate for a user's locale.
|
||||
Angular provides predefined pipes for common transformations, and you can also define your own pipes.
|
||||
Tus plantillas pueden usar *pipes* para mejorar la experiencia del usuario mediante la transformación de valores para mostrar.
|
||||
Por ejemplo, usa pipes para mostrar fechas y valores de moneda que sean apropiados para la configuración regional de un usuario.
|
||||
Angular proporciona pipes predefinidas para transformaciones comunes, y también puedes definir tus propias pipes.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For a more detailed discussion of these concepts, see [Introduction to components](guide/architecture-components).
|
||||
Para más información sobre estos conceptos, visita [Introducción a los componentes](guide/architecture-components).
|
||||
|
||||
</div>
|
||||
|
||||
{@a dependency-injection}
|
||||
|
||||
|
||||
## Services and dependency injection
|
||||
## Servicios e inyección de dependencia
|
||||
|
||||
For data or logic that isn't associated with a specific view, and that you want to share across components, you create a *service* class. A service class definition is immediately preceded by the `@Injectable()` decorator. The decorator provides the metadata that allows other providers to be **injected** as dependencies into your class.
|
||||
Para los datos o la lógica que no están asociados con una vista específica y que deseas compartir entre componentes, crea una clase *servicio*. Una definición de clase servicio está inmediatamente precedida por el decorador `@Injectable()`. El decorador proporciona los metadatos que permiten **inyectar** otros proveedores como dependencias en su clase.
|
||||
|
||||
*Dependency injection* (DI) lets you keep your component classes lean and efficient. They don't fetch data from the server, validate user input, or log directly to the console; they delegate such tasks to services.
|
||||
*Inyección de Dependecia* (ID) te permite mantener sus clases componente ligeras y eficientes. No obtienen datos del servidor, validan la entrada del usuario o registra directamente en la consola; tales tareas son delegadas a los servicios.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For a more detailed discussion, see [Introduction to services and DI](guide/architecture-services).
|
||||
Para más información, visita [Introducción a los servicios e inyección de dependencia](guide/architecture-services).
|
||||
|
||||
</div>
|
||||
|
||||
### Routing
|
||||
### Enrutamiento
|
||||
|
||||
The Angular `Router` NgModule provides a service that lets you define a navigation path among the different application states and view hierarchies in your app. It is modeled on the familiar browser navigation conventions:
|
||||
El NgModule `Router` de Angular proporciona un servicio que te permite definir una ruta de navegación entre los diferentes estados de la aplicación y ver sus jerarquías. Se basa en las convenciones frecuentes de navegación del navegador:
|
||||
|
||||
* Enter a URL in the address bar and the browser navigates to a corresponding page.
|
||||
* Ingresa una URL en la barra de direcciones para que el navegador vaya a la página correspondiente.
|
||||
|
||||
* Click links on the page and the browser navigates to a new page.
|
||||
* Haz clic en los enlaces de la página para que el navegador vaya a una nueva página.
|
||||
|
||||
* Click the browser's back and forward buttons and the browser navigates backward and forward through the history of pages you've seen.
|
||||
* Haz clic en los botones atrás y adelante del navegador para que el navegador vaya hacia atrás y hacia adelante a través del historial de las páginas que has visto.
|
||||
|
||||
The router maps URL-like paths to views instead of pages. When a user performs an action, such as clicking a link, that would load a new page in the browser, the router intercepts the browser's behavior, and shows or hides view hierarchies.
|
||||
El enrutador mapea rutas similares a URL para las vistas en lugar de páginas. Cuando un usuario realiza una acción, como hacer clic en un enlace, que cargaría una nueva página en el navegador, el enrutador intercepta el comportamiento del navegador y muestra u oculta las jerarquías de vista.
|
||||
|
||||
If the router determines that the current application state requires particular functionality, and the module that defines it hasn't been loaded, the router can *lazy-load* the module on demand.
|
||||
Si el enrutador determina que el estado actual de la aplicación requiere una funcionalidad particular, y el módulo que lo define no se ha cargado, el enrutador puede hacer *cargar diferida* sobre el módulo bajo demanda.
|
||||
|
||||
The router interprets a link URL according to your app's view navigation rules and data state. You can navigate to new views when the user clicks a button or selects from a drop box, or in response to some other stimulus from any source. The router logs activity in the browser's history, so the back and forward buttons work as well.
|
||||
El enrutador interpreta una URL de enlace de acuerdo con las reglas de navegación de visualización de la aplicación y el estado de los datos. Puedes navegar a las nuevas vistas cuando el usuario hace clic en un botón o selecciona desde un cuadro desplegable, o en respuesta a algún otro estímulo de cualquier fuente. El enrutador registra la actividad en el historial del navegador, por lo que los botones de retroceso y avance también funcionan.
|
||||
|
||||
To define navigation rules, you associate *navigation paths* with your components. A path uses a URL-like syntax that integrates your program data, in much the same way that template syntax integrates your views with your program data. You can then apply program logic to choose which views to show or to hide, in response to user input and your own access rules.
|
||||
Para definir reglas de navegación, asocia *rutas de navegación* a tus componentes. Una ruta utiliza una sintaxis similar a una URL que integra los datos de tu programa, de la misma manera que la sintaxis de la plantilla integra tus vistas con los datos de tu programa. Luego puedes aplicar la lógica del programa para elegir qué vistas mostrar u ocultar, en respuesta a la entrada del usuario y a tus propias reglas de acceso.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For a more detailed discussion, see [Routing and navigation](guide/router).
|
||||
Para más información, visita [Enrutamiento y navegación](guide/router).
|
||||
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
## What's next
|
||||
## ¿Qué sigue?
|
||||
|
||||
You've learned the basics about the main building blocks of an Angular application. The following diagram shows how these basic pieces are related.
|
||||
Has aprendido los conceptos básicos sobre los bloques de construcción de una aplicación en Angular. El siguiente diagrama muestra cómo se relacionan estos conceptos básicos.
|
||||
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/architecture/overview2.png" alt="overview">
|
||||
</div>
|
||||
|
||||
* Together, a component and template define an Angular view.
|
||||
* A decorator on a component class adds the metadata, including a pointer to the associated template.
|
||||
* Directives and binding markup in a component's template modify views based on program data and logic.
|
||||
* The dependency injector provides services to a component, such as the router service that lets you define navigation among views.
|
||||
* Juntos, un componente y una plantilla definen una vista en Angular.
|
||||
* Un decorador en una clase componente agrega los metadatos, incluido un apuntador a la plantilla asociada.
|
||||
* Las directivas y el enlace markup en la plantilla de un componente modifican las vistas basadas en los datos y la lógica del programa.
|
||||
* El inyector de dependencia proporciona servicios a un componente, como el servicio de enrutamiento que le permite definir la navegación entre vistas.
|
||||
|
||||
Each of these subjects is introduced in more detail in the following pages.
|
||||
Cada uno de estos temas se presenta con más detalle en las siguientes páginas.
|
||||
|
||||
* [Introduction to Modules](guide/architecture-modules)
|
||||
* [Introducción a los Módulos](guide/architecture-modules)
|
||||
|
||||
* [Introduction to Components](guide/architecture-components)
|
||||
* [Introducción a los Componentes](guide/architecture-components)
|
||||
|
||||
* [Templates and views](guide/architecture-components#templates-and-views)
|
||||
* [Plantillas y Vistas](guide/architecture-components#templates-and-views)
|
||||
|
||||
* [Component metadata](guide/architecture-components#component-metadata)
|
||||
* [Metadatos de Componentes](guide/architecture-components#component-metadata)
|
||||
|
||||
* [Data binding](guide/architecture-components#data-binding)
|
||||
* [Enlace de Datos](guide/architecture-components#data-binding)
|
||||
|
||||
* [Directives](guide/architecture-components#directives)
|
||||
* [Directivas](guide/architecture-components#directives)
|
||||
|
||||
* [Pipes](guide/architecture-components#pipes)
|
||||
|
||||
* [Introduction to services and dependency injection](guide/architecture-services)
|
||||
* [Introducción a los Servicios e Inyección de Dependencias.](guide/architecture-services)
|
||||
|
||||
When you're familiar with these fundamental building blocks, you can explore them in more detail in the documentation. To learn about more tools and techniques that are available to help you build and deploy Angular applications, see [Next steps: tools and techniques](guide/architecture-next-steps).
|
||||
Cuando estés familiarizado con estos bloques de construcción fundamentales, podrás explorarlos con más detalle en la documentación. Para saber más acerca de las herramientas y técnicas disponibles para ayudarte a crear y desplegar aplicaciones de Angular, visita [Próximos pasos: herramientas y técnicas](guide/architecture-next-steps).
|
||||
</div>
|
||||
|
303
aio/content/guide/attribute-binding.en.md
Normal file
303
aio/content/guide/attribute-binding.en.md
Normal file
@ -0,0 +1,303 @@
|
||||
# Attribute, class, and style bindings
|
||||
|
||||
The template syntax provides specialized one-way bindings for scenarios less well-suited to property binding.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
See the <live-example></live-example> for a working example containing the code snippets in this guide.
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
## Attribute binding
|
||||
|
||||
Set the value of an attribute directly with an **attribute binding**. This is the only exception to the rule that a binding sets a target property and the only binding that creates and sets an attribute.
|
||||
|
||||
Usually, setting an element property with a [property binding](guide/property-binding)
|
||||
is preferable to setting the attribute with a string. However, sometimes
|
||||
there is no element property to bind, so attribute binding is the solution.
|
||||
|
||||
Consider the [ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) and
|
||||
[SVG](https://developer.mozilla.org/en-US/docs/Web/SVG). They are purely attributes, don't correspond to element properties, and don't set element properties. In these cases, there are no property targets to bind to.
|
||||
|
||||
Attribute binding syntax resembles property binding, but
|
||||
instead of an element property between brackets, start with the prefix `attr`,
|
||||
followed by a dot (`.`), and the name of the attribute.
|
||||
You then set the attribute value, using an expression that resolves to a string,
|
||||
or remove the attribute when the expression resolves to `null`.
|
||||
|
||||
One of the primary use cases for attribute binding
|
||||
is to set ARIA attributes, as in this example:
|
||||
|
||||
<code-example path="attribute-binding/src/app/app.component.html" region="attrib-binding-aria" header="src/app/app.component.html"></code-example>
|
||||
|
||||
{@a colspan}
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
#### `colspan` and `colSpan`
|
||||
|
||||
Notice the difference between the `colspan` attribute and the `colSpan` property.
|
||||
|
||||
If you wrote something like this:
|
||||
|
||||
<code-example language="html">
|
||||
<tr><td colspan="{{1 + 1}}">Three-Four</td></tr>
|
||||
</code-example>
|
||||
|
||||
You'd get this error:
|
||||
|
||||
<code-example language="bash">
|
||||
Template parse errors:
|
||||
Can't bind to 'colspan' since it isn't a known native property
|
||||
</code-example>
|
||||
|
||||
As the message says, the `<td>` element does not have a `colspan` property. This is true
|
||||
because `colspan` is an attribute—`colSpan`, with a capital `S`, is the
|
||||
corresponding property. Interpolation and property binding can set only *properties*, not attributes.
|
||||
|
||||
Instead, you'd use property binding and write it like this:
|
||||
|
||||
<code-example path="attribute-binding/src/app/app.component.html" region="colSpan" header="src/app/app.component.html"></code-example>
|
||||
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
{@a class-binding}
|
||||
|
||||
## Class binding
|
||||
|
||||
Here's how to set the `class` attribute without a binding in plain HTML:
|
||||
|
||||
```html
|
||||
<!-- standard class attribute setting -->
|
||||
<div class="foo bar">Some text</div>
|
||||
```
|
||||
|
||||
You can also add and remove CSS class names from an element's `class` attribute with a **class binding**.
|
||||
|
||||
To create a single class binding, start with the prefix `class` followed by a dot (`.`) and the name of the CSS class (for example, `[class.foo]="hasFoo"`).
|
||||
Angular adds the class when the bound expression is truthy, and it removes the class when the expression is falsy (with the exception of `undefined`, see [styling delegation](#styling-delegation)).
|
||||
|
||||
To create a binding to multiple classes, use a generic `[class]` binding without the dot (for example, `[class]="classExpr"`).
|
||||
The expression can be a space-delimited string of class names, or you can format it as an object with class names as the keys and truthy/falsy expressions as the values.
|
||||
With object format, Angular will add a class only if its associated value is truthy.
|
||||
|
||||
It's important to note that with any object-like expression (`object`, `Array`, `Map`, `Set`, etc), the identity of the object must change for the class list to be updated.
|
||||
Updating the property without changing object identity will have no effect.
|
||||
|
||||
If there are multiple bindings to the same class name, conflicts are resolved using [styling precedence](#styling-precedence).
|
||||
|
||||
<style>
|
||||
td, th {vertical-align: top}
|
||||
</style>
|
||||
|
||||
<table width="100%">
|
||||
<col width="15%">
|
||||
</col>
|
||||
<col width="20%">
|
||||
</col>
|
||||
<col width="35%">
|
||||
</col>
|
||||
<col width="30%">
|
||||
</col>
|
||||
<tr>
|
||||
<th>
|
||||
Binding Type
|
||||
</th>
|
||||
<th>
|
||||
Syntax
|
||||
</th>
|
||||
<th>
|
||||
Input Type
|
||||
</th>
|
||||
<th>
|
||||
Example Input Values
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Single class binding</td>
|
||||
<td><code>[class.foo]="hasFoo"</code></td>
|
||||
<td><code>boolean | undefined | null</code></td>
|
||||
<td><code>true</code>, <code>false</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan=3>Multi-class binding</td>
|
||||
<td rowspan=3><code>[class]="classExpr"</code></td>
|
||||
<td><code>string</code></td>
|
||||
<td><code>"my-class-1 my-class-2 my-class-3"</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>{[key: string]: boolean | undefined | null}</code></td>
|
||||
<td><code>{foo: true, bar: false}</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>Array</code><<code>string</code>></td>
|
||||
<td><code>['foo', 'bar']</code></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
The [NgClass](guide/built-in-directives/#ngclass) directive can be used as an alternative to direct `[class]` bindings.
|
||||
However, using the above class binding syntax without `NgClass` is preferred because due to improvements in class binding in Angular, `NgClass` no longer provides significant value, and might eventually be removed in the future.
|
||||
|
||||
|
||||
<hr/>
|
||||
|
||||
## Style binding
|
||||
|
||||
Here's how to set the `style` attribute without a binding in plain HTML:
|
||||
|
||||
```html
|
||||
<!-- standard style attribute setting -->
|
||||
<div style="color: blue">Some text</div>
|
||||
```
|
||||
|
||||
You can also set styles dynamically with a **style binding**.
|
||||
|
||||
To create a single style binding, start with the prefix `style` followed by a dot (`.`) and the name of the CSS style property (for example, `[style.width]="width"`).
|
||||
The property will be set to the value of the bound expression, which is normally a string.
|
||||
Optionally, you can add a unit extension like `em` or `%`, which requires a number type.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
Note that a _style property_ name can be written in either
|
||||
[dash-case](guide/glossary#dash-case), as shown above, or
|
||||
[camelCase](guide/glossary#camelcase), such as `fontSize`.
|
||||
|
||||
</div>
|
||||
|
||||
If there are multiple styles you'd like to toggle, you can bind to the `[style]` property directly without the dot (for example, `[style]="styleExpr"`).
|
||||
The expression attached to the `[style]` binding is most often a string list of styles like `"width: 100px; height: 100px;"`.
|
||||
|
||||
You can also format the expression as an object with style names as the keys and style values as the values, like `{width: '100px', height: '100px'}`.
|
||||
It's important to note that with any object-like expression (`object`, `Array`, `Map`, `Set`, etc), the identity of the object must change for the class list to be updated.
|
||||
Updating the property without changing object identity will have no effect.
|
||||
|
||||
If there are multiple bindings to the same style property, conflicts are resolved using [styling precedence rules](#styling-precedence).
|
||||
|
||||
<style>
|
||||
td, th {vertical-align: top}
|
||||
</style>
|
||||
|
||||
<table width="100%">
|
||||
<col width="15%">
|
||||
</col>
|
||||
<col width="20%">
|
||||
</col>
|
||||
<col width="35%">
|
||||
</col>
|
||||
<col width="30%">
|
||||
</col>
|
||||
<tr>
|
||||
<th>
|
||||
Binding Type
|
||||
</th>
|
||||
<th>
|
||||
Syntax
|
||||
</th>
|
||||
<th>
|
||||
Input Type
|
||||
</th>
|
||||
<th>
|
||||
Example Input Values
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Single style binding</td>
|
||||
<td><code>[style.width]="width"</code></td>
|
||||
<td><code>string | undefined | null</code></td>
|
||||
<td><code>"100px"</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<tr>
|
||||
<td>Single style binding with units</td>
|
||||
<td><code>[style.width.px]="width"</code></td>
|
||||
<td><code>number | undefined | null</code></td>
|
||||
<td><code>100</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan=3>Multi-style binding</td>
|
||||
<td rowspan=3><code>[style]="styleExpr"</code></td>
|
||||
<td><code>string</code></td>
|
||||
<td><code>"width: 100px; height: 100px"</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>{[key: string]: string | undefined | null}</code></td>
|
||||
<td><code>{width: '100px', height: '100px'}</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>Array</code><<code>string</code>></td>
|
||||
<td><code>['width', '100px']</code></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
The [NgStyle](guide/built-in-directives/#ngstyle) directive can be used as an alternative to direct `[style]` bindings.
|
||||
However, using the above style binding syntax without `NgStyle` is preferred because due to improvements in style binding in Angular, `NgStyle` no longer provides significant value, and might eventually be removed in the future.
|
||||
|
||||
|
||||
<hr/>
|
||||
|
||||
{@a styling-precedence}
|
||||
|
||||
## Styling Precedence
|
||||
|
||||
A single HTML element can have its CSS class list and style values bound to multiple sources (for example, host bindings from multiple directives).
|
||||
|
||||
When there are multiple bindings to the same class name or style property, Angular uses a set of precedence rules to resolve conflicts and determine which classes or styles are ultimately applied to the element.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
<h4>Styling precedence (highest to lowest)</h4>
|
||||
|
||||
1. Template bindings
|
||||
1. Property binding (for example, `<div [class.foo]="hasFoo">` or `<div [style.color]="color">`)
|
||||
1. Map binding (for example, `<div [class]="classExpr">` or `<div [style]="styleExpr">`)
|
||||
1. Static value (for example, `<div class="foo">` or `<div style="color: blue">`)
|
||||
1. Directive host bindings
|
||||
1. Property binding (for example, `host: {'[class.foo]': 'hasFoo'}` or `host: {'[style.color]': 'color'}`)
|
||||
1. Map binding (for example, `host: {'[class]': 'classExpr'}` or `host: {'[style]': 'styleExpr'}`)
|
||||
1. Static value (for example, `host: {'class': 'foo'}` or `host: {'style': 'color: blue'}`)
|
||||
1. Component host bindings
|
||||
1. Property binding (for example, `host: {'[class.foo]': 'hasFoo'}` or `host: {'[style.color]': 'color'}`)
|
||||
1. Map binding (for example, `host: {'[class]': 'classExpr'}` or `host: {'[style]': 'styleExpr'}`)
|
||||
1. Static value (for example, `host: {'class': 'foo'}` or `host: {'style': 'color: blue'}`)
|
||||
|
||||
</div>
|
||||
|
||||
The more specific a class or style binding is, the higher its precedence.
|
||||
|
||||
A binding to a specific class (for example, `[class.foo]`) will take precedence over a generic `[class]` binding, and a binding to a specific style (for example, `[style.bar]`) will take precedence over a generic `[style]` binding.
|
||||
|
||||
<code-example path="attribute-binding/src/app/app.component.html" region="basic-specificity" header="src/app/app.component.html"></code-example>
|
||||
|
||||
Specificity rules also apply when it comes to bindings that originate from different sources.
|
||||
It's possible for an element to have bindings in the template where it's declared, from host bindings on matched directives, and from host bindings on matched components.
|
||||
|
||||
Template bindings are the most specific because they apply to the element directly and exclusively, so they have the highest precedence.
|
||||
|
||||
Directive host bindings are considered less specific because directives can be used in multiple locations, so they have a lower precedence than template bindings.
|
||||
|
||||
Directives often augment component behavior, so host bindings from components have the lowest precedence.
|
||||
|
||||
<code-example path="attribute-binding/src/app/app.component.html" region="source-specificity" header="src/app/app.component.html"></code-example>
|
||||
|
||||
In addition, bindings take precedence over static attributes.
|
||||
|
||||
In the following case, `class` and `[class]` have similar specificity, but the `[class]` binding will take precedence because it is dynamic.
|
||||
|
||||
<code-example path="attribute-binding/src/app/app.component.html" region="dynamic-priority" header="src/app/app.component.html"></code-example>
|
||||
|
||||
{@a styling-delegation}
|
||||
### Delegating to styles with lower precedence
|
||||
|
||||
It is possible for higher precedence styles to "delegate" to lower precedence styles using `undefined` values.
|
||||
Whereas setting a style property to `null` ensures the style is removed, setting it to `undefined` will cause Angular to fall back to the next-highest precedence binding to that style.
|
||||
|
||||
For example, consider the following template:
|
||||
|
||||
<code-example path="attribute-binding/src/app/app.component.html" region="style-delegation" header="src/app/app.component.html"></code-example>
|
||||
|
||||
Imagine that the `dirWithHostBinding` directive and the `comp-with-host-binding` component both have a `[style.width]` host binding.
|
||||
In that case, if `dirWithHostBinding` sets its binding to `undefined`, the `width` property will fall back to the value of the `comp-with-host-binding` host binding.
|
||||
However, if `dirWithHostBinding` sets its binding to `null`, the `width` property will be removed entirely.
|
@ -1,33 +1,28 @@
|
||||
# Attribute, class, and style bindings
|
||||
# Enlaces de atributos, clases y estilos
|
||||
|
||||
The template syntax provides specialized one-way bindings for scenarios less well-suited to property binding.
|
||||
La sintaxis de la plantilla proporciona enlaces one-way especializados para escenarios menos adecuados para el enlace de propiedades.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
See the <live-example></live-example> for a working example containing the code snippets in this guide.
|
||||
Consulta el <live-example></live-example> para ver un ejemplo práctico que contiene los fragmentos de código de esta guía.
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
## Attribute binding
|
||||
## Enlace de atributo
|
||||
|
||||
Set the value of an attribute directly with an **attribute binding**. This is the only exception to the rule that a binding sets a target property and the only binding that creates and sets an attribute.
|
||||
Establece el valor de un atributo directamente con un **enlace de atributo**. Esta es la única excepción a la regla de que un enlace establece una propiedad de destino y el único enlace que crea y establece un atributo.
|
||||
|
||||
Usually, setting an element property with a [property binding](guide/property-binding)
|
||||
is preferable to setting the attribute with a string. However, sometimes
|
||||
there is no element property to bind, so attribute binding is the solution.
|
||||
Por lo general, establecer una propiedad de elemento con un [enlace de propiedad](guide/property-binding) es preferible establecer el atributo con una string. Sin embargo, a veces
|
||||
no hay ninguna propiedad de elemento para vincular, por lo que la vinculación de atributos es la solución.
|
||||
|
||||
Consider the [ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) and
|
||||
[SVG](https://developer.mozilla.org/en-US/docs/Web/SVG). They are purely attributes, don't correspond to element properties, and don't set element properties. In these cases, there are no property targets to bind to.
|
||||
Considera el [ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) y
|
||||
[SVG](https://developer.mozilla.org/en-US/docs/Web/SVG). Son puramente atributos, no corresponden a las propiedades del elemento y no establecen las propiedades del elemento. En estos casos, no hay objetivos de propiedad a los que vincularse.
|
||||
|
||||
Attribute binding syntax resembles property binding, but
|
||||
instead of an element property between brackets, start with the prefix `attr`,
|
||||
followed by a dot (`.`), and the name of the attribute.
|
||||
You then set the attribute value, using an expression that resolves to a string,
|
||||
or remove the attribute when the expression resolves to `null`.
|
||||
La sintaxis de enlace de atributo se parece al enlace de propiedad, pero en lugar de una propiedad de elemento entre paréntesis, comienza con el prefijo `attr`, seguido de un punto (`.`) y el nombre del atributo.
|
||||
Luego establece el valor del atributo, utilizando una expresión que se resuelve en una string, o elimina el atributo cuando la expresión se resuelva en `null`.
|
||||
|
||||
One of the primary use cases for attribute binding
|
||||
is to set ARIA attributes, as in this example:
|
||||
Uno de los casos de uso principales para el enlace de atributos es establecer atributos ARIA, como en este ejemplo:
|
||||
|
||||
<code-example path="attribute-binding/src/app/app.component.html" region="attrib-binding-aria" header="src/app/app.component.html"></code-example>
|
||||
|
||||
@ -35,28 +30,27 @@ is to set ARIA attributes, as in this example:
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
#### `colspan` and `colSpan`
|
||||
#### `colspan` y `colSpan`
|
||||
|
||||
Notice the difference between the `colspan` attribute and the `colSpan` property.
|
||||
Observa la diferencia entre el atributo `colspan` y la propiedad `colSpan`.
|
||||
|
||||
If you wrote something like this:
|
||||
Si escribes algo como esto:
|
||||
|
||||
<code-example language="html">
|
||||
<tr><td colspan="{{1 + 1}}">Three-Four</td></tr>
|
||||
</code-example>
|
||||
|
||||
You'd get this error:
|
||||
Recibirías este error:
|
||||
|
||||
<code-example language="bash">
|
||||
Template parse errors:
|
||||
Can't bind to 'colspan' since it isn't a known native property
|
||||
</code-example>
|
||||
|
||||
As the message says, the `<td>` element does not have a `colspan` property. This is true
|
||||
because `colspan` is an attribute—`colSpan`, with a capital `S`, is the
|
||||
corresponding property. Interpolation and property binding can set only *properties*, not attributes.
|
||||
Como dice el mensaje, el elemento `<td>` no tiene una propiedad `colspan`. Esto es verdad
|
||||
porque `colspan` es un atributo—`colSpan`, con una `S` mayúscula, es la propiedad correspondiente. La interpolación y el enlace de propiedades solo pueden establecer *propiedades*, no atributos.
|
||||
|
||||
Instead, you'd use property binding and write it like this:
|
||||
En su lugar, puedes usar el enlace de propiedad y lo escribirías así:
|
||||
|
||||
<code-example path="attribute-binding/src/app/app.component.html" region="colSpan" header="src/app/app.component.html"></code-example>
|
||||
|
||||
@ -66,28 +60,28 @@ Instead, you'd use property binding and write it like this:
|
||||
|
||||
{@a class-binding}
|
||||
|
||||
## Class binding
|
||||
## Enlace de clase
|
||||
|
||||
Here's how to set the `class` attribute without a binding in plain HTML:
|
||||
Aquí se explica cómo configurar el atributo `class` sin un enlace en HTML simple:
|
||||
|
||||
```html
|
||||
<!-- standard class attribute setting -->
|
||||
<div class="foo bar">Some text</div>
|
||||
<div class="foo bar">Algún texto</div>
|
||||
```
|
||||
|
||||
You can also add and remove CSS class names from an element's `class` attribute with a **class binding**.
|
||||
También puedes agregar y eliminar nombres de clase CSS del atributo `class` de un elemento con un **enlace de clase**.
|
||||
|
||||
To create a single class binding, start with the prefix `class` followed by a dot (`.`) and the name of the CSS class (for example, `[class.foo]="hasFoo"`).
|
||||
Angular adds the class when the bound expression is truthy, and it removes the class when the expression is falsy (with the exception of `undefined`, see [styling delegation](#styling-delegation)).
|
||||
Para crear un enlace de clase único, comienza con el prefijo `class` seguido de un punto (`.`) y el nombre de la clase CSS (por ejemplo, `[class.foo]="hasFoo"`).
|
||||
Angular agrega la clase cuando la expresión enlazada es verdadera y elimina la clase cuando la expresión es falsa (con la excepción de `undefined`, vea [delegación de estilo](#styling-delegation)).
|
||||
|
||||
To create a binding to multiple classes, use a generic `[class]` binding without the dot (for example, `[class]="classExpr"`).
|
||||
The expression can be a space-delimited string of class names, or you can format it as an object with class names as the keys and truthy/falsy expressions as the values.
|
||||
With object format, Angular will add a class only if its associated value is truthy.
|
||||
Para crear un enlace a varias clases, usa un enlace genérico `[class]` sin el punto (por ejemplo, `[class]="classExpr"`).
|
||||
La expresión puede ser una string de nombres de clase delimitada por espacios, o puede formatearla como un objeto con nombres de clase como claves y expresiones de verdad / falsedad como valores.
|
||||
Con el formato de objeto, Angular agregará una clase solo si su valor asociado es verdadero.
|
||||
|
||||
It's important to note that with any object-like expression (`object`, `Array`, `Map`, `Set`, etc), the identity of the object must change for the class list to be updated.
|
||||
Updating the property without changing object identity will have no effect.
|
||||
Es importante tener en cuenta que con cualquier expresión similar a un objeto (`object`,`Array`, `Map`, `Set`, etc.), la identidad del objeto debe cambiar para que se actualice la lista de clases.
|
||||
Actualizar la propiedad sin cambiar la identidad del objeto no tendrá ningún efecto.
|
||||
|
||||
If there are multiple bindings to the same class name, conflicts are resolved using [styling precedence](#styling-precedence).
|
||||
Si hay varios enlaces al mismo nombre de clase, los conflictos se resuelven usando [precedencia de estilo](#styling-precedence).
|
||||
|
||||
<style>
|
||||
td, th {vertical-align: top}
|
||||
@ -104,26 +98,26 @@ If there are multiple bindings to the same class name, conflicts are resolved us
|
||||
</col>
|
||||
<tr>
|
||||
<th>
|
||||
Binding Type
|
||||
Tipo de enlace
|
||||
</th>
|
||||
<th>
|
||||
Syntax
|
||||
Sintaxis
|
||||
</th>
|
||||
<th>
|
||||
Input Type
|
||||
Tipo de entrada
|
||||
</th>
|
||||
<th>
|
||||
Example Input Values
|
||||
Ejemplo de valores de entrada
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Single class binding</td>
|
||||
<td>Enlace de clase única</td>
|
||||
<td><code>[class.foo]="hasFoo"</code></td>
|
||||
<td><code>boolean | undefined | null</code></td>
|
||||
<td><code>true</code>, <code>false</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan=3>Multi-class binding</td>
|
||||
<td rowspan=3>Enlace de clases múltiples</td>
|
||||
<td rowspan=3><code>[class]="classExpr"</code></td>
|
||||
<td><code>string</code></td>
|
||||
<td><code>"my-class-1 my-class-2 my-class-3"</code></td>
|
||||
@ -139,43 +133,43 @@ If there are multiple bindings to the same class name, conflicts are resolved us
|
||||
</table>
|
||||
|
||||
|
||||
The [NgClass](guide/built-in-directives/#ngclass) directive can be used as an alternative to direct `[class]` bindings.
|
||||
However, using the above class binding syntax without `NgClass` is preferred because due to improvements in class binding in Angular, `NgClass` no longer provides significant value, and might eventually be removed in the future.
|
||||
La directiva [NgClass](guide/built-in-directives/#ngclass) se puede utilizar como alternativa a los enlaces directos `[class]`.
|
||||
Sin embargo, se prefiere usar la sintaxis de enlace de clase anterior sin `NgClass` porque debido a las mejoras en el enlace de clase en Angular, `NgClass` ya no proporciona un valor significativo y podría eliminarse en el futuro.
|
||||
|
||||
|
||||
<hr/>
|
||||
|
||||
## Style binding
|
||||
{@a style-binding}
|
||||
|
||||
Here's how to set the `style` attribute without a binding in plain HTML:
|
||||
## Enlace de estilo
|
||||
|
||||
Aquí se explica cómo configurar el atributo `style` sin un enlace en HTML simple:
|
||||
|
||||
```html
|
||||
<!-- standard style attribute setting -->
|
||||
<div style="color: blue">Some text</div>
|
||||
<div style="color: blue">Algún texto</div>
|
||||
```
|
||||
|
||||
You can also set styles dynamically with a **style binding**.
|
||||
También se puede establecer estilos dinámicamente con un **enlace de estilo**.
|
||||
|
||||
To create a single style binding, start with the prefix `style` followed by a dot (`.`) and the name of the CSS style property (for example, `[style.width]="width"`).
|
||||
The property will be set to the value of the bound expression, which is normally a string.
|
||||
Optionally, you can add a unit extension like `em` or `%`, which requires a number type.
|
||||
Para crear un enlace de estilo único, comienza con el prefijo `style` seguido de un punto (`.`) y el nombre de la propiedad de estilo CSS (por ejemplo, `[style.width]="width"`).
|
||||
La propiedad se establecerá en el valor de la expresión enlazada, que normalmente es una string.
|
||||
Opcionalmente, se puede agregar una extensión de unidad como `em` o `%`, que requiere un tipo de número.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
Note that a _style property_ name can be written in either
|
||||
[dash-case](guide/glossary#dash-case), as shown above, or
|
||||
[camelCase](guide/glossary#camelcase), such as `fontSize`.
|
||||
Ten en cuenta que se puede escribir una _propiedad de estilo_ en [dash-case](guide/glossary#dash-case), como se muestra arriba, o [camelCase](guide/glossary#camelcase), como `fontSize`.
|
||||
|
||||
</div>
|
||||
|
||||
If there are multiple styles you'd like to toggle, you can bind to the `[style]` property directly without the dot (for example, `[style]="styleExpr"`).
|
||||
The expression attached to the `[style]` binding is most often a string list of styles like `"width: 100px; height: 100px;"`.
|
||||
Si deseas alternar múltiples estilos, puedes vincular la propiedad `[style]` directamente sin el punto (por ejemplo, `[style]="styleExpr"`).
|
||||
La expresión asociada al enlace `[style]` suele ser una lista de string de estilos como `"width: 100px; height: 100px;"`.
|
||||
|
||||
You can also format the expression as an object with style names as the keys and style values as the values, like `{width: '100px', height: '100px'}`.
|
||||
It's important to note that with any object-like expression (`object`, `Array`, `Map`, `Set`, etc), the identity of the object must change for the class list to be updated.
|
||||
Updating the property without changing object identity will have no effect.
|
||||
También se puede formatear la expresión como un objeto con nombres de estilo como claves y valores de estilo como los valores, como `{width: '100px', height: '100px'}`.
|
||||
Es importante tener en cuenta que con cualquier expresión similar a un objeto (`object`, `Array`, `Map`, `Set`, etc), la identidad del objeto debe cambiar para que se actualice la lista de clases.
|
||||
Actualizar la propiedad sin cambiar la identidad del objeto no tendrá ningún efecto.
|
||||
|
||||
If there are multiple bindings to the same style property, conflicts are resolved using [styling precedence rules](#styling-precedence).
|
||||
Si hay varios enlaces a la misma propiedad de estilo, los conflictos se resuelven usando [reglas de precedencia de estilo](#styling-precedence).
|
||||
|
||||
<style>
|
||||
td, th {vertical-align: top}
|
||||
@ -192,33 +186,33 @@ If there are multiple bindings to the same style property, conflicts are resolve
|
||||
</col>
|
||||
<tr>
|
||||
<th>
|
||||
Binding Type
|
||||
Tipo de enlace
|
||||
</th>
|
||||
<th>
|
||||
Syntax
|
||||
Sintaxis
|
||||
</th>
|
||||
<th>
|
||||
Input Type
|
||||
Tipo de entrada
|
||||
</th>
|
||||
<th>
|
||||
Example Input Values
|
||||
Ejemplo de valores de entrada
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Single style binding</td>
|
||||
<td>Enlace de estilo único</td>
|
||||
<td><code>[style.width]="width"</code></td>
|
||||
<td><code>string | undefined | null</code></td>
|
||||
<td><code>"100px"</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<tr>
|
||||
<td>Single style binding with units</td>
|
||||
<td>Enlace de estilo único con unidades</td>
|
||||
<td><code>[style.width.px]="width"</code></td>
|
||||
<td><code>number | undefined | null</code></td>
|
||||
<td><code>100</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan=3>Multi-style binding</td>
|
||||
<td rowspan=3>Enlace de múltiples estilos</td>
|
||||
<td rowspan=3><code>[style]="styleExpr"</code></td>
|
||||
<td><code>string</code></td>
|
||||
<td><code>"width: 100px; height: 100px"</code></td>
|
||||
@ -233,71 +227,71 @@ If there are multiple bindings to the same style property, conflicts are resolve
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
The [NgStyle](guide/built-in-directives/#ngstyle) directive can be used as an alternative to direct `[style]` bindings.
|
||||
However, using the above style binding syntax without `NgStyle` is preferred because due to improvements in style binding in Angular, `NgStyle` no longer provides significant value, and might eventually be removed in the future.
|
||||
La directiva [NgStyle](guide/built-in-directives/#ngstyle) se puede utilizar como alternativa a los enlaces directos `[style]`.
|
||||
Sin embargo, se prefiere usar la sintaxis de enlace de estilos anterior sin `NgStyle` porque debido a las mejoras en el enlace de estilos en Angular, `NgStyle` ya no proporciona un valor significativo y podría eliminarse en el futuro.
|
||||
|
||||
|
||||
<hr/>
|
||||
|
||||
{@a styling-precedence}
|
||||
|
||||
## Styling Precedence
|
||||
## Precedencia de estilo
|
||||
|
||||
A single HTML element can have its CSS class list and style values bound to multiple sources (for example, host bindings from multiple directives).
|
||||
Un único elemento HTML puede tener su lista de clases CSS y valores de estilo vinculados a múltiples fuentes (por ejemplo, enlaces de host de múltiples directivas).
|
||||
|
||||
When there are multiple bindings to the same class name or style property, Angular uses a set of precedence rules to resolve conflicts and determine which classes or styles are ultimately applied to the element.
|
||||
Cuando hay varios enlaces al mismo nombre de clase o propiedad de estilo, Angular usa un conjunto de reglas de precedencia para resolver conflictos y determinar qué clases o estilos se aplican finalmente al elemento.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
<h4>Styling precedence (highest to lowest)</h4>
|
||||
<h4>Precedencia de estilo (de mayor a menor)</h4>
|
||||
|
||||
1. Template bindings
|
||||
1. Property binding (for example, `<div [class.foo]="hasFoo">` or `<div [style.color]="color">`)
|
||||
1. Map binding (for example, `<div [class]="classExpr">` or `<div [style]="styleExpr">`)
|
||||
1. Static value (for example, `<div class="foo">` or `<div style="color: blue">`)
|
||||
1. Directive host bindings
|
||||
1. Property binding (for example, `host: {'[class.foo]': 'hasFoo'}` or `host: {'[style.color]': 'color'}`)
|
||||
1. Map binding (for example, `host: {'[class]': 'classExpr'}` or `host: {'[style]': 'styleExpr'}`)
|
||||
1. Static value (for example, `host: {'class': 'foo'}` or `host: {'style': 'color: blue'}`)
|
||||
1. Component host bindings
|
||||
1. Property binding (for example, `host: {'[class.foo]': 'hasFoo'}` or `host: {'[style.color]': 'color'}`)
|
||||
1. Map binding (for example, `host: {'[class]': 'classExpr'}` or `host: {'[style]': 'styleExpr'}`)
|
||||
1. Static value (for example, `host: {'class': 'foo'}` or `host: {'style': 'color: blue'}`)
|
||||
1. Enlaces de plantillas
|
||||
1. Enlace de propiedad (por ejemplo, `<div [class.foo]="hasFoo">` o `<div [style.color]="color">`)
|
||||
1. Enlace de mapa (por ejemplo, `<div [class]="classExpr">` o `<div [style]="styleExpr">`)
|
||||
1. Valor estático (por ejemplo, `<div class="foo">` o `<div style="color: blue">`)
|
||||
1. Enlaces de directivas hosts
|
||||
1. Enlace de propiedad (por ejemplo, `host: {'[class.foo]': 'hasFoo'}` o `host: {'[style.color]': 'color'}`)
|
||||
1. Enlace de mapa (por ejemplo, `host: {'[class]': 'classExpr'}` o `host: {'[style]': 'styleExpr'}`)
|
||||
1. Valor estático (por ejemplo, `host: {'class': 'foo'}` o `host: {'style': 'color: blue'}`)
|
||||
1. Enlaces de componentes hosts
|
||||
1. Enlace de propiedad (por ejemplo, `host: {'[class.foo]': 'hasFoo'}` o `host: {'[style.color]': 'color'}`)
|
||||
1. Enlace de mapa (por ejemplo, `host: {'[class]': 'classExpr'}` o `host: {'[style]': 'styleExpr'}`)
|
||||
1. Valor estático (por ejemplo, `host: {'class': 'foo'}` o `host: {'style': 'color: blue'}`)
|
||||
|
||||
</div>
|
||||
|
||||
The more specific a class or style binding is, the higher its precedence.
|
||||
Cuanto más específico sea un enlace de clase o estilo, mayor será su precedencia.
|
||||
|
||||
A binding to a specific class (for example, `[class.foo]`) will take precedence over a generic `[class]` binding, and a binding to a specific style (for example, `[style.bar]`) will take precedence over a generic `[style]` binding.
|
||||
Un enlace a una clase específica (por ejemplo, `[class.foo]`) tendrá prioridad sobre un enlace genérico `[class]`, y un enlace a un estilo específico (por ejemplo, `[style.bar]`) tendrá prioridad sobre un enlace genérico `[style]`.
|
||||
|
||||
<code-example path="attribute-binding/src/app/app.component.html" region="basic-specificity" header="src/app/app.component.html"></code-example>
|
||||
|
||||
Specificity rules also apply when it comes to bindings that originate from different sources.
|
||||
It's possible for an element to have bindings in the template where it's declared, from host bindings on matched directives, and from host bindings on matched components.
|
||||
Las reglas de especificidad también se aplican cuando se trata de enlaces que se originan de diferentes fuentes.
|
||||
Es posible que un elemento tenga enlaces en la plantilla donde se declara, desde enlaces de host en directivas coincidentes y desde enlaces de host en componentes coincidentes.
|
||||
|
||||
Template bindings are the most specific because they apply to the element directly and exclusively, so they have the highest precedence.
|
||||
Los enlaces de plantilla son los más específicos porque se aplican al elemento directa y exclusivamente, por lo que tienen la mayor prioridad.
|
||||
|
||||
Directive host bindings are considered less specific because directives can be used in multiple locations, so they have a lower precedence than template bindings.
|
||||
Los enlaces de host de directiva se consideran menos específicos porque las directivas se pueden usar en varias ubicaciones, por lo que tienen una precedencia menor que los enlaces de plantilla.
|
||||
|
||||
Directives often augment component behavior, so host bindings from components have the lowest precedence.
|
||||
Las directivas a menudo aumentan el comportamiento de los componentes, por lo que los enlaces de host de los componentes tienen la prioridad más baja.
|
||||
|
||||
<code-example path="attribute-binding/src/app/app.component.html" region="source-specificity" header="src/app/app.component.html"></code-example>
|
||||
|
||||
In addition, bindings take precedence over static attributes.
|
||||
Además, los enlaces tienen prioridad sobre los atributos estáticos.
|
||||
|
||||
In the following case, `class` and `[class]` have similar specificity, but the `[class]` binding will take precedence because it is dynamic.
|
||||
En el siguiente caso, `class` y `[class]` tienen una especificidad similar, pero el enlace `[class]` tendrá prioridad porque es dinámico.
|
||||
|
||||
<code-example path="attribute-binding/src/app/app.component.html" region="dynamic-priority" header="src/app/app.component.html"></code-example>
|
||||
|
||||
{@a styling-delegation}
|
||||
### Delegating to styles with lower precedence
|
||||
### Delegar a estilos con menor prioridad
|
||||
|
||||
It is possible for higher precedence styles to "delegate" to lower precedence styles using `undefined` values.
|
||||
Whereas setting a style property to `null` ensures the style is removed, setting it to `undefined` will cause Angular to fall back to the next-highest precedence binding to that style.
|
||||
Es posible que los estilos de precedencia más alta "deleguen" a los estilos de precedencia más bajos utilizando valores `undefined`.
|
||||
Mientras que establecer una propiedad de estilo en `null` asegura que el estilo se elimine, establecerlo en `undefined` hará que Angular vuelva al siguiente enlace de precedencia más alto para ese estilo.
|
||||
|
||||
For example, consider the following template:
|
||||
Por ejemplo, considera la siguiente plantilla:
|
||||
|
||||
<code-example path="attribute-binding/src/app/app.component.html" region="style-delegation" header="src/app/app.component.html"></code-example>
|
||||
|
||||
Imagine that the `dirWithHostBinding` directive and the `comp-with-host-binding` component both have a `[style.width]` host binding.
|
||||
In that case, if `dirWithHostBinding` sets its binding to `undefined`, the `width` property will fall back to the value of the `comp-with-host-binding` host binding.
|
||||
However, if `dirWithHostBinding` sets its binding to `null`, the `width` property will be removed entirely.
|
||||
Imagina que la directiva `dirWithHostBinding` y el componente `comp-with-host-binding` tienen un enlace de host `[style.width]`.
|
||||
En ese caso, si `dirWithHostBinding` establece su enlace en `undefined`, la propiedad `width` volverá al valor del enlace de host del componente `comp-with-host-binding`.
|
||||
Sin embargo, si `dirWithHostBinding` establece su enlace en `null`, la propiedad `width` se eliminará por completo.
|
||||
|
174
aio/content/guide/bootstrapping.en.md
Normal file
174
aio/content/guide/bootstrapping.en.md
Normal file
@ -0,0 +1,174 @@
|
||||
# Launching your app with a root module
|
||||
|
||||
#### Prerequisites
|
||||
|
||||
A basic understanding of the following:
|
||||
* [JavaScript Modules vs. NgModules](guide/ngmodule-vs-jsmodule).
|
||||
|
||||
<hr />
|
||||
|
||||
An NgModule describes how the application parts fit together.
|
||||
Every application has at least one Angular module, the _root_ module,
|
||||
which must be present for bootstrapping the application on launch.
|
||||
By convention and by default, this NgModule is named `AppModule`.
|
||||
|
||||
When you use the [Angular CLI](cli) command `ng new` to generate an app, the default `AppModule` is as follows.
|
||||
|
||||
```typescript
|
||||
/* JavaScript imports */
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
/* the AppModule class with the @NgModule decorator */
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
FormsModule,
|
||||
HttpClientModule
|
||||
],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
||||
|
||||
```
|
||||
|
||||
After the import statements is a class with the
|
||||
**`@NgModule`** [decorator](guide/glossary#decorator '"Decorator" explained').
|
||||
|
||||
The `@NgModule` decorator identifies `AppModule` as an `NgModule` class.
|
||||
`@NgModule` takes a metadata object that tells Angular how to compile and launch the application.
|
||||
|
||||
* **_declarations_**—this application's lone component.
|
||||
* **_imports_**—import `BrowserModule` to have browser specific services such as DOM rendering, sanitization, and location.
|
||||
* **_providers_**—the service providers.
|
||||
* **_bootstrap_**—the _root_ component that Angular creates and inserts
|
||||
into the `index.html` host web page.
|
||||
|
||||
The default application created by the Angular CLI only has one component, `AppComponent`, so it
|
||||
is in both the `declarations` and the `bootstrap` arrays.
|
||||
|
||||
{@a declarations}
|
||||
|
||||
## The `declarations` array
|
||||
|
||||
The module's `declarations` array tells Angular which components belong to that module.
|
||||
As you create more components, add them to `declarations`.
|
||||
|
||||
You must declare every component in exactly one `NgModule` class.
|
||||
If you use a component without declaring it, Angular returns an
|
||||
error message.
|
||||
|
||||
The `declarations` array only takes declarables. Declarables
|
||||
are components, [directives](guide/attribute-directives) and [pipes](guide/pipes).
|
||||
All of a module's declarables must be in the `declarations` array.
|
||||
Declarables must belong to exactly one module. The compiler emits
|
||||
an error if you try to declare the same class in more than one module.
|
||||
|
||||
These declared classes are visible within the module but invisible
|
||||
to components in a different module unless they are exported from
|
||||
this module and the other module imports this one.
|
||||
|
||||
An example of what goes into a declarations array follows:
|
||||
|
||||
```typescript
|
||||
declarations: [
|
||||
YourComponent,
|
||||
YourPipe,
|
||||
YourDirective
|
||||
],
|
||||
```
|
||||
|
||||
A declarable can only belong to one module, so only declare it in
|
||||
one `@NgModule`. When you need it elsewhere,
|
||||
import the module that has the declarable you need in it.
|
||||
|
||||
**Only `@NgModule` references** go in the `imports` array.
|
||||
|
||||
|
||||
### Using directives with `@NgModule`
|
||||
|
||||
Use the `declarations` array for directives.
|
||||
To use a directive, component, or pipe in a module, you must do a few things:
|
||||
|
||||
1. Export it from the file where you wrote it.
|
||||
2. Import it into the appropriate module.
|
||||
3. Declare it in the `@NgModule` `declarations` array.
|
||||
|
||||
|
||||
Those three steps look like the following. In the file where you create your directive, export it.
|
||||
The following example, named `ItemDirective` is the default directive structure that the CLI generates in its own file, `item.directive.ts`:
|
||||
|
||||
<code-example path="bootstrapping/src/app/item.directive.ts" region="directive" header="src/app/item.directive.ts"></code-example>
|
||||
|
||||
The key point here is that you have to export it so you can import it elsewhere. Next, import it
|
||||
into the `NgModule`, in this example `app.module.ts`, with a JavaScript import statement:
|
||||
|
||||
<code-example path="bootstrapping/src/app/app.module.ts" region="directive-import" header="src/app/app.module.ts"></code-example>
|
||||
|
||||
And in the same file, add it to the `@NgModule` `declarations` array:
|
||||
|
||||
<code-example path="bootstrapping/src/app/app.module.ts" region="declarations" header="src/app/app.module.ts"></code-example>
|
||||
|
||||
|
||||
Now you could use your `ItemDirective` in a component. This example uses `AppModule`, but you'd do it the same way for a feature module. For more about directives, see [Attribute Directives](guide/attribute-directives) and [Structural Directives](guide/structural-directives). You'd also use the same technique for [pipes](guide/pipes) and components.
|
||||
|
||||
Remember, components, directives, and pipes belong to one module only. You only need to declare them once in your app because you share them by importing the necessary modules. This saves you time and helps keep your app lean.
|
||||
|
||||
|
||||
|
||||
|
||||
{@a imports}
|
||||
|
||||
## The `imports` array
|
||||
|
||||
The module's `imports` array appears exclusively in the `@NgModule` metadata object.
|
||||
It tells Angular about other NgModules that this particular module needs to function properly.
|
||||
|
||||
This list of modules are those that export components, directives, or pipes
|
||||
that the component templates in this module reference. In this case, the component is
|
||||
`AppComponent`, which references components, directives, or pipes in `BrowserModule`,
|
||||
`FormsModule`, or `HttpClientModule`.
|
||||
A component template can reference another component, directive,
|
||||
or pipe when the referenced class is declared in this module or
|
||||
the class was imported from another module.
|
||||
|
||||
{@a bootstrap-array}
|
||||
|
||||
## The `providers` array
|
||||
|
||||
The providers array is where you list the services the app needs. When
|
||||
you list services here, they are available app-wide. You can scope
|
||||
them when using feature modules and lazy loading. For more information, see
|
||||
[Providers](guide/providers).
|
||||
|
||||
## The `bootstrap` array
|
||||
|
||||
The application launches by bootstrapping the root `AppModule`, which is
|
||||
also referred to as an `entryComponent`.
|
||||
Among other things, the bootstrapping process creates the component(s) listed in the `bootstrap` array
|
||||
and inserts each one into the browser DOM.
|
||||
|
||||
Each bootstrapped component is the base of its own tree of components.
|
||||
Inserting a bootstrapped component usually triggers a cascade of
|
||||
component creations that fill out that tree.
|
||||
|
||||
While you can put more than one component tree on a host web page,
|
||||
most applications have only one component tree and bootstrap a single root component.
|
||||
|
||||
This one root component is usually called `AppComponent` and is in the
|
||||
root module's `bootstrap` array.
|
||||
|
||||
|
||||
|
||||
## More about Angular Modules
|
||||
|
||||
For more on NgModules you're likely to see frequently in apps,
|
||||
see [Frequently Used Modules](guide/frequent-ngmodules).
|
@ -1,18 +1,18 @@
|
||||
# Launching your app with a root module
|
||||
# Lanzando tu aplicación con un módulo raíz
|
||||
|
||||
#### Prerequisites
|
||||
#### Pre-requisitos
|
||||
|
||||
A basic understanding of the following:
|
||||
Una comprensión básica de lo siguiente:
|
||||
* [JavaScript Modules vs. NgModules](guide/ngmodule-vs-jsmodule).
|
||||
|
||||
<hr />
|
||||
|
||||
An NgModule describes how the application parts fit together.
|
||||
Every application has at least one Angular module, the _root_ module,
|
||||
which must be present for bootstrapping the application on launch.
|
||||
By convention and by default, this NgModule is named `AppModule`.
|
||||
Un NgModule describe cómo encajan las partes de la aplicación.
|
||||
Cada aplicación tiene al menos un módulo Angular, el módulo _root_,
|
||||
que debe estar presente para arrancar la aplicación en el lanzamiento inicial.
|
||||
Por convención y por defecto, este NgModule se llama `AppModule`.
|
||||
|
||||
When you use the [Angular CLI](cli) command `ng new` to generate an app, the default `AppModule` is as follows.
|
||||
Cuando se usa el comando de [Angular CLI](cli) `ng new` para generar una aplicación, el `AppModule` predeterminado es el siguiente.
|
||||
|
||||
```typescript
|
||||
/* JavaScript imports */
|
||||
@ -40,43 +40,44 @@ export class AppModule { }
|
||||
|
||||
```
|
||||
|
||||
After the import statements is a class with the
|
||||
**`@NgModule`** [decorator](guide/glossary#decorator '"Decorator" explained').
|
||||
Después de las declaraciones de importación hay una clase con
|
||||
[decorador](guide/glossary#decorator 'Explicando "Decorator"') **`@NgModule`**.
|
||||
|
||||
The `@NgModule` decorator identifies `AppModule` as an `NgModule` class.
|
||||
`@NgModule` takes a metadata object that tells Angular how to compile and launch the application.
|
||||
El decorador `@NgModule` identifica `AppModule` como una clase `NgModule`.
|
||||
`@NgModule` toma un objeto de metadatos que le dice a Angular cómo compilar e iniciar la aplicación.
|
||||
|
||||
* **_declarations_**—this application's lone component.
|
||||
* **_imports_**—import `BrowserModule` to have browser specific services such as DOM rendering, sanitization, and location.
|
||||
* **_providers_**—the service providers.
|
||||
* **_bootstrap_**—the _root_ component that Angular creates and inserts
|
||||
into the `index.html` host web page.
|
||||
* **_declarations_**— el único componente de esta aplicación..
|
||||
* **_imports_**— importar `BrowserModule` para tener servicios específicos del navegador como renderizado DOM, sanitization y ubicación.
|
||||
* **_providers_**— los proveedores de servicios.
|
||||
* **_bootstrap_**— el componente raíz que Angular crea e inserta
|
||||
en la página web de host `index.html`.
|
||||
|
||||
The default application created by the Angular CLI only has one component, `AppComponent`, so it
|
||||
is in both the `declarations` and the `bootstrap` arrays.
|
||||
La aplicación predeterminada creada por Angular CLI solo tiene un componente, `AppComponent`, por lo que
|
||||
está en los arrays de `declarations` y `bootstrap`.
|
||||
|
||||
{@a the-declarations-array}
|
||||
{@a declarations}
|
||||
|
||||
## The `declarations` array
|
||||
## El array `declarations`
|
||||
|
||||
The module's `declarations` array tells Angular which components belong to that module.
|
||||
As you create more components, add them to `declarations`.
|
||||
El array de `declarations` le dice a Angular qué componentes pertenecen a ese módulo.
|
||||
A medida que crees más componentes, agrégalos a las `declarations`.
|
||||
|
||||
You must declare every component in exactly one `NgModule` class.
|
||||
If you use a component without declaring it, Angular returns an
|
||||
error message.
|
||||
Debe declarar cada componente en exactamente una clase `NgModule`.
|
||||
Si se usa un componente sin declararlo, Angular devuelve un
|
||||
mensaje de error.
|
||||
|
||||
The `declarations` array only takes declarables. Declarables
|
||||
are components, [directives](guide/attribute-directives) and [pipes](guide/pipes).
|
||||
All of a module's declarables must be in the `declarations` array.
|
||||
Declarables must belong to exactly one module. The compiler emits
|
||||
an error if you try to declare the same class in more than one module.
|
||||
El array `declarations` solo acepta declarables. Declarables pueden ser
|
||||
componentes, [directivas](guide/attribute-directives) y [pipes](guide/pipes).
|
||||
Todos los declarables de un módulo deben estar en el array de `declarations`.
|
||||
Los declarables deben pertenecer exactamente a un módulo. El compilador emite
|
||||
un error si se intenta declarar la misma clase en más de un módulo.
|
||||
|
||||
These declared classes are visible within the module but invisible
|
||||
to components in a different module unless they are exported from
|
||||
this module and the other module imports this one.
|
||||
Estas clases declaradas son visibles dentro del módulo pero invisibles
|
||||
a componentes en un módulo diferente, a menos que se exporten desde
|
||||
éste módulo y el otro módulo importe éste mismo módulo.
|
||||
|
||||
An example of what goes into a declarations array follows:
|
||||
A continuación, se muestra un ejemplo de un array `declarations`:
|
||||
|
||||
```typescript
|
||||
declarations: [
|
||||
@ -86,89 +87,86 @@ An example of what goes into a declarations array follows:
|
||||
],
|
||||
```
|
||||
|
||||
A declarable can only belong to one module, so only declare it in
|
||||
one `@NgModule`. When you need it elsewhere,
|
||||
import the module that has the declarable you need in it.
|
||||
Un declarable solo puede pertenecer a un módulo, por lo que solo debe ser declarado en
|
||||
un `@NgModule`. Cuando se necesite en otro lugar,
|
||||
importa el módulo que tiene el declarable que necesites.
|
||||
|
||||
**Only `@NgModule` references** go in the `imports` array.
|
||||
**Solo las referencias de `@NgModule`** van en el array `imports`.
|
||||
|
||||
|
||||
### Using directives with `@NgModule`
|
||||
### Usando directivas con `@NgModule`
|
||||
|
||||
Use the `declarations` array for directives.
|
||||
To use a directive, component, or pipe in a module, you must do a few things:
|
||||
Usa el array `declarations` para las directivas.
|
||||
Para usar una directiva, un componente o un pipe en un módulo, hay que hacer algunas cosas:
|
||||
|
||||
1. Export it from the file where you wrote it.
|
||||
2. Import it into the appropriate module.
|
||||
3. Declare it in the `@NgModule` `declarations` array.
|
||||
1. Exportarlo desde el archivo donde se escribió.
|
||||
2. Importarlo al módulo apropiado.
|
||||
3. Declararlo en el array `declarations` del `@NgModule`.
|
||||
|
||||
|
||||
Those three steps look like the following. In the file where you create your directive, export it.
|
||||
The following example, named `ItemDirective` is the default directive structure that the CLI generates in its own file, `item.directive.ts`:
|
||||
Esos tres pasos se parecen a los siguientes. En el archivo donde se crea la directiva, expórtalo.
|
||||
El siguiente ejemplo, llamado `ItemDirective` es la estructura de directiva predeterminada que la CLI genera en su propio archivo, `item.directive.ts`:
|
||||
|
||||
<code-example path="bootstrapping/src/app/item.directive.ts" region="directive" header="src/app/item.directive.ts"></code-example>
|
||||
|
||||
The key point here is that you have to export it so you can import it elsewhere. Next, import it
|
||||
into the `NgModule`, in this example `app.module.ts`, with a JavaScript import statement:
|
||||
El punto clave aquí es que se debe exportar para poder importarlo en otro lugar. A continuación, importar
|
||||
en el `NgModule`, en este ejemplo, `app.module.ts` con una declaración de importación de JavaScript:
|
||||
|
||||
<code-example path="bootstrapping/src/app/app.module.ts" region="directive-import" header="src/app/app.module.ts"></code-example>
|
||||
|
||||
And in the same file, add it to the `@NgModule` `declarations` array:
|
||||
Y en el mismo archivo, agregarlo al array `declarations` del `@ NgModule`:
|
||||
|
||||
<code-example path="bootstrapping/src/app/app.module.ts" region="declarations" header="src/app/app.module.ts"></code-example>
|
||||
|
||||
|
||||
Now you could use your `ItemDirective` in a component. This example uses `AppModule`, but you'd do it the same way for a feature module. For more about directives, see [Attribute Directives](guide/attribute-directives) and [Structural Directives](guide/structural-directives). You'd also use the same technique for [pipes](guide/pipes) and components.
|
||||
|
||||
Remember, components, directives, and pipes belong to one module only. You only need to declare them once in your app because you share them by importing the necessary modules. This saves you time and helps keep your app lean.
|
||||
|
||||
Ahora puedes usar tu `ItemDirective` en un componente. Este ejemplo usa `AppModule`, pero se haría de la misma manera para un módulo de funciones. Para obtener más información sobre las directivas, consulta [Directivas de atributos](guide/attribute-directives) y [Directivas estructurales](guide/structural-directives). También se usaría la misma técnica para [pipes](guide/pipes) y componentes.
|
||||
|
||||
Recuerda, los componentes, directivas y pipes pertenecen a un solo módulo. Solo se necesita declararlos una vez en tu aplicación porque se comparten importando los módulos necesarios. Esto ahorra tiempo y ayuda a mantener la aplicación optimizada.
|
||||
|
||||
|
||||
{@a imports}
|
||||
|
||||
## The `imports` array
|
||||
## El array de `imports`
|
||||
|
||||
The module's `imports` array appears exclusively in the `@NgModule` metadata object.
|
||||
It tells Angular about other NgModules that this particular module needs to function properly.
|
||||
El array de `imports` del módulo aparece exclusivamente en el objeto de metadatos del `@NgModule`.
|
||||
Le dice a Angular sobre otros NgModules que este módulo en particular necesita para funcionar correctamente.
|
||||
|
||||
This list of modules are those that export components, directives, or pipes
|
||||
that the component templates in this module reference. In this case, the component is
|
||||
`AppComponent`, which references components, directives, or pipes in `BrowserModule`,
|
||||
`FormsModule`, or `HttpClientModule`.
|
||||
A component template can reference another component, directive,
|
||||
or pipe when the referenced class is declared in this module or
|
||||
the class was imported from another module.
|
||||
Esta lista de módulos son los que exportan componentes, directivas o pipes
|
||||
que las plantillas de componentes en este módulo hacen referencia. En este caso, el componente es
|
||||
`AppComponent`, que hace referencia a componentes, directivas o pipes en `BrowserModule`,
|
||||
`FormsModule`, o `HttpClientModule`.
|
||||
Una plantilla de componente puede hacer referencia a otro componente, directiva,
|
||||
o pipe cuando la clase referenciada se declara en este módulo o
|
||||
la clase se importó de otro módulo.
|
||||
|
||||
{@a bootstrap-array}
|
||||
|
||||
## The `providers` array
|
||||
## El array `providers`
|
||||
|
||||
The providers array is where you list the services the app needs. When
|
||||
you list services here, they are available app-wide. You can scope
|
||||
them when using feature modules and lazy loading. For more information, see
|
||||
[Providers](guide/providers).
|
||||
El array `providers` es donde se enumeran los servicios que necesita la aplicación. Cuando
|
||||
enumera los servicios, están disponibles en toda la aplicación. Puedes reducir el scope
|
||||
al usar módulos de funciones y carga diferida. Para más información, ver
|
||||
[Proveedores](guide/providers).
|
||||
|
||||
## The `bootstrap` array
|
||||
## El array `bootstrap`
|
||||
|
||||
The application launches by bootstrapping the root `AppModule`, which is
|
||||
also referred to as an `entryComponent`.
|
||||
Among other things, the bootstrapping process creates the component(s) listed in the `bootstrap` array
|
||||
and inserts each one into the browser DOM.
|
||||
La aplicación se inicia haciendo bootstraping desde la raíz `AppModule`, que es
|
||||
también conocido como `entryComponent`.
|
||||
Entre otras cosas, el proceso de carga crea los componentes enumerados en el array de `bootstrap`
|
||||
e inserta cada uno en el DOM del navegador.
|
||||
|
||||
Each bootstrapped component is the base of its own tree of components.
|
||||
Inserting a bootstrapped component usually triggers a cascade of
|
||||
component creations that fill out that tree.
|
||||
Cada componente bootstrap es la base de su propio árbol de componentes.
|
||||
La inserción de un componente bootstrapped generalmente desencadena una cascada de
|
||||
creaciones de componentes que completan ese árbol.
|
||||
|
||||
While you can put more than one component tree on a host web page,
|
||||
most applications have only one component tree and bootstrap a single root component.
|
||||
Si bien puedes colocar más de un árbol de componentes en una página web de host,
|
||||
la mayoría de las aplicaciones tienen solo un árbol de componentes y arrancan un solo componente raíz.
|
||||
|
||||
This one root component is usually called `AppComponent` and is in the
|
||||
root module's `bootstrap` array.
|
||||
Este componente raíz se suele llamar `AppComponent` y se encuentra en el
|
||||
array `bootstrap` del módulo raíz.
|
||||
|
||||
|
||||
## Más sobre módulos Angular
|
||||
|
||||
## More about Angular Modules
|
||||
|
||||
For more on NgModules you're likely to see frequently in apps,
|
||||
see [Frequently Used Modules](guide/frequent-ngmodules).
|
||||
Para obtener más información sobre NgModules que probablemente veas con frecuencia en las aplicaciones,
|
||||
consulta [Módulos de uso frecuente](guide/frequent-ngmodules).
|
||||
|
@ -10,7 +10,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><b>platformBrowserDynamic().bootstrapModule</b>(AppModule);</code></td>
|
||||
<td><p>Bootstraps the app, using the root component from the specified <code>NgModule</code>. </p>
|
||||
<td><p>Carga la app, usando el componente raíz del <code>NgModule</code> especificado.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
@ -24,370 +24,371 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>@<b>NgModule</b>({ declarations: ..., imports: ...,<br> exports: ..., providers: ..., bootstrap: ...})<br>class MyModule {}</code></td>
|
||||
<td><p>Defines a module that contains components, directives, pipes, and providers.</p>
|
||||
<td><p>Define un módulo que contiene componentes, directivas, pipes y proveedores.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><b>declarations:</b> [MyRedComponent, MyBlueComponent, MyDatePipe]</code></td>
|
||||
<td><p>List of components, directives, and pipes that belong to this module.</p>
|
||||
<td><p>Lista de componentes, directivas y pipes que pertenecen a este módulo.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><b>imports:</b> [BrowserModule, SomeOtherModule]</code></td>
|
||||
<td><p>List of modules to import into this module. Everything from the imported modules
|
||||
is available to <code>declarations</code> of this module.</p>
|
||||
<td><p>Lista de módulos para importar en este módulo. Todo, desde los módulos importados,
|
||||
está disponible para las declaraciones (<code>declarations</code>) de este módulo.
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><b>exports:</b> [MyRedComponent, MyDatePipe]</code></td>
|
||||
<td><p>List of components, directives, and pipes visible to modules that import this module.</p>
|
||||
<td><p>Lista de componentes, directivas y pipes visibles a los módulos que importan este módulo.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><b>providers:</b> [MyService, { provide: ... }]</code></td>
|
||||
<td><p>List of dependency injection providers visible both to the contents of this module and to importers of this module.</p>
|
||||
<td><p>Lista de proveedores de inyección de dependencias visibles tanto para los contenidos de este módulo como para los importadores de este módulo.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><b>entryComponents:</b> [SomeComponent, OtherComponent]</code></td>
|
||||
<td><p>List of components not referenced in any reachable template, for example dynamically created from code.</p></td>
|
||||
<td><p>Lista de componentes no referenciados en cualquier plantilla accesible, por ejemplo, creada dinámicamente a partir de código.</p></td>
|
||||
</tr><tr>
|
||||
<td><code><b>bootstrap:</b> [MyAppComponent]</code></td>
|
||||
<td><p>List of components to bootstrap when this module is bootstrapped.</p>
|
||||
<td><p>Lista de componentes a empaquetar cuando este módulo se inicia.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
|
||||
<table class="is-full-width is-fixed-layout">
|
||||
<tbody><tr>
|
||||
<th>Template syntax</th>
|
||||
<th>Sintaxis de plantilla</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><input <b>[value]</b>="firstName"></code></td>
|
||||
<td><p>Binds property <code>value</code> to the result of expression <code>firstName</code>.</p>
|
||||
<td><p>Vincula la propiedad <code>value</code> al resultado de la expresión <code>firstName</code>.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><div <b>[attr.role]</b>="myAriaRole"></code></td>
|
||||
<td><p>Binds attribute <code>role</code> to the result of expression <code>myAriaRole</code>.</p>
|
||||
<td><p>Vincula el atributo <code>role</code> al resultado de la expresión <code>myAriaRole</code>.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><div <b>[class.extra-sparkle]</b>="isDelightful"></code></td>
|
||||
<td><p>Binds the presence of the CSS class <code>extra-sparkle</code> on the element to the truthiness of the expression <code>isDelightful</code>.</p>
|
||||
<td><p>Vincula la presencia de la clase CSS <code>extra-sparkle</code> sobre el elemento a la veracidad de la expresión <code>isDelightful</code>.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><div <b>[style.width.px]</b>="mySize"></code></td>
|
||||
<td><p>Binds style property <code>width</code> to the result of expression <code>mySize</code> in pixels. Units are optional.</p>
|
||||
<td><p>Vincula la propiedad de estilo <code>width</code> al resultado de la expresión <code>mySize</code> en píxeles. La unidad de medida es opcional.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><button <b>(click)</b>="readRainbow($event)"></code></td>
|
||||
<td><p>Calls method <code>readRainbow</code> when a click event is triggered on this button element (or its children) and passes in the event object.</p>
|
||||
<td><p>Llama al método <code>readRainbow</code> cuando se lanza un evento click en este elemento botón (o sus hijos) y pasa por argumento el objeto evento.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><div title="Hello <b>{{ponyName}}</b>"></code></td>
|
||||
<td><p>Binds a property to an interpolated string, for example, "Hello Seabiscuit". Equivalent to:
|
||||
<code><div [title]="'Hello ' + ponyName"></code></p>
|
||||
<td><code><div title="Hola <b>{{ponyName}}</b>"></code></td>
|
||||
<td><p>Vincula una propiedad a una cadena interpolada, por ejemplo, "Hola Seabiscuit". Equivalente a:
|
||||
<code><div [title]="'Hola ' + ponyName"></code></p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><p>Hello <b>{{ponyName}}</b></p></code></td>
|
||||
<td><p>Binds text content to an interpolated string, for example, "Hello Seabiscuit".</p>
|
||||
<td><code><p>Hola <b>{{ponyName}}</b></p></code></td>
|
||||
<td><p>Vincula el contenido de texto a una cadena interpolada, por ejemplo, "Hola Seabiscuit".</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><my-cmp <b>[(title)]</b>="name"></code></td>
|
||||
<td><p>Sets up two-way data binding. Equivalent to: <code><my-cmp [title]="name" (titleChange)="name=$event"></code></p>
|
||||
<td><p>Establece el two-way data binding. Equivalente a: <code><my-cmp [title]="name" (titleChange)="name=$event"></code></p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><video <b>#movieplayer</b> ...><br> <button <b>(click)</b>="movieplayer.play()"><br></video></code></td>
|
||||
<td><p>Creates a local variable <code>movieplayer</code> that provides access to the <code>video</code> element instance in data-binding and event-binding expressions in the current template.</p>
|
||||
<td><p>Crea una variable local <code>movieplayer</code> que provee acceso a la instancia del elemento <code>video</code> en las expresiones de data-binding y event-binding de la actual plantilla.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><p <b>*myUnless</b>="myExpression">...</p></code></td>
|
||||
<td><p>The <code>*</code> symbol turns the current element into an embedded template. Equivalent to:
|
||||
<td><p>El símbolo <code>*</code> convierte el elemento actual en una plantilla incrustada. Equivalente a:
|
||||
<code><ng-template [myUnless]="myExpression"><p>...</p></ng-template></code></p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><p>Card No.: <b>{{cardNumber | myCardNumberFormatter}}</b></p></code></td>
|
||||
<td><p>Transforms the current value of expression <code>cardNumber</code> via the pipe called <code>myCardNumberFormatter</code>.</p>
|
||||
<td><p>Transforma el valor actual de la expresión <code>cardNumber</code> a través de la pipe <code>myCardNumberFormatter</code>.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><p>Employer: <b>{{employer?.companyName}}</b></p></code></td>
|
||||
<td><p>The safe navigation operator (<code>?</code>) means that the <code>employer</code> field is optional and if <code>undefined</code>, the rest of the expression should be ignored.</p>
|
||||
<td><p>El operador de navegación seguro (<code>?</code>) significa que el campo <code>employer</code> es opcional y que si es <code>undefined</code>, el resto de la expresión debería ser ignorado.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><<b>svg:</b>rect x="0" y="0" width="100" height="100"/></code></td>
|
||||
<td><p>An SVG snippet template needs an <code>svg:</code> prefix on its root element to disambiguate the SVG element from an HTML component.</p>
|
||||
<td><p>Una plantilla de fragmento SVG necesita un prefijo <code>svg:</code> en su elemento raíz para distinguir el elemento SVG de un componente HTML.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><<b>svg</b>><br> <rect x="0" y="0" width="100" height="100"/><br></<b>svg</b>></code></td>
|
||||
<td><p>An <code><svg></code> root element is detected as an SVG element automatically, without the prefix.</p>
|
||||
<td><p>Un elemento raíz <code><svg></code> es detectado como un elemento SVG automáticamente, sin el prefijo.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
|
||||
<table class="is-full-width is-fixed-layout">
|
||||
<tbody><tr>
|
||||
<th>Built-in directives</th>
|
||||
<th>Directivas incorporadas</th>
|
||||
<th><p><code>import { CommonModule } from '@angular/common';</code>
|
||||
</p>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><section <b>*ngIf</b>="showSection"></code></td>
|
||||
<td><p>Removes or recreates a portion of the DOM tree based on the <code>showSection</code> expression.</p>
|
||||
<td><p>Elimina o recrea una parte del árbol DOM basado en la expresión <code>showSection</code>.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><li <b>*ngFor</b>="let item of list"></code></td>
|
||||
<td><p>Turns the li element and its contents into a template, and uses that to instantiate a view for each item in list.</p>
|
||||
<td><p>Convierte el elemento li y su contenido en una plantilla, y lo utiliza para crear una vista por cada elemento de la lista.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><div <b>[ngSwitch]</b>="conditionExpression"><br> <ng-template <b>[<b>ngSwitchCase</b>]</b>="case1Exp">...</ng-template><br> <ng-template <b>ngSwitchCase</b>="case2LiteralString">...</ng-template><br> <ng-template <b>ngSwitchDefault</b>>...</ng-template><br></div></code></td>
|
||||
<td><p>Conditionally swaps the contents of the div by selecting one of the embedded templates based on the current value of <code>conditionExpression</code>.</p>
|
||||
<td><p>Intercambia condicionalmente el contenido del div seleccionando una de las plantillas incrustadas en función del valor actual de <code>conditionExpression</code>.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><div <b>[ngClass]</b>="{'active': isActive, 'disabled': isDisabled}"></code></td>
|
||||
<td><p>Binds the presence of CSS classes on the element to the truthiness of the associated map values. The right-hand expression should return {class-name: true/false} map.</p>
|
||||
<td><p>Vincula la presencia de clases CSS en el elemento a la veracidad de los valores de mapa asociados. La expresión de la derecha debería devolver el mapa {class-name: true/false}.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><div <b>[ngStyle]</b>="{'property': 'value'}"></code><br><code><div <b>[ngStyle]</b>="dynamicStyles()"></code></td>
|
||||
<td><p>Allows you to assign styles to an HTML element using CSS. You can use CSS directly, as in the first example, or you can call a method from the component.</p>
|
||||
<p>Te permite asignar estilos a un elemento HTML usando CSS. Puedes usar CSS directamente, como en el primer ejemplo, o puedes llamar a un método desde el componente.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
|
||||
<table class="is-full-width is-fixed-layout">
|
||||
<tbody><tr>
|
||||
<th>Forms</th>
|
||||
<th>Formularios</th>
|
||||
<th><p><code>import { FormsModule } from '@angular/forms';</code>
|
||||
</p>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><input <b>[(ngModel)]</b>="userName"></code></td>
|
||||
<td><p>Provides two-way data-binding, parsing, and validation for form controls.</p>
|
||||
<td><p>Provee two-way data-binding, conversión y validación para controles de formulario.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
|
||||
<table class="is-full-width is-fixed-layout">
|
||||
<tbody><tr>
|
||||
<th>Class decorators</th>
|
||||
<th>Decoradores de clases</th>
|
||||
<th><p><code>import { Directive, ... } from '@angular/core';</code>
|
||||
</p>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><b>@Component({...})</b><br>class MyComponent() {}</code></td>
|
||||
<td><p>Declares that a class is a component and provides metadata about the component.</p>
|
||||
<td><p>Declara que una clase es un componente y proporciona metadatos sobre el componente.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><b>@Directive({...})</b><br>class MyDirective() {}</code></td>
|
||||
<td><p>Declares that a class is a directive and provides metadata about the directive.</p>
|
||||
<td><p>Declara que una clase es una directiva y proporciona metadatos sobre la directiva.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><b>@Pipe({...})</b><br>class MyPipe() {}</code></td>
|
||||
<td><p>Declares that a class is a pipe and provides metadata about the pipe.</p>
|
||||
<td><p>Declara que una clase es una pipe y proporciona metadatos sobre la pipe.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><b>@Injectable()</b><br>class MyService() {}</code></td>
|
||||
<td><p>Declares that a class can be provided and injected by other classes. Without this decorator, the compiler won't generate enough metadata to allow the class to be created properly when it's injected somewhere.</p>
|
||||
<td><p>Declara que una clase puede ser proporcionada e inyectada por otras clases. Sin este decorador, el compilador no generará suficientes metadatos para permitir que la clase se cree correctamente cuando se inyecta en alguna parte.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
|
||||
<table class="is-full-width is-fixed-layout">
|
||||
<tbody><tr>
|
||||
<th>Directive configuration</th>
|
||||
<th>Configuración de Directiva</th>
|
||||
<th><p><code>@Directive({ property1: value1, ... })</code>
|
||||
</p>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><b>selector:</b> '.cool-button:not(a)'</code></td>
|
||||
<td><p>Specifies a CSS selector that identifies this directive within a template. Supported selectors include <code>element</code>,
|
||||
<td><p>Especifica un selector CSS que identifica esta directiva dentro de una plantilla. Los selectores compatibles incluyen <code>element</code>,
|
||||
<code>[attribute]</code>, <code>.class</code>, and <code>:not()</code>.</p>
|
||||
<p>Does not support parent-child relationship selectors.</p>
|
||||
<p>No soporta selectores de relación padre-hijo.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><b>providers:</b> [MyService, { provide: ... }]</code></td>
|
||||
<td><p>List of dependency injection providers for this directive and its children.</p>
|
||||
<td><p>Lista de proveedores de inyección de dependencia para esta directiva y sus hijos.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
|
||||
<table class="is-full-width is-fixed-layout">
|
||||
<tbody><tr>
|
||||
<th>Component configuration</th>
|
||||
<th>Configuración de Componente</th>
|
||||
<th><p>
|
||||
<code>@Component</code> extends <code>@Directive</code>,
|
||||
so the <code>@Directive</code> configuration applies to components as well</p>
|
||||
<code>@Component</code> extiende <code>@Directive</code>,
|
||||
entonces la configuración de <code>@Directive</code> se aplica también a los componentes</p>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><b>moduleId:</b> module.id</code></td>
|
||||
<td><p>If set, the <code>templateUrl</code> and <code>styleUrl</code> are resolved relative to the component.</p>
|
||||
<td><p>Si está presente, el <code>templateUrl</code> y <code>styleUrl</code> se resuelven en relación con el componente.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><b>viewProviders:</b> [MyService, { provide: ... }]</code></td>
|
||||
<td><p>List of dependency injection providers scoped to this component's view.</p>
|
||||
<td><p>Lista de proveedores de inyección de dependencias en la vista de este componente.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><b>template:</b> 'Hello {{name}}'<br><b>templateUrl:</b> 'my-component.html'</code></td>
|
||||
<td><p>Inline template or external template URL of the component's view.</p>
|
||||
<td><code><b>template:</b> 'Hola {{name}}'<br><b>templateUrl:</b> 'my-component.html'</code></td>
|
||||
<td><p>Plantilla en línea o URL de plantilla externa de la vista del componente.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><b>styles:</b> ['.primary {color: red}']<br><b>styleUrls:</b> ['my-component.css']</code></td>
|
||||
<td><p>List of inline CSS styles or external stylesheet URLs for styling the component’s view.</p>
|
||||
<td><p>Lista de estilos CSS en línea o URL de hojas de estilo externas para estilar la vista del componente.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
|
||||
<table class="is-full-width is-fixed-layout">
|
||||
<tbody><tr>
|
||||
<th>Class field decorators for directives and components</th>
|
||||
<th>Decoradores para los campos de la clase para directivas y componentes.</th>
|
||||
<th><p><code>import { Input, ... } from '@angular/core';</code>
|
||||
</p>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><b>@Input()</b> myProperty;</code></td>
|
||||
<td><p>Declares an input property that you can update via property binding (example:
|
||||
<td><p>Declara una propiedad de entrada (input) que puede actualizar mediante el enlace de propiedad (property binding) (ejemplo:
|
||||
<code><my-cmp [myProperty]="someExpression"></code>).</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><b>@Output()</b> myEvent = new EventEmitter();</code></td>
|
||||
<td><p>Declares an output property that fires events that you can subscribe to with an event binding (example: <code><my-cmp (myEvent)="doSomething()"></code>).</p>
|
||||
<td><p>Declara una propiedad de salida (output) que dispara eventos a los que puedes suscribirse con un enlace de evento (event binding) (ejemplo: <code><my-cmp (myEvent)="doSomething()"></code>).</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><b>@HostBinding('class.valid')</b> isValid;</code></td>
|
||||
<td><p>Binds a host element property (here, the CSS class <code>valid</code>) to a directive/component property (<code>isValid</code>).</p>
|
||||
<td><p>Vincula una propiedad del elemento anfitrión (aquí, la clase CSS <code>valid</code>) a una propiedad de directiva/componente (<code>isValid</code>).</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><b>@HostListener('click', ['$event'])</b> onClick(e) {...}</code></td>
|
||||
<td><p>Subscribes to a host element event (<code>click</code>) with a directive/component method (<code>onClick</code>), optionally passing an argument (<code>$event</code>).</p>
|
||||
<td><p>Se suscribe a un evento del elemento anfitrión (<code>click</code>) con un método de directiva/componente (<code>onClick</code>), opcionalmente, pasando un argumento (<code>$event</code>).</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><b>@ContentChild(myPredicate)</b> myChildComponent;</code></td>
|
||||
<td><p>Binds the first result of the component content query (<code>myPredicate</code>) to a property (<code>myChildComponent</code>) of the class.</p>
|
||||
<td><p>Vincula el primer resultado de la consulta de contenido del componente (<code>myPredicate</code>) a una propiedad (<code>myChildComponent</code>) de la clase.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><b>@ContentChildren(myPredicate)</b> myChildComponents;</code></td>
|
||||
<td><p>Binds the results of the component content query (<code>myPredicate</code>) to a property (<code>myChildComponents</code>) of the class.</p>
|
||||
<td><p>Vincula los resultados de la consulta de contenido del componente (<code>myPredicate</code>) a una propiedad (<code>myChildComponents</code>) de la clase.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><b>@ViewChild(myPredicate)</b> myChildComponent;</code></td>
|
||||
<td><p>Binds the first result of the component view query (<code>myPredicate</code>) to a property (<code>myChildComponent</code>) of the class. Not available for directives.</p>
|
||||
<td><p>Vincula el primer resultado de la consulta de vista del componente (<code>myPredicate</code>) a una propiedad (<code>myChildComponent</code>) de la clase. No disponible para directivas.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><b>@ViewChildren(myPredicate)</b> myChildComponents;</code></td>
|
||||
<td><p>Binds the results of the component view query (<code>myPredicate</code>) to a property (<code>myChildComponents</code>) of the class. Not available for directives.</p>
|
||||
<td><p>Vincula los resultados de la consulta de vista del componente (<code>myPredicate</code>) a una propiedad (<code>myChildComponents</code>) de la clase. No disponible para directivas.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
|
||||
<table class="is-full-width is-fixed-layout">
|
||||
<tbody><tr>
|
||||
<th>Directive and component change detection and lifecycle hooks</th>
|
||||
<th><p>(implemented as class methods)
|
||||
|
||||
<th>Detección de cambios (change detection) y ciclos de vida (lifecycle hooks) en directivas y componentes</th>
|
||||
<th><p>(implementado como métodos de clase)
|
||||
</p>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><b>constructor(myService: MyService, ...)</b> { ... }</code></td>
|
||||
<td><p>Called before any other lifecycle hook. Use it to inject dependencies, but avoid any serious work here.</p>
|
||||
<td><p>Se llama antes que cualquier ciclo de vida. Úselo para inyectar dependencias, pero evite cualquier trabajo serio aquí.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><b>ngOnChanges(changeRecord)</b> { ... }</code></td>
|
||||
<td><p>Called after every change to input properties and before processing content or child views.</p>
|
||||
<td><p>Se llama después de cada cambio en las propiedades de entrada (input) y antes de procesar contenido o vistas de hijos.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><b>ngOnInit()</b> { ... }</code></td>
|
||||
<td><p>Called after the constructor, initializing input properties, and the first call to <code>ngOnChanges</code>.</p>
|
||||
<td><p>Se llama después del constructor, inicializando propiedades de entrada (input), y la primera llamada a <code>ngOnChanges</code>.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><b>ngDoCheck()</b> { ... }</code></td>
|
||||
<td><p>Called every time that the input properties of a component or a directive are checked. Use it to extend change detection by performing a custom check.</p>
|
||||
<td><p>Se llama cada vez que se verifican las propiedades de entrada (input) de un componente o una directiva. Úselo para extender la detección de cambios (change detection) realizando una verificación personalizada.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><b>ngAfterContentInit()</b> { ... }</code></td>
|
||||
<td><p>Called after <code>ngOnInit</code> when the component's or directive's content has been initialized.</p>
|
||||
<td><p>Se llama después de <code>ngOnInit</code> cuando el contenido del componente o directiva ha sido inicializado.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><b>ngAfterContentChecked()</b> { ... }</code></td>
|
||||
<td><p>Called after every check of the component's or directive's content.</p>
|
||||
<td><p>Se llama después de cada verificación del contenido del componente o directiva.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><b>ngAfterViewInit()</b> { ... }</code></td>
|
||||
<td><p>Called after <code>ngAfterContentInit</code> when the component's views and child views / the view that a directive is in has been initialized.</p>
|
||||
<td><p>Se llama después de <code>ngAfterContentInit</code> cuando las vistas del componente y las vistas hijas / la vista en la que se encuentra una directiva ha sido inicializado.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><b>ngAfterViewChecked()</b> { ... }</code></td>
|
||||
<td><p>Called after every check of the component's views and child views / the view that a directive is in.</p>
|
||||
<td><p>Se llama después de cada verificación de las vistas del componentes y las vistas hijas / la vista en la que se encuentra una directiva.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><b>ngOnDestroy()</b> { ... }</code></td>
|
||||
<td><p>Called once, before the instance is destroyed.</p>
|
||||
<td><p>Se llama una vez, antes de que la instancia se destruya.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
|
||||
<table class="is-full-width is-fixed-layout">
|
||||
<tbody><tr>
|
||||
<th>Dependency injection configuration</th>
|
||||
<th>Configuración de inyección de dependencia</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>{ <b>provide</b>: MyService, <b>useClass</b>: MyMockService }</code></td>
|
||||
<td><p>Sets or overrides the provider for <code>MyService</code> to the <code>MyMockService</code> class.</p>
|
||||
<td><p>Establece o sobre-escribe el proveedor para <code>MyService</code> en la clase <code>MyMockService</code>.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code>{ <b>provide</b>: MyService, <b>useFactory</b>: myFactory }</code></td>
|
||||
<td><p>Sets or overrides the provider for <code>MyService</code> to the <code>myFactory</code> factory function.</p>
|
||||
<td><p>Establece o sobre-escribe el proveedor para <code>MyService</code> en la factoría de función <code>myFactory</code>.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code>{ <b>provide</b>: MyValue, <b>useValue</b>: 41 }</code></td>
|
||||
<td><p>Sets or overrides the provider for <code>MyValue</code> to the value <code>41</code>.</p>
|
||||
<td><p>Establece o sobre-escribe el proveedor para <code>MyValue</code> al valor <code>41</code>.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
|
||||
<table class="is-full-width is-fixed-layout">
|
||||
<tbody><tr>
|
||||
<th>Routing and navigation</th>
|
||||
<th>Enrutamiento y navegación</th>
|
||||
<th><p><code>import { Routes, RouterModule, ... } from '@angular/router';</code>
|
||||
</p>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>const routes: <b>Routes</b> = [<br> { path: '', component: HomeComponent },<br> { path: 'path/:routeParam', component: MyComponent },<br> { path: 'staticPath', component: ... },<br> { path: '**', component: ... },<br> { path: 'oldPath', redirectTo: '/staticPath' },<br> { path: ..., component: ..., data: { message: 'Custom' } }<br>]);<br><br>const routing = RouterModule.forRoot(routes);</code></td>
|
||||
<td><p>Configures routes for the application. Supports static, parameterized, redirect, and wildcard routes. Also supports custom route data and resolve.</p>
|
||||
<td><p>Configura rutas para la aplicación. Soporta rutas estáticas, parametrizadas, de redireccionamiento y comodines. También soporta datos de ruta personalizados y los resuelve.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><br><<b>router-outlet</b>></<b>router-outlet</b>><br><<b>router-outlet</b> name="aux"></<b>router-outlet</b>><br></code></td>
|
||||
<td><p>Marks the location to load the component of the active route.</p>
|
||||
<td><p>Marca la ubicación para cargar el componente de la ruta activa.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><br><a routerLink="/path"><br><a <b>[routerLink]</b>="[ '/path', routeParam ]"><br><a <b>[routerLink]</b>="[ '/path', { matrixParam: 'value' } ]"><br><a <b>[routerLink]</b>="[ '/path' ]" [queryParams]="{ page: 1 }"><br><a <b>[routerLink]</b>="[ '/path' ]" fragment="anchor"><br></code></td>
|
||||
<td><p>Creates a link to a different view based on a route instruction consisting of a route path, required and optional parameters, query parameters, and a fragment. To navigate to a root route, use the <code>/</code> prefix; for a child route, use the <code>./</code>prefix; for a sibling or parent, use the <code>../</code> prefix.</p>
|
||||
<td><p>Crea un enlace a una vista diferente basada en una instrucción de ruta que consta de un camino de de ruta, parámetros obligatorios y opcionales, parámetros de consulta y un fragmento. Para navegar a un camino de ruta, usa el prefijo <code>/</code>; para una ruta hija, usa el prefijo <code>./</code>; para un padre o hermano, usa el prefijo <code>../</code>.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code><a [routerLink]="[ '/path' ]" routerLinkActive="active"></code></td>
|
||||
<td><p>The provided classes are added to the element when the <code>routerLink</code> becomes the current active route.</p>
|
||||
<td><p>Las clases proporcionadas se agregan al elemento cuando el <code>routerLink</code> se convierte en la ruta activa actual.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code>class <b>CanActivate</b>Guard implements <b>CanActivate</b> {<br> canActivate(<br> route: ActivatedRouteSnapshot,<br> state: RouterStateSnapshot<br> ): Observable<boolean|UrlTree>|Promise<boolean|UrlTree>|boolean|UrlTree { ... }<br>}<br><br>{ path: ..., canActivate: [<b>CanActivate</b>Guard] }</code></td>
|
||||
<td><p>An interface for defining a class that the router should call first to determine if it should activate this component. Should return a boolean|UrlTree or an Observable/Promise that resolves to a boolean|UrlTree.</p>
|
||||
<td><p>Una interfaz para definir una clase que el enrutador debe llamar primero para determinar si debe activar este componente. Debe devolver un boolean|UrlTree o un Observable/Promise que se resuelba en un boolean|UrlTree.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code>class <b>CanDeactivate</b>Guard implements <b>CanDeactivate</b><T> {<br> canDeactivate(<br> component: T,<br> route: ActivatedRouteSnapshot,<br> state: RouterStateSnapshot<br> ): Observable<boolean|UrlTree>|Promise<boolean|UrlTree>|boolean|UrlTree { ... }<br>}<br><br>{ path: ..., canDeactivate: [<b>CanDeactivate</b>Guard] }</code></td>
|
||||
<td><p>An interface for defining a class that the router should call first to determine if it should deactivate this component after a navigation. Should return a boolean|UrlTree or an Observable/Promise that resolves to a boolean|UrlTree.</p>
|
||||
<td><p>Una interfaz para definir una clase que el enrutador debería llamar primero para determinar si debería desactivar este componente después de una navegación. Debe devolver un boolean|UrlTree o un Observable/Promise que se resuelva a boolean|UrlTree.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code>class <b>CanActivateChild</b>Guard implements <b>CanActivateChild</b> {<br> canActivateChild(<br> route: ActivatedRouteSnapshot,<br> state: RouterStateSnapshot<br> ): Observable<boolean|UrlTree>|Promise<boolean|UrlTree>|boolean|UrlTree { ... }<br>}<br><br>{ path: ..., canActivateChild: [CanActivateGuard],<br> children: ... }</code></td>
|
||||
<td><p>An interface for defining a class that the router should call first to determine if it should activate the child route. Should return a boolean|UrlTree or an Observable/Promise that resolves to a boolean|UrlTree.</p>
|
||||
<td><p>Una interfaz para definir una clase que el enrutador debe llamar primero para determinar si debe activar la ruta hija. Debe devolver un boolean|UrlTree o un Observable/Promise que se resuelva en un boolean|UrlTree.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code>class <b>Resolve</b>Guard implements <b>Resolve</b><T> {<br> resolve(<br> route: ActivatedRouteSnapshot,<br> state: RouterStateSnapshot<br> ): Observable<any>|Promise<any>|any { ... }<br>}<br><br>{ path: ..., resolve: [<b>Resolve</b>Guard] }</code></td>
|
||||
<td><p>An interface for defining a class that the router should call first to resolve route data before rendering the route. Should return a value or an Observable/Promise that resolves to a value.</p>
|
||||
<td><p>Una interfaz para definir una clase que el enrutador debe llamar primero para resolver los datos de la ruta antes de representar la ruta. Debe devolver un valor o un Observable/Promise que se resuelva en un valor.</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td><code>class <b>CanLoad</b>Guard implements <b>CanLoad</b> {<br> canLoad(<br> route: Route<br> ): Observable<boolean|UrlTree>|Promise<boolean|UrlTree>|boolean|UrlTree { ... }<br>}<br><br>{ path: ..., canLoad: [<b>CanLoad</b>Guard], loadChildren: ... }</code></td>
|
||||
<td><p>An interface for defining a class that the router should call first to check if the lazy loaded module should be loaded. Should return a boolean|UrlTree or an Observable/Promise that resolves to a boolean|UrlTree.</p>
|
||||
<td><p>Una interfaz para definir una clase a la que el enrutador debe llamar primero para verificar si el módulo perezoso cargado (lazy loaded module) debe cargarse. Debe devolver un boolean|UrlTree o un Observable/Promise que se resuelva en un boolean|UrlTree.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
|
318
aio/content/guide/comparing-observables.en.md
Normal file
318
aio/content/guide/comparing-observables.en.md
Normal file
@ -0,0 +1,318 @@
|
||||
# Observables compared to other techniques
|
||||
|
||||
You can often use observables instead of promises to deliver values asynchronously. Similarly, observables can take the place of event handlers. Finally, because observables deliver multiple values, you can use them where you might otherwise build and operate on arrays.
|
||||
|
||||
Observables behave somewhat differently from the alternative techniques in each of these situations, but offer some significant advantages. Here are detailed comparisons of the differences.
|
||||
|
||||
## Observables compared to promises
|
||||
|
||||
Observables are often compared to promises. Here are some key differences:
|
||||
|
||||
* Observables are declarative; computation does not start until subscription. Promises execute immediately on creation. This makes observables useful for defining recipes that can be run whenever you need the result.
|
||||
|
||||
* Observables provide many values. Promises provide one. This makes observables useful for getting multiple values over time.
|
||||
|
||||
* Observables differentiate between chaining and subscription. Promises only have `.then()` clauses. This makes observables useful for creating complex transformation recipes to be used by other part of the system, without causing the work to be executed.
|
||||
|
||||
* Observables `subscribe()` is responsible for handling errors. Promises push errors to the child promises. This makes observables useful for centralized and predictable error handling.
|
||||
|
||||
|
||||
### Creation and subscription
|
||||
|
||||
* Observables are not executed until a consumer subscribes. The `subscribe()` executes the defined behavior once, and it can be called again. Each subscription has its own computation. Resubscription causes recomputation of values.
|
||||
|
||||
<code-example
|
||||
path="comparing-observables/src/observables.ts"
|
||||
header="src/observables.ts (observable)"
|
||||
region="observable">
|
||||
</code-example>
|
||||
|
||||
* Promises execute immediately, and just once. The computation of the result is initiated when the promise is created. There is no way to restart work. All `then` clauses (subscriptions) share the same computation.
|
||||
|
||||
<code-example
|
||||
path="comparing-observables/src/promises.ts"
|
||||
header="src/promises.ts (promise)"
|
||||
region="promise">
|
||||
</code-example>
|
||||
|
||||
### Chaining
|
||||
|
||||
* Observables differentiate between transformation function such as a map and subscription. Only subscription activates the subscriber function to start computing the values.
|
||||
|
||||
<code-example
|
||||
path="comparing-observables/src/observables.ts"
|
||||
header="src/observables.ts (chain)"
|
||||
region="chain">
|
||||
</code-example>
|
||||
|
||||
* Promises do not differentiate between the last `.then` clauses (equivalent to subscription) and intermediate `.then` clauses (equivalent to map).
|
||||
|
||||
<code-example
|
||||
path="comparing-observables/src/promises.ts"
|
||||
header="src/promises.ts (chain)"
|
||||
region="chain">
|
||||
</code-example>
|
||||
|
||||
### Cancellation
|
||||
|
||||
* Observable subscriptions are cancellable. Unsubscribing removes the listener from receiving further values, and notifies the subscriber function to cancel work.
|
||||
|
||||
<code-example
|
||||
path="comparing-observables/src/observables.ts"
|
||||
header="src/observables.ts (unsubcribe)"
|
||||
region="unsubscribe">
|
||||
</code-example>
|
||||
|
||||
* Promises are not cancellable.
|
||||
|
||||
### Error handling
|
||||
|
||||
* Observable execution errors are delivered to the subscriber's error handler, and the subscriber automatically unsubscribes from the observable.
|
||||
|
||||
<code-example
|
||||
path="comparing-observables/src/observables.ts"
|
||||
header="src/observables.ts (error)"
|
||||
region="error">
|
||||
</code-example>
|
||||
|
||||
* Promises push errors to the child promises.
|
||||
|
||||
<code-example
|
||||
path="comparing-observables/src/promises.ts"
|
||||
header="src/promises.ts (error)"
|
||||
region="error">
|
||||
</code-example>
|
||||
|
||||
### Cheat sheet
|
||||
|
||||
The following code snippets illustrate how the same kind of operation is defined using observables and promises.
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Operation</th>
|
||||
<th>Observable</th>
|
||||
<th>Promise</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Creation</td>
|
||||
<td>
|
||||
<pre>
|
||||
new Observable((observer) => {
|
||||
observer.next(123);
|
||||
});</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre>
|
||||
new Promise((resolve, reject) => {
|
||||
resolve(123);
|
||||
});</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Transform</td>
|
||||
<td><pre>obs.pipe(map((value) => value * 2));</pre></td>
|
||||
<td><pre>promise.then((value) => value * 2);</pre></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Subscribe</td>
|
||||
<td>
|
||||
<pre>
|
||||
sub = obs.subscribe((value) => {
|
||||
console.log(value)
|
||||
});</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre>
|
||||
promise.then((value) => {
|
||||
console.log(value);
|
||||
});</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Unsubscribe</td>
|
||||
<td><pre>sub.unsubscribe();</pre></td>
|
||||
<td>Implied by promise resolution.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Observables compared to events API
|
||||
|
||||
Observables are very similar to event handlers that use the events API. Both techniques define notification handlers, and use them to process multiple values delivered over time. Subscribing to an observable is equivalent to adding an event listener. One significant difference is that you can configure an observable to transform an event before passing the event to the handler.
|
||||
|
||||
Using observables to handle events and asynchronous operations can have the advantage of greater consistency in contexts such as HTTP requests.
|
||||
|
||||
Here are some code samples that illustrate how the same kind of operation is defined using observables and the events API.
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Observable</th>
|
||||
<th>Events API</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Creation & cancellation</td>
|
||||
<td>
|
||||
<pre>// Setup
|
||||
let clicks$ = fromEvent(buttonEl, ‘click’);
|
||||
// Begin listening
|
||||
let subscription = clicks$
|
||||
.subscribe(e => console.log(‘Clicked’, e))
|
||||
// Stop listening
|
||||
subscription.unsubscribe();</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre>function handler(e) {
|
||||
console.log(‘Clicked’, e);
|
||||
}
|
||||
// Setup & begin listening
|
||||
button.addEventListener(‘click’, handler);
|
||||
// Stop listening
|
||||
button.removeEventListener(‘click’, handler);
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Subscription</td>
|
||||
<td>
|
||||
<pre>observable.subscribe(() => {
|
||||
// notification handlers here
|
||||
});</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre>element.addEventListener(eventName, (event) => {
|
||||
// notification handler here
|
||||
});</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Configuration</td>
|
||||
<td>Listen for keystrokes, but provide a stream representing the value in the input.
|
||||
<pre>fromEvent(inputEl, 'keydown').pipe(
|
||||
map(e => e.target.value)
|
||||
);</pre>
|
||||
</td>
|
||||
<td>Does not support configuration.
|
||||
<pre>element.addEventListener(eventName, (event) => {
|
||||
// Cannot change the passed Event into another
|
||||
// value before it gets to the handler
|
||||
});</pre>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
## Observables compared to arrays
|
||||
|
||||
An observable produces values over time. An array is created as a static set of values. In a sense, observables are asynchronous where arrays are synchronous. In the following examples, ➞ implies asynchronous value delivery.
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Observable</th>
|
||||
<th>Array</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Given</td>
|
||||
<td>
|
||||
<pre>obs: ➞1➞2➞3➞5➞7</pre>
|
||||
<pre>obsB: ➞'a'➞'b'➞'c'</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre>arr: [1, 2, 3, 5, 7]</pre>
|
||||
<pre>arrB: ['a', 'b', 'c']</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><pre>concat()</pre></td>
|
||||
<td>
|
||||
<pre>concat(obs, obsB)</pre>
|
||||
<pre>➞1➞2➞3➞5➞7➞'a'➞'b'➞'c'</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre>arr.concat(arrB)</pre>
|
||||
<pre>[1,2,3,5,7,'a','b','c']</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><pre>filter()</pre></td>
|
||||
<td>
|
||||
<pre>obs.pipe(filter((v) => v>3))</pre>
|
||||
<pre>➞5➞7</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre>arr.filter((v) => v>3)</pre>
|
||||
<pre>[5, 7]</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><pre>find()</pre></td>
|
||||
<td>
|
||||
<pre>obs.pipe(find((v) => v>3))</pre>
|
||||
<pre>➞5</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre>arr.find((v) => v>3)</pre>
|
||||
<pre>5</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><pre>findIndex()</pre></td>
|
||||
<td>
|
||||
<pre>obs.pipe(findIndex((v) => v>3))</pre>
|
||||
<pre>➞3</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre>arr.findIndex((v) => v>3)</pre>
|
||||
<pre>3</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><pre>forEach()</pre></td>
|
||||
<td>
|
||||
<pre>obs.pipe(tap((v) => {
|
||||
console.log(v);
|
||||
}))
|
||||
1
|
||||
2
|
||||
3
|
||||
5
|
||||
7</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre>arr.forEach((v) => {
|
||||
console.log(v);
|
||||
})
|
||||
1
|
||||
2
|
||||
3
|
||||
5
|
||||
7</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><pre>map()</pre></td>
|
||||
<td>
|
||||
<pre>obs.pipe(map((v) => -v))</pre>
|
||||
<pre>➞-1➞-2➞-3➞-5➞-7</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre>arr.map((v) => -v)</pre>
|
||||
<pre>[-1, -2, -3, -5, -7]</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><pre>reduce()</pre></td>
|
||||
<td>
|
||||
<pre>obs.pipe(reduce((s,v)=> s+v, 0))</pre>
|
||||
<pre>➞18</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre>arr.reduce((s,v) => s+v, 0)</pre>
|
||||
<pre>18</pre>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
@ -1,25 +1,24 @@
|
||||
# Observables compared to other techniques
|
||||
# Observables en comparación con otras técnicas
|
||||
|
||||
You can often use observables instead of promises to deliver values asynchronously. Similarly, observables can take the place of event handlers. Finally, because observables deliver multiple values, you can use them where you might otherwise build and operate on arrays.
|
||||
A menudo puedes usar observables en lugar de promesas para entregar valores de forma asíncrona. Del mismo modo, los observables pueden reemplazar a los controladores de eventos. Finalmente, porque los observables entregan múltiples valores, puedes usarlos donde de otro modo podrías construir y operar con arrays.
|
||||
|
||||
Observables behave somewhat differently from the alternative techniques in each of these situations, but offer some significant advantages. Here are detailed comparisons of the differences.
|
||||
Los observables se comportan de manera algo diferente a las técnicas alternativas en cada una de estas situaciones, pero ofrecen algunas ventajas significativas. Aquí hay comparaciones detalladas de las diferencias.
|
||||
|
||||
## Observables compared to promises
|
||||
## Observables en comparación con promesas
|
||||
|
||||
Observables are often compared to promises. Here are some key differences:
|
||||
Los observables a menudo se comparan con las promesas. Aquí hay algunas diferencias clave:
|
||||
|
||||
* Observables are declarative; computation does not start until subscription. Promises execute immediately on creation. This makes observables useful for defining recipes that can be run whenever you need the result.
|
||||
* Los observables son declarativos; La ejecución no comienza hasta la suscripción. Las promesas se ejecutan inmediatamente después de la creación. Esto hace que los observables sean útiles para definir recetas que se pueden ejecutar cuando necesites el resultado.
|
||||
|
||||
* Observables provide many values. Promises provide one. This makes observables useful for getting multiple values over time.
|
||||
* Los observables proporcionan muchos valores. Las promesas proporcionan un valor. Esto hace que los observables sean útiles para obtener múltiples valores a lo largo del tiempo.
|
||||
|
||||
* Observables differentiate between chaining and subscription. Promises only have `.then()` clauses. This makes observables useful for creating complex transformation recipes to be used by other part of the system, without causing the work to be executed.
|
||||
* Los observables diferencian entre encadenamiento y suscripción. Las promesas solo tienen cláusulas `.then ()`. Esto hace que los observables sean útiles para crear recetas de transformación complejas para ser utilizadas por otra parte del sistema, sin que el trabajo se ejecute.
|
||||
|
||||
* Observables `subscribe()` is responsible for handling errors. Promises push errors to the child promises. This makes observables useful for centralized and predictable error handling.
|
||||
* Observables `subscribe()` es responsable de manejar los errores. Las promesas empujan los errores a promesas hijas. Esto hace que los observables sean útiles para el manejo centralizado y predecible de errores.
|
||||
|
||||
### Creación y suscripción
|
||||
|
||||
### Creation and subscription
|
||||
|
||||
* Observables are not executed until a consumer subscribes. The `subscribe()` executes the defined behavior once, and it can be called again. Each subscription has its own computation. Resubscription causes recomputation of values.
|
||||
* Los observables no se ejecutan hasta que un consumidor se suscribe. El `subscribe()` ejecuta el comportamiento definido una vez, y se puede volver a llamar. Cada suscripción tiene su propia computación. La resuscripción provoca la recomputación de los valores.
|
||||
|
||||
<code-example
|
||||
path="comparing-observables/src/observables.ts"
|
||||
@ -27,7 +26,7 @@ Observables are often compared to promises. Here are some key differences:
|
||||
region="observable">
|
||||
</code-example>
|
||||
|
||||
* Promises execute immediately, and just once. The computation of the result is initiated when the promise is created. There is no way to restart work. All `then` clauses (subscriptions) share the same computation.
|
||||
* Las promesas se ejecutan de inmediato, y solo una vez. La computación del resultado se inicia cuando se crea la promesa. No hay forma de reiniciar el trabajo. Todas las cláusulas `then` (suscripciones) comparten la misma computación.
|
||||
|
||||
<code-example
|
||||
path="comparing-observables/src/promises.ts"
|
||||
@ -35,9 +34,9 @@ Observables are often compared to promises. Here are some key differences:
|
||||
region="promise">
|
||||
</code-example>
|
||||
|
||||
### Chaining
|
||||
### Encadenamiento
|
||||
|
||||
* Observables differentiate between transformation function such as a map and subscription. Only subscription activates the subscriber function to start computing the values.
|
||||
* Los observables diferencian entre la función de transformación, como `map` y `subscription`. Solo la suscripción activa la función de suscriptor para comenzar a calcular los valores.
|
||||
|
||||
<code-example
|
||||
path="comparing-observables/src/observables.ts"
|
||||
@ -45,7 +44,7 @@ Observables are often compared to promises. Here are some key differences:
|
||||
region="chain">
|
||||
</code-example>
|
||||
|
||||
* Promises do not differentiate between the last `.then` clauses (equivalent to subscription) and intermediate `.then` clauses (equivalent to map).
|
||||
* Las promesas no diferencian entre las últimas cláusulas `.then` (equivalentes al subscription) y las cláusulas intermedias `.then` (equivalentes al map).
|
||||
|
||||
<code-example
|
||||
path="comparing-observables/src/promises.ts"
|
||||
@ -53,9 +52,9 @@ Observables are often compared to promises. Here are some key differences:
|
||||
region="chain">
|
||||
</code-example>
|
||||
|
||||
### Cancellation
|
||||
### Cancelación
|
||||
|
||||
* Observable subscriptions are cancellable. Unsubscribing removes the listener from receiving further values, and notifies the subscriber function to cancel work.
|
||||
* Las suscripciones de los observables son cancelables. La cancelación de la suscripción evita que el oyente reciba más valores y notifica a la función del suscriptor que cancele el trabajo.
|
||||
|
||||
<code-example
|
||||
path="comparing-observables/src/observables.ts"
|
||||
@ -63,11 +62,11 @@ Observables are often compared to promises. Here are some key differences:
|
||||
region="unsubscribe">
|
||||
</code-example>
|
||||
|
||||
* Promises are not cancellable.
|
||||
* Las promesas no son cancelables.
|
||||
|
||||
### Error handling
|
||||
### Manejo de errores
|
||||
|
||||
* Observable execution errors are delivered to the subscriber's error handler, and the subscriber automatically unsubscribes from the observable.
|
||||
* Los errores de ejecución en observables se entregan al controlador de errores del suscriptor, y el suscriptor cancela automáticamente la suscripción del observable.
|
||||
|
||||
<code-example
|
||||
path="comparing-observables/src/observables.ts"
|
||||
@ -75,7 +74,7 @@ Observables are often compared to promises. Here are some key differences:
|
||||
region="error">
|
||||
</code-example>
|
||||
|
||||
* Promises push errors to the child promises.
|
||||
* Las promesas empujan los errores a las promesas hijas.
|
||||
|
||||
<code-example
|
||||
path="comparing-observables/src/promises.ts"
|
||||
@ -83,9 +82,9 @@ Observables are often compared to promises. Here are some key differences:
|
||||
region="error">
|
||||
</code-example>
|
||||
|
||||
### Cheat sheet
|
||||
### Hoja de trucos
|
||||
|
||||
The following code snippets illustrate how the same kind of operation is defined using observables and promises.
|
||||
Los siguientes fragmentos de código ilustran cómo se define el mismo tipo de operación utilizando observables y promesas.
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
@ -139,13 +138,13 @@ promise.then((value) => {
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Observables compared to events API
|
||||
## Observables en comparación con eventos API
|
||||
|
||||
Observables are very similar to event handlers that use the events API. Both techniques define notification handlers, and use them to process multiple values delivered over time. Subscribing to an observable is equivalent to adding an event listener. One significant difference is that you can configure an observable to transform an event before passing the event to the handler.
|
||||
Los observables son muy similares a los controladores de eventos que usan la API de eventos. Ambas técnicas definen manejadores de notificaciones y las utilizan para procesar múltiples valores entregados a lo largo del tiempo. Suscribirse a un observable es equivalente a agregar un detector de eventos. Una diferencia significativa es que puedes configurar un observable para transformar un evento antes de pasar el evento al controlador.
|
||||
|
||||
Using observables to handle events and asynchronous operations can have the advantage of greater consistency in contexts such as HTTP requests.
|
||||
El uso de observables para manejar eventos y operaciones asíncronas puede tener la ventaja de una mayor coherencia en contextos como las solicitudes HTTP.
|
||||
|
||||
Here are some code samples that illustrate how the same kind of operation is defined using observables and the events API.
|
||||
Aquí hay algunos ejemplos de código que ilustran cómo se define el mismo tipo de operación usando observables y la API de eventos.
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
@ -205,9 +204,9 @@ button.removeEventListener(‘click’, handler);
|
||||
</table>
|
||||
|
||||
|
||||
## Observables compared to arrays
|
||||
## Observables en comparación con arrays
|
||||
|
||||
An observable produces values over time. An array is created as a static set of values. In a sense, observables are asynchronous where arrays are synchronous. In the following examples, ➞ implies asynchronous value delivery.
|
||||
Un observable produce valores a lo largo del tiempo. Se crea un array como un conjunto estático de valores. En cierto sentido, los observables son asíncronos mientras que los arrays son síncronos. En los siguientes ejemplos, ➞ implica entrega de valor asíncrono.
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
|
104
aio/content/guide/complex-animation-sequences.en.md
Normal file
104
aio/content/guide/complex-animation-sequences.en.md
Normal file
@ -0,0 +1,104 @@
|
||||
# Complex animation sequences
|
||||
|
||||
#### Prerequisites
|
||||
|
||||
A basic understanding of the following concepts:
|
||||
|
||||
* [Introduction to Angular animations](guide/animations)
|
||||
* [Transition and triggers](guide/transition-and-triggers)
|
||||
|
||||
<hr>
|
||||
|
||||
So far, we've learned simple animations of single HTML elements. Angular also lets you animate coordinated sequences, such as an entire grid or list of elements as they enter and leave a page. You can choose to run multiple animations in parallel, or run discrete animations sequentially, one following another.
|
||||
|
||||
Functions that control complex animation sequences are as follows:
|
||||
|
||||
* `query()` finds one or more inner HTML elements.
|
||||
* `stagger()` applies a cascading delay to animations for multiple elements.
|
||||
* [`group()`](api/animations/group) runs multiple animation steps in parallel.
|
||||
* `sequence()` runs animation steps one after another.
|
||||
|
||||
{@a complex-sequence}
|
||||
|
||||
## Animate multiple elements using query() and stagger() functions
|
||||
|
||||
The `query()` function allows you to find inner elements within the element that is being animated. This function targets specific HTML elements within a parent component and applies animations to each element individually. Angular intelligently handles setup, teardown, and cleanup as it coordinates the elements across the page.
|
||||
|
||||
The `stagger()` function allows you to define a timing gap between each queried item that is animated and thus animates elements with a delay between them.
|
||||
|
||||
The Filter/Stagger tab in the live example shows a list of heroes with an introductory sequence. The entire list of heroes cascades in, with a slight delay from top to bottom.
|
||||
|
||||
The following example demonstrates how to use `query()` and `stagger()` functions on the entry of an animated element.
|
||||
|
||||
* Use `query()` to look for an element entering the page that meets certain criteria.
|
||||
|
||||
* For each of these elements, use `style()` to set the same initial style for the element. Make it invisible and use `transform` to move it out of position so that it can slide into place.
|
||||
|
||||
* Use `stagger()` to delay each animation by 30 milliseconds.
|
||||
|
||||
* Animate each element on screen for 0.5 seconds using a custom-defined easing curve, simultaneously fading it in and un-transforming it.
|
||||
|
||||
<code-example path="animations/src/app/hero-list-page.component.ts" header="src/app/hero-list-page.component.ts" region="page-animations" language="typescript"></code-example>
|
||||
|
||||
## Parallel animation using group() function
|
||||
|
||||
You've seen how to add a delay between each successive animation. But you may also want to configure animations that happen in parallel. For example, you may want to animate two CSS properties of the same element but use a different `easing` function for each one. For this, you can use the animation [`group()`](api/animations/group) function.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
**Note:** The [`group()`](api/animations/group) function is used to group animation *steps*, rather than animated elements.
|
||||
</div>
|
||||
|
||||
In the following example, using groups on both `:enter` and `:leave` allow for two different timing configurations. They're applied to the same element in parallel, but run independently.
|
||||
|
||||
<code-example path="animations/src/app/hero-list-groups.component.ts" region="animationdef" header="src/app/hero-list-groups.component.ts (excerpt)" language="typescript"></code-example>
|
||||
|
||||
## Sequential vs. parallel animations
|
||||
|
||||
Complex animations can have many things happening at once. But what if you want to create an animation involving several animations happening one after the other? Earlier we used [`group()`](api/animations/group) to run multiple animations all at the same time, in parallel.
|
||||
|
||||
A second function called `sequence()` lets you run those same animations one after the other. Within `sequence()`, the animation steps consist of either `style()` or `animate()` function calls.
|
||||
|
||||
* Use `style()` to apply the provided styling data immediately.
|
||||
* Use `animate()` to apply styling data over a given time interval.
|
||||
|
||||
## Filter animation example
|
||||
|
||||
Let's take a look at another animation on the live example page. Under the Filter/Stagger tab, enter some text into the **Search Heroes** text box, such as `Magnet` or `tornado`.
|
||||
|
||||
The filter works in real time as you type. Elements leave the page as you type each new letter and the filter gets progressively stricter. The heroes list gradually re-enters the page as you delete each letter in the filter box.
|
||||
|
||||
The HTML template contains a trigger called `filterAnimation`.
|
||||
|
||||
<code-example path="animations/src/app/hero-list-page.component.html" header="src/app/hero-list-page.component.html" region="filter-animations"></code-example>
|
||||
|
||||
The component file contains three transitions.
|
||||
|
||||
<code-example path="animations/src/app/hero-list-page.component.ts" header="src/app/hero-list-page.component.ts" region="filter-animations" language="typescript"></code-example>
|
||||
|
||||
The animation does the following:
|
||||
|
||||
* Ignores any animations that are performed when the user first opens or navigates to this page. The filter narrows what is already there, so it assumes that any HTML elements to be animated already exist in the DOM.
|
||||
|
||||
* Performs a filter match for matches.
|
||||
|
||||
For each match:
|
||||
|
||||
* Hides the element by making it completely transparent and infinitely narrow, by setting its opacity and width to 0.
|
||||
|
||||
* Animates in the element over 300 milliseconds. During the animation, the element assumes its default width and opacity.
|
||||
|
||||
* If there are multiple matching elements, staggers in each element starting at the top of the page, with a 50-millisecond delay between each element.
|
||||
|
||||
## Animation sequence summary
|
||||
|
||||
Angular functions for animating multiple elements start with `query()` to find inner elements, for example gathering all images within a `<div>`. The remaining functions, `stagger()`, [`group()`](api/animations/group), and `sequence()`, apply cascades or allow you to control how multiple animation steps are applied.
|
||||
|
||||
## More on Angular animations
|
||||
|
||||
You may also be interested in the following:
|
||||
|
||||
* [Introduction to Angular animations](guide/animations)
|
||||
* [Transition and triggers](guide/transition-and-triggers)
|
||||
* [Reusable animations](guide/reusable-animations)
|
||||
* [Route transition animations](guide/route-animations)
|
@ -1,104 +1,105 @@
|
||||
# Complex animation sequences
|
||||
# Secuencias de animación complejas
|
||||
|
||||
#### Prerequisites
|
||||
#### Requisitos
|
||||
|
||||
A basic understanding of the following concepts:
|
||||
Una comprensión básica de los siguientes conceptos:
|
||||
|
||||
* [Introduction to Angular animations](guide/animations)
|
||||
* [Transition and triggers](guide/transition-and-triggers)
|
||||
- [Introducción a animaciones Angular](guide/animations)
|
||||
- [Transición y triggers](guide/transition-and-triggers)
|
||||
|
||||
<hr>
|
||||
|
||||
So far, we've learned simple animations of single HTML elements. Angular also lets you animate coordinated sequences, such as an entire grid or list of elements as they enter and leave a page. You can choose to run multiple animations in parallel, or run discrete animations sequentially, one following another.
|
||||
Hasta ahora, hemos aprendido animaciones simples de elementos HTML individuales. Angular también te permite animar secuencias coordinadas, como un grid completo o una lista de elementos cuando entran y salen de una página. Puedes elegir ejecutar varias animaciones en paralelo, o ejecutar animaciones discretas secuencialmente, una tras otra.
|
||||
|
||||
Functions that control complex animation sequences are as follows:
|
||||
Las funciones que controlan secuencias de animación complejas son las siguientes:
|
||||
|
||||
* `query()` finds one or more inner HTML elements.
|
||||
* `stagger()` applies a cascading delay to animations for multiple elements.
|
||||
* [`group()`](api/animations/group) runs multiple animation steps in parallel.
|
||||
* `sequence()` runs animation steps one after another.
|
||||
- `query()` encuentra uno o más elementos HTML internos.
|
||||
- `stagger()` aplica un retraso en cascada a las animaciones para varios elementos.
|
||||
- [`group()`](api/animations/group) ejecuta varios pasos de animación en paralelo.
|
||||
- `sequence()` ejecuta pasos de animación uno tras otro.
|
||||
|
||||
{@a complex-sequence}
|
||||
|
||||
## Animate multiple elements using query() and stagger() functions
|
||||
## Animar varios elementos usando las funciones query() y stagger()
|
||||
|
||||
The `query()` function allows you to find inner elements within the element that is being animated. This function targets specific HTML elements within a parent component and applies animations to each element individually. Angular intelligently handles setup, teardown, and cleanup as it coordinates the elements across the page.
|
||||
La función `query()` permite encontrar elementos internos dentro del elemento que estás animando. Esta función se dirige a elementos HTML específicos dentro de un componente principal y aplica animaciones a cada elemento individualmente. Angular maneja de manera inteligente la configuración, el desmontaje y la limpieza a medida que coordina los elementos en la página.
|
||||
|
||||
The `stagger()` function allows you to define a timing gap between each queried item that is animated and thus animates elements with a delay between them.
|
||||
La función `stagger()` permite definir un intervalo de tiempo entre cada elemento consultado que está animado y, por lo tanto, anima elementos con un retraso entre ellos.
|
||||
|
||||
The Filter/Stagger tab in the live example shows a list of heroes with an introductory sequence. The entire list of heroes cascades in, with a slight delay from top to bottom.
|
||||
La pestaña Filter/Stagger en el ejemplo en vivo muestra una lista de héroes con una secuencia introductoria. La lista completa de héroes entra en cascada, con un ligero retraso de arriba a abajo.
|
||||
|
||||
The following example demonstrates how to use `query()` and `stagger()` functions on the entry of an animated element.
|
||||
El siguiente ejemplo demuestra cómo utilizar las funciones `query()` y `stagger()` en la entrada de un elemento animado.
|
||||
|
||||
* Use `query()` to look for an element entering the page that meets certain criteria.
|
||||
- Usa `query()` para buscar un elemento que ingrese a la página que cumpla con ciertos criterios.
|
||||
|
||||
* For each of these elements, use `style()` to set the same initial style for the element. Make it invisible and use `transform` to move it out of position so that it can slide into place.
|
||||
- Para cada uno de estos elementos, usa `style()` para establecer el mismo estilo inicial para el elemento. Hazlo invisible y usa `transform` para moverlo fuera de su posición para que pueda deslizarse a su lugar.
|
||||
|
||||
* Use `stagger()` to delay each animation by 30 milliseconds.
|
||||
- Usa `stagger()` para retrasar cada animación en 30 milisegundos.
|
||||
|
||||
* Animate each element on screen for 0.5 seconds using a custom-defined easing curve, simultaneously fading it in and un-transforming it.
|
||||
- Anima cada elemento en la pantalla durante 0,5 segundos utilizando una curva de easing (suavizado) definida a medida, desvaneciéndolo y deshaciéndolo simultáneamente.
|
||||
|
||||
<code-example path="animations/src/app/hero-list-page.component.ts" header="src/app/hero-list-page.component.ts" region="page-animations" language="typescript"></code-example>
|
||||
|
||||
## Parallel animation using group() function
|
||||
## Animación paralela usando la función group()
|
||||
|
||||
You've seen how to add a delay between each successive animation. But you may also want to configure animations that happen in parallel. For example, you may want to animate two CSS properties of the same element but use a different `easing` function for each one. For this, you can use the animation [`group()`](api/animations/group) function.
|
||||
Has visto cómo agregar un retraso entre cada animación sucesiva. Pero es posible que también quieras configurar animaciones que suceden en paralelo. Por ejemplo, es posible que quieras animar dos propiedades CSS del mismo elemento pero utilizar una función de `easing` diferente para cada una. Para ello, puedes utilizar la función de animación [`group()`](api/animations/group).
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
**Note:** The [`group()`](api/animations/group) function is used to group animation *steps*, rather than animated elements.
|
||||
**Nota:** La función [`group()`](api/animations/group) se usa para agrupar _pasos_ de animación, en lugar de elementos animados.
|
||||
|
||||
</div>
|
||||
|
||||
In the following example, using groups on both `:enter` and `:leave` allow for two different timing configurations. They're applied to the same element in parallel, but run independently.
|
||||
En el siguiente ejemplo, el uso de grupos tanto en `:enter` como en `:leave` permite dos configuraciones de tiempo diferentes. Se aplican al mismo elemento en paralelo, pero se ejecutan de forma independiente.
|
||||
|
||||
<code-example path="animations/src/app/hero-list-groups.component.ts" region="animationdef" header="src/app/hero-list-groups.component.ts (excerpt)" language="typescript"></code-example>
|
||||
|
||||
## Sequential vs. parallel animations
|
||||
## Animaciones secuenciales vs paralelas
|
||||
|
||||
Complex animations can have many things happening at once. But what if you want to create an animation involving several animations happening one after the other? Earlier we used [`group()`](api/animations/group) to run multiple animations all at the same time, in parallel.
|
||||
Las animaciones complejas pueden tener muchas cosas sucediendo a la vez. Pero, ¿qué sucede si quieres crear una animación que involucre varias animaciones sucediendo una tras otra? Anteriormente usamos [`group()`](api/animations/group) para ejecutar múltiples animaciones al mismo tiempo, en paralelo.
|
||||
|
||||
A second function called `sequence()` lets you run those same animations one after the other. Within `sequence()`, the animation steps consist of either `style()` or `animate()` function calls.
|
||||
Una segunda función llamada `sequence()` permite ejecutar esas mismas animaciones una tras otra. Dentro de `sequence()`, los pasos de la animación consisten en llamadas de función `style()` o `animate()`
|
||||
|
||||
* Use `style()` to apply the provided styling data immediately.
|
||||
* Use `animate()` to apply styling data over a given time interval.
|
||||
- Usa `style()` para aplicar los datos de estilo proporcionados inmediatamente.
|
||||
- Usa `animate()` para aplicar datos de estilo en un intervalo de tiempo determinado.
|
||||
|
||||
## Filter animation example
|
||||
## Ejemplo de animación de filtro
|
||||
|
||||
Let's take a look at another animation on the live example page. Under the Filter/Stagger tab, enter some text into the **Search Heroes** text box, such as `Magnet` or `tornado`.
|
||||
Echemos un vistazo a otra animación en la página de ejemplo. En la pestaña Filter/Stagger, ingresa un texto en el cuadro de texto **Search Heroes**, como `Magnet` o `tornado`.
|
||||
|
||||
The filter works in real time as you type. Elements leave the page as you type each new letter and the filter gets progressively stricter. The heroes list gradually re-enters the page as you delete each letter in the filter box.
|
||||
El filtro funciona en tiempo real a medida que escribe. Los elementos abandonan la página a medida que escribe cada nueva letra y el filtro se vuelve progresivamente más estricto. La lista de héroes vuelve a entrar gradualmente en la página a medida que eliminas cada letra en la caja de filtro.
|
||||
|
||||
The HTML template contains a trigger called `filterAnimation`.
|
||||
La plantilla HTML contiene un trigger llamado `filterAnimation`.
|
||||
|
||||
<code-example path="animations/src/app/hero-list-page.component.html" header="src/app/hero-list-page.component.html" region="filter-animations"></code-example>
|
||||
|
||||
The component file contains three transitions.
|
||||
El archivo del componente contiene tres transiciones.
|
||||
|
||||
<code-example path="animations/src/app/hero-list-page.component.ts" header="src/app/hero-list-page.component.ts" region="filter-animations" language="typescript"></code-example>
|
||||
|
||||
The animation does the following:
|
||||
La animación hace lo siguiente:
|
||||
|
||||
* Ignores any animations that are performed when the user first opens or navigates to this page. The filter narrows what is already there, so it assumes that any HTML elements to be animated already exist in the DOM.
|
||||
- Ignora las animaciones que se realizan cuando el usuario abre o navega por primera vez a esta página. El filtro reduce lo que ya está allí, por lo que asume que los elementos HTML que se van a animar ya existen en el DOM.
|
||||
|
||||
* Performs a filter match for matches.
|
||||
- Realiza un filtro de coincidencia.
|
||||
|
||||
For each match:
|
||||
Para cada coincidencia:
|
||||
|
||||
* Hides the element by making it completely transparent and infinitely narrow, by setting its opacity and width to 0.
|
||||
- Oculta el elemento haciéndolo completamente transparente e infinitamente estrecho, estableciendo su opacidad y ancho en 0.
|
||||
|
||||
* Animates in the element over 300 milliseconds. During the animation, the element assumes its default width and opacity.
|
||||
- Anima el elemento más de 300 milisegundos. Durante la animación, el elemento asume su ancho y opacidad predeterminados.
|
||||
|
||||
* If there are multiple matching elements, staggers in each element starting at the top of the page, with a 50-millisecond delay between each element.
|
||||
- Si hay varios elementos coincidentes, se escalona en cada elemento comenzando en la parte superior de la página, con un retraso de 50 milisegundos entre cada elemento.
|
||||
|
||||
## Animation sequence summary
|
||||
## Resumen de la secuencia de animación
|
||||
|
||||
Angular functions for animating multiple elements start with `query()` to find inner elements, for example gathering all images within a `<div>`. The remaining functions, `stagger()`, [`group()`](api/animations/group), and `sequence()`, apply cascades or allow you to control how multiple animation steps are applied.
|
||||
Las funciones Angular para animar múltiples elementos comienzan con `query()` para encontrar elementos internos, por ejemplo, reuniendo todas las imágenes dentro de un `<div>`. Las funciones restantes, `stagger()`, [`group()`](api/animations/group) y `sequence()`, aplican cascadas o te permiten controlar cómo se aplican múltiples pasos de animación.
|
||||
|
||||
## More on Angular animations
|
||||
## Más sobre animaciones en Angular
|
||||
|
||||
You may also be interested in the following:
|
||||
También puedes estar interesado en lo siguiente:
|
||||
|
||||
* [Introduction to Angular animations](guide/animations)
|
||||
* [Transition and triggers](guide/transition-and-triggers)
|
||||
* [Reusable animations](guide/reusable-animations)
|
||||
* [Route transition animations](guide/route-animations)
|
||||
- [Introducción a animaciones Angular](guide/animations)
|
||||
- [Transición y triggers](guide/transition-and-triggers)
|
||||
- [Animaicones reusables](guide/reusable-animations)
|
||||
- [Animaciones en transición de ruta](guide/route-animations)
|
||||
|
247
aio/content/guide/creating-libraries.es.md
Normal file
247
aio/content/guide/creating-libraries.es.md
Normal file
@ -0,0 +1,247 @@
|
||||
# Creando librerías
|
||||
|
||||
Está pagina provee una vista conceptual de como puedes crear y publicar nuevas librerías para extender las funcionalidades de Angular.
|
||||
|
||||
Si necesitas resolver el mismo problema en mas de una aplicación (o quiere compartir tu solución con otros desarrolladores), tienes un candidato para una librería.
|
||||
Un ejemplo simple puede ser un botón que envía a los usuarios hacia el sitio web de tu empresa, que sería incluido en todas las aplicaciones que tu empresa crea.
|
||||
|
||||
## Empezando
|
||||
|
||||
Usa el Angular CLI para generar un nuevo esqueleto de librería, en nuevo espacio de trabajo con los siguiente comandos.
|
||||
|
||||
<code-example language="bash">
|
||||
ng new my-workspace --create-application=false
|
||||
cd my-workspace
|
||||
ng generate library my-lib
|
||||
</code-example>
|
||||
|
||||
El comando `ng generate` crea la carpeta `projects/my-lib` en el espacio de trabajo, que contiene un componente y un servicio dentro de un NgModule.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
Para más detalles sobre como una librería es estructurada, refiérase a los [Archivos de Librería](guide/file-structure#library-project-files) en la sección de [Guía de estructura de archivos](guide/file-structure).
|
||||
|
||||
Puedes usar un modelo de monorepo para usar el mismo espacio de trabajo con multiples proyectos. Véase [Configuración para espacio de trabajo multiproyecto](guide/file-structure#multiple-projects).
|
||||
|
||||
</div>
|
||||
|
||||
Cuando se genera una nueva librería, el archivo de configuración del espacio de trabajo, `angular.json`, es actualizado con un proyecto de tipo 'library'.
|
||||
|
||||
<code-example format="json">
|
||||
"projects": {
|
||||
...
|
||||
"my-lib": {
|
||||
"root": "projects/my-lib",
|
||||
"sourceRoot": "projects/my-lib/src",
|
||||
"projectType": "library",
|
||||
"prefix": "lib",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-ng-packagr:build",
|
||||
...
|
||||
</code-example>
|
||||
|
||||
Puedes crear, probar y comprobar con los comandos de CLI:
|
||||
|
||||
<code-example language="bash">
|
||||
ng build my-lib
|
||||
ng test my-lib
|
||||
ng lint my-lib
|
||||
</code-example>
|
||||
|
||||
Puedes notar que el constructor configurado para el proyecto es diferente que el constructor por defecto para proyectos.
|
||||
El constructor, entre otras cosas, asegura que la librería siempre este construida con el [compilador AOT](guide/aot-compiler), sin la necesidad de especificar la bandera `--prod`.
|
||||
|
||||
Para hacer el código de la librería reusable debes definir una API pública para ella. Esta "capa de usuario" define que esta disponible para los consumidores de tu librería. Un usuario de tu librería debería ser capaz de acceder a la funcionalidad publica (como NgModules, servicios, proveedores y en general funciones de utilidad) mediante una sola ruta.
|
||||
|
||||
La API pública para tu librería es mantenida en el archivo `public-api.ts` en tu carpeta de librería.
|
||||
Cualquier cosa exportada desde este archivo se hace publica cuando tu librería es importada dentro de una aplicación.
|
||||
Usa un NgModule para exponer los servicios y componentes.
|
||||
|
||||
Tu libería debería suministrar documentatión (típicamente en el archivo README) para la instalación y mantenimiento.
|
||||
|
||||
## Refactorizando partes de una app dentro de un librería
|
||||
|
||||
Para hacer tu solución reusable, necesitas ajustarla para que no dependa del código específico de la aplicación.
|
||||
Aquí algunas cosas para considerar al migrar la funcionalidad de la aplicación a una librería.
|
||||
|
||||
* Declaraciones tales como componentes y pipes deberían ser diseñados como 'stateless' (sin estado), lo que significa que no dependen ni alteran variables externas. Si tu dependes del estado, necesitas evaluar cada caso y decidir el estado de la aplicación o el estado que la aplicación administraría.
|
||||
|
||||
* Cualquier observable al cual los componentes se suscriban internamente deberían ser limpiados y desechados durante el ciclo de vida de esos componentes.
|
||||
|
||||
* Los componentes deberían exponer sus interacciones a través de 'inputs' para proporcionar contexto y 'outputs' para comunicar los eventos hacia otros componentes.
|
||||
|
||||
* Verifique todas las dependencias internas.
|
||||
* Para clases personalizadas o interfaces usadas en componentes o servicios, verifique si dependen en clases adicionales o interfaces que también necesiten ser migradas.
|
||||
* Del mismo modo, si tu código de librería depende de un servicio, este servicio necesita ser migrado.
|
||||
* Si tu código de librería o sus plantillas dependen de otras librerías (como Angular Material), debes configurar tu librería con esas dependencias.
|
||||
|
||||
* Considere como proporcionar servicios a las aplicaciones cliente.
|
||||
|
||||
* Los servicios deberían declarar sus propios proveedores (en lugar de declarar los proveedores en el NgModule o en un componente). Esto le permite al compilador dejar los servicios fuera del 'bundle' si este nunca fue inyectado dentro de la aplicación que importa la librería, véase [proveedores Tree-shakable](guide/dependency-injection-providers#tree-shakable-providers)
|
||||
* Si registras proveedores globales o compartes proveedores a través de múltiples NgModules, usa el [`forRoot()` y `forChild()` como patrones de diseño](guide/singleton-services) proporcionados por el [RouterModule](api/router/RouterModule).
|
||||
* Si tu librería proporciona servicios opcionales que podrían no ser usados por todos las aplicaciones cliente, soporte apropiadamente el 'tree-shaking' para esos casos usando el [patrón de diseño de token ligero](guide/lightweight-injection-tokens).
|
||||
|
||||
{@a integrating-with-the-cli}
|
||||
|
||||
## Integración con el CLI usando generación de código con los schematics.
|
||||
|
||||
Comúnmente una librería incluye *código reusable* que define componentes, servicios y otros Artefactos de Angular (pipes, directivas y etc.) que tu simplemente importas a un proyecto.
|
||||
Una librería es empaquetada dentro de un paquete npm para publicar y compartir.
|
||||
|
||||
Este paquete también puede incluir [schematics](guide/glossary#schematic) que proporciona instrucciones para generar o transformar código directamente un tu proyecto, de la misma forma que el CLI crea un nuevo componente genérico con `ng generate component`.
|
||||
|
||||
Un 'schematic' empaquetado con una librería puede por ejemplo proporcionar al Angular CLI la información que necesita para generar un componente que configura y usa una particular característica o conjunto de características, definido en la librería.
|
||||
|
||||
Un ejemplo de esto es el 'schematic' de navegación de Angular Material el cual configura los CDK's `BreakpointObserver` y lo usa con los componentes `MatSideNav` y `MatToolbar` de Angular Material.
|
||||
|
||||
Puedes crear e incluir los siguientes tipos de 'schematics'.
|
||||
|
||||
* Incluye un 'schematic' de instalación para que con `ng add` puedas agregar tu libería a un proyecto.
|
||||
|
||||
* Incluye un 'schematic' de generación en tu librería para que con `ng generate` puedas hacer scaffolding de sus artefactos (componentes, servicios, pruebas y etc) en un proyecto.
|
||||
|
||||
* Incluye un 'schematic' de actualización para que con `ng update` puedas actualizar las dependencias de tu librería y proporcionar migraciones para cambios importantes en un nuevo release.
|
||||
|
||||
Lo que incluya tu librería depende de tu tarea.
|
||||
Por ejemplo, podrías definir un 'schematic' para crear un desplegable (dropdown) que esta pre-poblado con datos para mostrar como agregarlo a una aplicación.
|
||||
Si quieres un desplegable (dropdown) que contendrá valores diferentes cada vez, tu librería podría definir un 'schematic' para crearlo con una configuración dada. Los desarrolladores podrán entonces usar `ng generate` para configurar una instancia para sus propias aplicaciones.
|
||||
|
||||
Supón que quieres leer un archivo de configuración y entonces generar una formulario con base a la configuración.
|
||||
Si este formulario necesita personalización adicional por parte del desarrollador que esta usando tu librería, esto podría trabajar mejor como un 'schematic'.
|
||||
Sin embargo, si el formulario siempre será el mismo y no necesita de mucha personalización por parte de los desarrolladores, entonces podría crear un componente dinámico que tome la configuración y genere el formulario.
|
||||
En general, entre más compleja sea personalización, la más util será en enfoque de un 'schematic'.
|
||||
|
||||
Para aprender más, véase [Vista general de Schematics](guide/schematics)
|
||||
|
||||
## Publicando tu librería
|
||||
|
||||
Usa el Angular CLI y el gestor de paquetes npm para construir y publicar tu librería como un paquete npm.
|
||||
|
||||
Antes de publicar una librería a NPM, constrúyela usando la bandera `--prod` la cúal usará el compilador y tiempo de ejecución (runtime) más antiguos como 'View Engine' en vez de 'Ivy'.
|
||||
|
||||
<code-example language="bash">
|
||||
ng build my-lib --prod
|
||||
cd dist/my-lib
|
||||
npm publish
|
||||
</code-example>
|
||||
|
||||
Si nunca has publicado un paquete en npm antes, tu debes crear un cuenta. Lee más en [Publicando paquetes npm](https://docs.npmjs.com/getting-started/publishing-npm-packages).
|
||||
|
||||
<div class="alert is-important">
|
||||
|
||||
Por ahora, no es recomendando publicar librerías con Ivy hacia NPM por que Ivy genera código que no es retrocompatible con 'View Engine', entonces las aplicaciones usando 'View Engine' no podrán consumirlas. Además, las instrucciones internas de IVY no son estables aun, lo cual puede romper potencialmente a los consumidores que usan una diferente versión de Angular a la que uso para construir la libería.
|
||||
|
||||
Cuando una librería publicada es usada en una aplicación con Ivy, el Angular CLI automáticamente la convertirá a Ivy usando una herramienta conocida como el compilador de compatibilidad Angular (`ngcc`). Por lo tanto, publicar tus librerías usado el compilador 'View Engine' garantiza que ellas puede ser consumidas de forma transparente por ambos motores 'View Engine' y 'Ivy'.
|
||||
|
||||
</div>
|
||||
|
||||
{@a lib-assets}
|
||||
|
||||
## Gestionando activos (assets) en una librería.
|
||||
|
||||
Desde la versión 9.x de la herramienta [ng-packagr](https://github.com/ng-packagr/ng-packagr/blob/master/README.md), puedes configurar la herramienta para que automáticamente copie los activos (assets) dentro de el paquete de librería como parte del proceso de construcción.
|
||||
Puedes usar esta característica cuando tu librería necesite publicar archivos de temas opcionales, funciones de Sass o documentación (como un registro de cambios 'changelog').
|
||||
|
||||
* Aprende como [copiar activos (assets) dentro de tu librería como parte de la construcción](https://github.com/ng-packagr/ng-packagr/blob/master/docs/copy-assets.md).
|
||||
|
||||
* Aprende más acerca de como usar la herramienta para [incrustar activos (assets) de CSS](https://github.com/ng-packagr/ng-packagr/blob/master/docs/embed-assets-css.md).
|
||||
|
||||
|
||||
## Vinculando librerías
|
||||
|
||||
Mientras trabajas en un librería publicada, puedes usar [npm link](https://docs.npmjs.com/cli/link) para evitar re instalar la librería en cada construcción.
|
||||
|
||||
La librería debe ser reconstruida en cada cambio.
|
||||
Cuando vinculas una librería, asegurate que el paso de construir corra en modo vigía (watch mode) y que el `package.json` de la librería configure los puntos de entrada correctos.
|
||||
Por ejemplo, `main` debería apuntar a un archivo JavaScript, no a un archivo TypeScript.
|
||||
|
||||
## Utiliza el mapeo de rutas de TypeScript por las dependencias de pares.
|
||||
|
||||
Las librerías de Angular deben enumerar todas las dependencias `@angular/*` como dependencias de pares.
|
||||
Esto garantiza que cuando los módulos solicitan Angular, todos ellos obtienen exactamente el mismo módulo.
|
||||
Si tu librería lista `@angular/core` en `dependencies` en vez de en `peerDependencies`, podría obtener un módulo Angular diferente, lo qué haría que tu aplicación se rompiera.
|
||||
|
||||
Cuando desarrollas una librería, tu debes instalar todas las dependencias de pares mediante `devDependencies` para garantizar que la librería compile apropiadamente.
|
||||
Una librería vinculada tendrá su propio conjunto de librerías Angular que usa para construir, ubicados en su carpeta `node_modules`.
|
||||
|
||||
Sin embargo, esto puede causar problemas mientras construyes o corres tu aplicación.
|
||||
|
||||
Para evitar este problema tu puedes usar el mapeo de rutas de TypeScript para indicarle a TypeScript que este debería cargar algunos módulos desde una ubicación especifica.
|
||||
|
||||
Enumera todas las dependencias de pares que tu librería usa en el archivo de configuración `./tsconfig.json` del espacio de trabajo de TypeScript, y apúntalos a la copia local en la carpeta `node_modules` de la aplicación.
|
||||
|
||||
```
|
||||
{
|
||||
"compilerOptions": {
|
||||
// ...
|
||||
// paths are relative to `baseUrl` path.
|
||||
"paths": {
|
||||
"@angular/*": [
|
||||
"./node_modules/@angular/*"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Este mapeador garantiza que tu librería siempre cargue las copias locales del módulo que necesita.
|
||||
|
||||
|
||||
## Usando tu propia librería en aplicaciones.
|
||||
|
||||
No tienes que publicar tu librería hacia el gestor de paquetes npm para usarla en tus propias aplicaciones, pero tienes que construirla primero.
|
||||
|
||||
Para usar tu propia librería en tu aplicación:
|
||||
|
||||
* Construye la librería. No puedes usar una librería antes que se construya.
|
||||
<code-example language="bash">
|
||||
ng build my-lib
|
||||
</code-example>
|
||||
|
||||
* En tus aplicaciones, importa la librería por el nombre:
|
||||
```
|
||||
import { myExport } from 'my-lib';
|
||||
```
|
||||
|
||||
### Construyendo y re construyendo tu librería.
|
||||
|
||||
El paso de construir es importante si no tienes publicada tu librería como un paquete npm y luego ha instalado el paquete de nuevo dentro tu aplicación desde npm.
|
||||
Por ejemplo, si clonas tu repositorio git y corres `npm install`, tu editor mostrará la importación de `my-lib` como perdida si no tienes aun construida tu librería.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
Cuando importas algo desde una librería en una aplicación Angular, Angular busca un mapeo entre el nombre de librería y una ubicación en disco.
|
||||
Cuando instalas un paquete de librería, el mapeo esta en la carpeta `node_modules`. Cuando construyes tu propia librería, tiene que encontrar el mapeo en tus rutas de `tsconfig`.
|
||||
|
||||
Generando una librería con el Angular CLI automáticamente agrega su ruta en el archivo `tsconfig`.
|
||||
El Angular CLI usa las rutas `tsconfig` para indicarle al sistema construido donde encontrar la librería.
|
||||
|
||||
</div>
|
||||
|
||||
Si descubres que los cambios en tu librería no son reflejados en tu aplicación, tu aplicación probablemente esta usando una construcción antigua de la librería.
|
||||
|
||||
Puedes re construir tu librería cada vez que hagas cambios en esta, pero este paso extra toma tiempo.
|
||||
Las *construcciones incrementales* funcionalmente mejoran la experiencia de desarrollo de librerías.
|
||||
Cada vez que un archivo es cambiando una construcción parcial es realizada y esta emite los archivos modificados.
|
||||
|
||||
Las *Construcciones incrementales* puede ser ejecutadas como un proceso en segundo plano en tu entorno de desarrollo. Para aprovechar esta característica agrega la bandera `--watch` al comando de construcción:
|
||||
|
||||
<code-example language="bash">
|
||||
ng build my-lib --watch
|
||||
</code-example>
|
||||
|
||||
<div class="alert is-important">
|
||||
|
||||
El comando `build` del CLI utiliza un constructor diferente e invoca una herramienta de construcción diferente para las librerías que para las aplicaciones.
|
||||
|
||||
* El sistema de construcción para aplicaciones, `@angular-devkit/build-angular`, esta basado en `webpack`, y esta incluida en todos los nuevos proyectos de Angular CLI.
|
||||
* El sistema de construcción esta basado en `ng-packagr`. Este es solo agregado en tus dependencias cuando agregas una librería usando `ng generate library my-lib`.
|
||||
|
||||
Los dos sistemas de construcción soportan diferentes cosas e incluso si ellos soportan las mismas cosas, ellos hacen esas cosas de forma diferente.
|
||||
Esto quiere decir que la fuente de TypeScript puede generar en código JavaScript diferente en una librería construida que en una aplicación construida.
|
||||
|
||||
Por esta razón, una aplicación que depende de una librería debería solo usar el mapeo de rutas de TypeScript que apunte a la *librería construida*.
|
||||
El mapeo de rutas de TypeScript no debería apuntar hacia los archivos `.ts` fuente de la librería.
|
||||
|
||||
</div>
|
@ -14,7 +14,7 @@ established through the components' [view objects](guide/glossary#view).
|
||||
Each component has a *host view*, and can have additional *embedded views*.
|
||||
An embedded view in component A is the
|
||||
host view of component B, which can in turn have embedded view.
|
||||
This means that there is a [view hierarchy](guide/glossary#view-hierarchy) for each component,
|
||||
This means that there is a [view hierarchy](guide/glossary#view-tree) for each component,
|
||||
of which that component's host view is the root.
|
||||
|
||||
There is an API for navigating *down* the view hierarchy.
|
||||
|
@ -91,7 +91,7 @@ Angular components, templates, and styles go here.
|
||||
|
||||
| `src/app/` FILES | PURPOSE |
|
||||
| :-------------------------- | :------------------------------------------|
|
||||
| `app/app.component.ts` | Defines the logic for the app's root component, named `AppComponent`. The view associated with this root component becomes the root of the [view hierarchy](guide/glossary#view-hierarchy) as you add components and services to your application. |
|
||||
| `app/app.component.ts` | Defines the logic for the app's root component, named `AppComponent`. The view associated with this root component becomes the root of the [view hierarchy](guide/glossary#view-tree) as you add components and services to your application. |
|
||||
| `app/app.component.html` | Defines the HTML template associated with the root `AppComponent`. |
|
||||
| `app/app.component.css` | Defines the base CSS stylesheet for the root `AppComponent`. |
|
||||
| `app/app.component.spec.ts` | Defines a unit test for the root `AppComponent`. |
|
||||
|
1090
aio/content/guide/glossary.en.md
Normal file
1090
aio/content/guide/glossary.en.md
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -39,7 +39,7 @@ To prepare your app for translations, you should have a basic understanding of t
|
||||
|
||||
* [Templates](guide/glossary#template "Definition of a template")
|
||||
* [Components](guide/glossary#component "Definition of a component")
|
||||
* [Angular CLI](guide/glossary#command-line-interface-cli "Definition of CLI") command-line tool for managing the Angular development cycle
|
||||
* [Angular CLI](guide/glossary#cli "Definition of CLI") command-line tool for managing the Angular development cycle
|
||||
* [Extensible Markup Language (XML)](https://www.w3.org/XML/ "W3C: Extensible Markup Language (XML)") used for translation files
|
||||
|
||||
## Steps to localize your app
|
||||
@ -534,13 +534,13 @@ The following example shows both translation units after translating:
|
||||
|
||||
## Merge translations into the app
|
||||
|
||||
To merge the completed translations into the app, use the [Angular CLI](guide/glossary#command-line-interface-cli "Definition of CLI") to build a copy of the app's distributable files for each locale.
|
||||
To merge the completed translations into the app, use the [Angular CLI](guide/glossary#cli "Definition of CLI") to build a copy of the app's distributable files for each locale.
|
||||
The build process replaces the original text with translated text, and sets the `LOCALE_ID` token for each distributable copy of the app.
|
||||
It also loads and registers the locale data.
|
||||
|
||||
After merging, you can serve each distributable copy of the app using server-side language detection or different subdirectories, as described in the next section about [deploying multiple locales](#deploy-locales).
|
||||
|
||||
The build process uses [ahead-of-time (AOT) compilation](guide/glossary#ahead-of-time-aot-compilation) to produce a small, fast,
|
||||
The build process uses [ahead-of-time (AOT) compilation](guide/glossary#aot) to produce a small, fast,
|
||||
ready-to-run app. With Ivy in Angular version 9, AOT is used by default for both
|
||||
development and production builds, and AOT is required to localize component templates.
|
||||
|
||||
@ -610,7 +610,7 @@ To use your locale definition in the build configuration, use the `"localize"` o
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
Note: [Ahead-of-time (AOT) compilation](guide/glossary#ahead-of-time-aot-compilation) is required to localize component templates.
|
||||
Note: [Ahead-of-time (AOT) compilation](guide/glossary#aot) is required to localize component templates.
|
||||
If you changed this setting, set `"aot"` to `true` in order to use AOT.
|
||||
|
||||
</div>
|
||||
|
37
aio/content/guide/libraries.en.md
Normal file
37
aio/content/guide/libraries.en.md
Normal file
@ -0,0 +1,37 @@
|
||||
# Overview of Angular libraries
|
||||
|
||||
Many applications need to solve the same general problems, such as presenting a unified user interface, presenting data, and allowing data entry.
|
||||
Developers can create general solutions for particular domains that can be adapted for re-use in different apps.
|
||||
Such a solution can be built as Angular *libraries* and these libraries can be published and shared as *npm packages*.
|
||||
|
||||
An Angular library is an Angular [project](guide/glossary#project) that differs from an app in that it cannot run on its own.
|
||||
A library must be imported and used in an app.
|
||||
|
||||
Libraries extend Angular's base functionality. For example, to add [reactive forms](guide/reactive-forms) to an app, add the library package using `ng add @angular/forms`, then import the `ReactiveFormsModule` from the `@angular/forms` library in your application code.
|
||||
Similarly, adding the [service worker](guide/service-worker-intro) library to an Angular application is one of the steps for turning an application into a [Progressive Web App](https://developers.google.com/web/progressive-web-apps/) (PWA).
|
||||
[Angular Material](https://material.angular.io/) is an example of a large, general-purpose library that provides sophisticated, reusable, and adaptable UI components.
|
||||
|
||||
Any app developer can use these and other libraries that have been published as npm packages by the Angular team or by third parties. See [Using Published Libraries](guide/using-libraries).
|
||||
|
||||
## Creating libraries
|
||||
|
||||
If you have developed functionality that is suitable for reuse, you can create your own libraries.
|
||||
These libraries can be used locally in your workspace, or you can publish them as [npm packages](guide/npm-packages) to share with other projects or other Angular developers.
|
||||
These packages can be published to the npm registry, a private npm Enterprise registry, or a private package management system that supports npm packages.
|
||||
See [Creating Libraries](guide/creating-libraries).
|
||||
|
||||
Whether you decide to package functionality as a library is an architectural decision, similar to deciding whether a piece of functionality is a component or a service, or deciding on the scope of a component.
|
||||
|
||||
Packaging functionality as a library forces the artifacts in the library to be decoupled from the application's business logic.
|
||||
This can help to avoid various bad practices or architecture mistakes that can make it difficult to decouple and reuse code in the future.
|
||||
|
||||
Putting code into a separate library is more complex than simply putting everything in one app.
|
||||
It requires more of an investment in time and thought for managing, maintaining, and updating the library.
|
||||
This complexity can pay off, however, when the library is being used in multiple apps.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
Note that libraries are intended to be used by Angular apps.
|
||||
To add Angular functionality to non-Angular web apps, you can use [Angular custom elements](guide/elements).
|
||||
|
||||
</div>
|
@ -1,37 +1,38 @@
|
||||
# Overview of Angular libraries
|
||||
# Vista general de librerías para Angular
|
||||
|
||||
Many applications need to solve the same general problems, such as presenting a unified user interface, presenting data, and allowing data entry.
|
||||
Developers can create general solutions for particular domains that can be adapted for re-use in different apps.
|
||||
Such a solution can be built as Angular *libraries* and these libraries can be published and shared as *npm packages*.
|
||||
Muchas aplicaciones necesitan resolver los mismos problemas en general, como presentar una interfaz de usuario unificada, mostrar datos, permitir entrada de datos etc.
|
||||
Los desarrolladores puede crear soluciones generales para dominios particulares que pueden ser adoptados para re usarse en diferentes aplicaciones.
|
||||
Tal solución se puede construir como *librerías* para Angular y estas librerías pueden ser publicadas y compartidas como *paquetes de npm*.
|
||||
|
||||
An Angular library is an Angular [project](guide/glossary#project) that differs from an app in that it cannot run on its own.
|
||||
A library must be imported and used in an app.
|
||||
Una librería de Angular es como un [proyecto](guide/glossary#project) lo que la diferencia de una app es que no puede correr por si sola.
|
||||
Una librería debe ser importada y usada en una app.
|
||||
|
||||
Libraries extend Angular's base functionality. For example, to add [reactive forms](guide/reactive-forms) to an app, add the library package using `ng add @angular/forms`, then import the `ReactiveFormsModule` from the `@angular/forms` library in your application code.
|
||||
Similarly, adding the [service worker](guide/service-worker-intro) library to an Angular application is one of the steps for turning an application into a [Progressive Web App](https://developers.google.com/web/progressive-web-apps/) (PWA).
|
||||
[Angular Material](https://material.angular.io/) is an example of a large, general-purpose library that provides sophisticated, reusable, and adaptable UI components.
|
||||
Las librerías extienden la funcionalidad base de Angular. Por ejemplo, para agregar [formularios reactivos](guide/reactive-forms) en una app, agregamos la librería usando `ng add @angular/forms`, entonces importamos el `ReactiveFormsModule` desde la librería `@angular/forms` el código de la aplicación.
|
||||
De igual manera, agregar la librería [service worker](guide/service-worker-intro) dentro de una aplicación Angular es el primer paso para convertir una aplicación a una [Progressive Web App](https://developers.google.com/web/progressive-web-apps/) (PWA).
|
||||
[Angular Material](https://material.angular.io/) es un ejemplo de una gran librería de propósito general que ofrece componentes de UI sofisticados, reutilizables y adaptables.
|
||||
|
||||
Any app developer can use these and other libraries that have been published as npm packages by the Angular team or by third parties. See [Using Published Libraries](guide/using-libraries).
|
||||
Cualquier desarrollador de apps puede usar estas y otras librerías que han sido publicadas como paquetes de npm por el equipo de Angular o por terceros. Mirá [Usando librerías publicadas](guide/using-libraries).
|
||||
|
||||
## Creating libraries
|
||||
## Creando librerías
|
||||
|
||||
If you have developed functionality that is suitable for reuse, you can create your own libraries.
|
||||
These libraries can be used locally in your workspace, or you can publish them as [npm packages](guide/npm-packages) to share with other projects or other Angular developers.
|
||||
These packages can be published to the npm registry, a private npm Enterprise registry, or a private package management system that supports npm packages.
|
||||
See [Creating Libraries](guide/creating-libraries).
|
||||
Si tu tienes funcionalidades desarrolladas que puede ser adecuadas para re usarse tu puedes crear tus propias librerías.
|
||||
Estas librerías puede ser usadas localmente en tu espacio de trabajo, o puede ser publicadas como [paquetes de npm](guide/npm-packages) para compartir con otros proyectos o otros desarrolladores Angular.
|
||||
Estos paquetes pueden ser publicados en el registro de npm, en un registro empresarial privado de npm, o en un sistema de gestión de paquetes privado que soporte paquetes de npm.
|
||||
Mirá [Creando librerías](guide/creating-libraries).
|
||||
|
||||
Whether you decide to package functionality as a library is an architectural decision, similar to deciding whether a piece of functionality is a component or a service, or deciding on the scope of a component.
|
||||
Si tu decides empaquetar una funcionalidad como una librería es una decisión de arquitectura, similar a decidir entre si una pieza de funcionalidad es un componente o un servicio, o decidir el alcance de un componente.
|
||||
|
||||
Packaging functionality as a library forces the artifacts in the library to be decoupled from the application's business logic.
|
||||
This can help to avoid various bad practices or architecture mistakes that can make it difficult to decouple and reuse code in the future.
|
||||
Empaquetar funcionalidad como una librería fuerza a
|
||||
que los artefactos en la librería puedan ser desacoplados de la lógica de negocio de la aplicación.
|
||||
Esto puede ayudar a evitar varias malas practicas o errores de arquitectura que puede hacer difícil desacoplar y re usar código en el futuro.
|
||||
|
||||
Putting code into a separate library is more complex than simply putting everything in one app.
|
||||
It requires more of an investment in time and thought for managing, maintaining, and updating the library.
|
||||
This complexity can pay off, however, when the library is being used in multiple apps.
|
||||
Poniendo el código dentro de una librería separada es más complejo que simplemente poner todo en una sola aplicación.
|
||||
Esto requiere una inversión mayor de tiempo y pensar para administrar, mantener y actualizar la librería.
|
||||
Sin embargo esta complejidad puede valer la pena cuando la librería esta siendo usada en multiples aplicaciones.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
Note that libraries are intended to be used by Angular apps.
|
||||
To add Angular functionality to non-Angular web apps, you can use [Angular custom elements](guide/elements).
|
||||
Note que las librerías están destinadas para ser usadas por aplicaciones Angular.
|
||||
Para agregar funcionalidad de Angular hacia una aplicación web que no es Angular, puedes usar [Angular custom elements](guide/elements).
|
||||
|
||||
</div>
|
||||
|
@ -457,7 +457,7 @@ The object reference did not change when the value of its own `name` property ch
|
||||
|
||||
### Responding to view changes
|
||||
|
||||
As Angular traverses the [view hierarchy](guide/glossary#view-hierarchy "Definition of view hierarchy definition") during change detection, it needs to be sure that a change in a child does not attempt to cause a change in its own parent. Such a change would not be rendered properly, because of how [unidirectional data flow](guide/glossary#unidirectional-data-flow "Definition") works.
|
||||
As Angular traverses the [view hierarchy](guide/glossary#view-tree "Definition of view hierarchy definition") during change detection, it needs to be sure that a change in a child does not attempt to cause a change in its own parent. Such a change would not be rendered properly, because of how [unidirectional data flow](guide/glossary#unidirectional-data-flow "Definition") works.
|
||||
|
||||
If you need to make a change that inverts the expected data flow, you must trigger a new change detection cycle to allow that change to be rendered.
|
||||
The examples illustrate how to make such changes safely.
|
||||
|
68
aio/content/guide/ngmodules.en.md
Normal file
68
aio/content/guide/ngmodules.en.md
Normal file
@ -0,0 +1,68 @@
|
||||
# NgModules
|
||||
|
||||
**NgModules** configure the injector and the compiler and help organize related things together.
|
||||
|
||||
An NgModule is a class marked by the `@NgModule` decorator.
|
||||
`@NgModule` takes a metadata object that describes how to compile a component's template and how to create an injector at runtime.
|
||||
It identifies the module's own components, directives, and pipes,
|
||||
making some of them public, through the `exports` property, so that external components can use them.
|
||||
`@NgModule` can also add service providers to the application dependency injectors.
|
||||
|
||||
For an example app showcasing all the techniques that NgModules related pages
|
||||
cover, see the <live-example></live-example>. For explanations on the individual techniques, visit the relevant NgModule pages under the NgModules
|
||||
section.
|
||||
|
||||
## Angular modularity
|
||||
|
||||
Modules are a great way to organize an application and extend it with capabilities from external libraries.
|
||||
|
||||
Angular libraries are NgModules, such as `FormsModule`, `HttpClientModule`, and `RouterModule`.
|
||||
Many third-party libraries are available as NgModules such as
|
||||
<a href="https://material.angular.io/">Material Design</a>,
|
||||
<a href="http://ionicframework.com/">Ionic</a>, and
|
||||
<a href="https://github.com/angular/angularfire2">AngularFire2</a>.
|
||||
|
||||
NgModules consolidate components, directives, and pipes into
|
||||
cohesive blocks of functionality, each focused on a
|
||||
feature area, application business domain, workflow, or common collection of utilities.
|
||||
|
||||
Modules can also add services to the application.
|
||||
Such services might be internally developed, like something you'd develop yourself or come from outside sources, such as the Angular router and HTTP client.
|
||||
|
||||
Modules can be loaded eagerly when the application starts or lazy loaded asynchronously by the router.
|
||||
|
||||
NgModule metadata does the following:
|
||||
|
||||
* Declares which components, directives, and pipes belong to the module.
|
||||
* Makes some of those components, directives, and pipes public so that other module's component templates can use them.
|
||||
* Imports other modules with the components, directives, and pipes that components in the current module need.
|
||||
* Provides services that the other application components can use.
|
||||
|
||||
Every Angular app has at least one module, the root module.
|
||||
You [bootstrap](guide/bootstrapping) that module to launch the application.
|
||||
|
||||
The root module is all you need in a simple application with a few components.
|
||||
As the app grows, you refactor the root module into [feature modules](guide/feature-modules)
|
||||
that represent collections of related functionality.
|
||||
You then import these modules into the root module.
|
||||
|
||||
## The basic NgModule
|
||||
|
||||
The [Angular CLI](cli) generates the following basic `AppModule` when creating a new app.
|
||||
|
||||
|
||||
<code-example path="ngmodules/src/app/app.module.1.ts" header="src/app/app.module.ts (default AppModule)">
|
||||
// @NgModule decorator with its metadata
|
||||
</code-example>
|
||||
|
||||
At the top are the import statements. The next section is where you configure the `@NgModule` by stating what components and directives belong to it (`declarations`) as well as which other modules it uses (`imports`). For more information on the structure of an `@NgModule`, be sure to read [Bootstrapping](guide/bootstrapping).
|
||||
|
||||
<hr />
|
||||
|
||||
## More on NgModules
|
||||
|
||||
You may also be interested in the following:
|
||||
* [Feature Modules](guide/feature-modules).
|
||||
* [Entry Components](guide/entry-components).
|
||||
* [Providers](guide/providers).
|
||||
* [Types of NgModules](guide/module-types).
|
@ -1,68 +1,56 @@
|
||||
# NgModules
|
||||
|
||||
**NgModules** configure the injector and the compiler and help organize related things together.
|
||||
**NgModules** configura el inyector y el compilador y ayuda a agrupar cosas similares.
|
||||
|
||||
An NgModule is a class marked by the `@NgModule` decorator.
|
||||
`@NgModule` takes a metadata object that describes how to compile a component's template and how to create an injector at runtime.
|
||||
It identifies the module's own components, directives, and pipes,
|
||||
making some of them public, through the `exports` property, so that external components can use them.
|
||||
`@NgModule` can also add service providers to the application dependency injectors.
|
||||
Un NgModule es una clase marcada por el decorador `@NgModule`. Este toma un objeto metadato que describe cómo compilar la template de un componente, y cómo crear un inyector en tiempo de ejecución.
|
||||
|
||||
For an example app showcasing all the techniques that NgModules related pages
|
||||
cover, see the <live-example></live-example>. For explanations on the individual techniques, visit the relevant NgModule pages under the NgModules
|
||||
section.
|
||||
Identifica los componentes del propio módulo, directivas y pipes, haciendo algunos de ellos públicos (a través de la propiedad `export`) para que los componentes externos puedan utilizarlos.
|
||||
|
||||
## Angular modularity
|
||||
`NgModule` también puede añadir proveedores de servicio a los inyectores de la aplicación de dependencia.
|
||||
|
||||
Modules are a great way to organize an application and extend it with capabilities from external libraries.
|
||||
Para ver una app de ejemplo que contiene todas las técnicas relacionadas con los `NgModules` , consulta <live-example></live-example>. Para explicaciones individuales de cada técnica, visita las páginas específicas bajo la sección NgModules.
|
||||
|
||||
Angular libraries are NgModules, such as `FormsModule`, `HttpClientModule`, and `RouterModule`.
|
||||
Many third-party libraries are available as NgModules such as
|
||||
<a href="https://material.angular.io/">Material Design</a>,
|
||||
<a href="http://ionicframework.com/">Ionic</a>, and
|
||||
<a href="https://github.com/angular/angularfire2">AngularFire2</a>.
|
||||
## Modularidad en Angular
|
||||
|
||||
NgModules consolidate components, directives, and pipes into
|
||||
cohesive blocks of functionality, each focused on a
|
||||
feature area, application business domain, workflow, or common collection of utilities.
|
||||
Los módulos son una muy buena forma de organizar una aplicación y extenderla con funcionalidades de bibliotecas externas.
|
||||
|
||||
Modules can also add services to the application.
|
||||
Such services might be internally developed, like something you'd develop yourself or come from outside sources, such as the Angular router and HTTP client.
|
||||
Las bibliotecas de Angular son NgModules, como `FormsModule`, `HttpClientModule`, and `RouterModule`.
|
||||
|
||||
Modules can be loaded eagerly when the application starts or lazy loaded asynchronously by the router.
|
||||
También hay disponibles bibliotecas de terceros, tales como <a href="https://material.angular.io/">Material Design</a>, <a href="http://ionicframework.com/">Ionic</a>, o <a href="https://github.com/angular/angularfire2">AngularFire2</a>.
|
||||
|
||||
NgModule metadata does the following:
|
||||
Los NgModules consolidan componentes, directivas y pipes en bloques cohesivos de funcionalidades, cada uno centrado en áreas distintas como funciones, aplicación de dominios business, flujo de trabajo, o recolección de utilidades.
|
||||
|
||||
* Declares which components, directives, and pipes belong to the module.
|
||||
* Makes some of those components, directives, and pipes public so that other module's component templates can use them.
|
||||
* Imports other modules with the components, directives, and pipes that components in the current module need.
|
||||
* Provides services that the other application components can use.
|
||||
Los módulos también pueden añadir servicios a la aplicación. Estos servicios pueden haber sido desarrollados internamente, es decir, puedes haberlos desarrollado tú mismo o venir de una fuente extena, como el cliente HTTP y router de Angular.
|
||||
|
||||
Every Angular app has at least one module, the root module.
|
||||
You [bootstrap](guide/bootstrapping) that module to launch the application.
|
||||
Los módulos se pueden cargar de forma *entusiasta*, cuando la aplicación se inicia; o de forma *perezosa*, cargados asíncronamente por el router.
|
||||
|
||||
The root module is all you need in a simple application with a few components.
|
||||
As the app grows, you refactor the root module into [feature modules](guide/feature-modules)
|
||||
that represent collections of related functionality.
|
||||
You then import these modules into the root module.
|
||||
Los metadatos NgModule hacen lo siguiente:
|
||||
|
||||
## The basic NgModule
|
||||
* Declarar qué componentes, directivas y pipes pertenecen al módulo.
|
||||
* Hacer algunos de esos componentes, directivas y pipes públicos para que las templates de los componentes de otros módulos puedan utilizarlos.
|
||||
* Importar otros módulos con los componentes, directivas y pipes que los componentes del módulo actual requieren
|
||||
* Proveer servicios que otros componentes de la aplicación pueden usar.
|
||||
|
||||
The [Angular CLI](cli) generates the following basic `AppModule` when creating a new app.
|
||||
Todas las apps de Angular contienen como mínimo un módulo, el módulo root. Se hace [bootstrap](guide/bootstrapping) a ese módulo para iniciar la aplicación.
|
||||
|
||||
El módulo root es todo lo que necesitas en una aplicación simple de pocos componentes. Según tu app crezca, puedes refactorizar el módulo root en [módulos de funcionalidades](guide/feature-modules), que representan colecciones de funcionalidades similares. Luego, importa esos módulos al módulo root.
|
||||
|
||||
## El NgModule básico
|
||||
|
||||
El [CLI de Angular ](cli) genera los siguientes `AppModule` básicos cuando crea una nueva app.
|
||||
|
||||
<code-example path="ngmodules/src/app/app.module.1.ts" header="src/app/app.module.ts (default AppModule)">
|
||||
// @NgModule decorator with its metadata
|
||||
// decorador @NgModule con sus metadatos
|
||||
</code-example>
|
||||
|
||||
At the top are the import statements. The next section is where you configure the `@NgModule` by stating what components and directives belong to it (`declarations`) as well as which other modules it uses (`imports`). For more information on the structure of an `@NgModule`, be sure to read [Bootstrapping](guide/bootstrapping).
|
||||
Encima están las declaraciones de `import`. La siguiente sección es donde se configura el `@NgModule`, indicando qué componentes y directivas le pertenecen (`declarations`), además de qué otros módulos utiliza (`imports`). Para más información sobre la estructura de un `@NgModule`, consulta [Bootstrapping](guide/bootstrapping).
|
||||
|
||||
<hr />
|
||||
|
||||
## More on NgModules
|
||||
## Más sobre los NgModules
|
||||
|
||||
You may also be interested in the following:
|
||||
* [Feature Modules](guide/feature-modules).
|
||||
* [Entry Components](guide/entry-components).
|
||||
* [Providers](guide/providers).
|
||||
* [Types of NgModules](guide/module-types).
|
||||
Puede que te interesen las siguientes páginas:
|
||||
* [Módulos de funciones](guide/feature-modules).
|
||||
* [Componentes de entrada](guide/entry-components).
|
||||
* [Proveedores](guide/providers).
|
||||
* [Tipos de NgModules](guide/module-types).
|
||||
|
@ -146,7 +146,7 @@ You can then use your custom pipe in template expressions, the same way you use
|
||||
|
||||
### Marking a class as a pipe
|
||||
|
||||
To mark a class as a pipe and supply configuration metadata, apply the [`@Pipe`](/api/core/Pipe "API reference for Pipe") [decorator](/guide/glossary#decorator--decoration "Definition for decorator") to the class.
|
||||
To mark a class as a pipe and supply configuration metadata, apply the [`@Pipe`](/api/core/Pipe "API reference for Pipe") [decorator](/guide/glossary#decorator "Definition for decorator") to the class.
|
||||
Use [UpperCamelCase](guide/glossary#case-types "Definition of case types") (the general convention for class names) for the pipe class name, and [camelCase](guide/glossary#case-types "Definition of case types") for the corresponding `name` string.
|
||||
Do not use hyphens in the `name`.
|
||||
For details and more examples, see [Pipe names](guide/styleguide#pipe-names "Pipe names in the Angular coding style guide").
|
||||
|
23
aio/content/guide/practical-observable-usage.en.md
Normal file
23
aio/content/guide/practical-observable-usage.en.md
Normal file
@ -0,0 +1,23 @@
|
||||
# Practical observable usage
|
||||
|
||||
Here are some examples of domains in which observables are particularly useful.
|
||||
|
||||
## Type-ahead suggestions
|
||||
|
||||
Observables can simplify the implementation of type-ahead suggestions. Typically, a type-ahead has to do a series of separate tasks:
|
||||
|
||||
* Listen for data from an input.
|
||||
* Trim the value (remove whitespace) and make sure it’s a minimum length.
|
||||
* Debounce (so as not to send off API requests for every keystroke, but instead wait for a break in keystrokes).
|
||||
* Don’t send a request if the value stays the same (rapidly hit a character, then backspace, for instance).
|
||||
* Cancel ongoing AJAX requests if their results will be invalidated by the updated results.
|
||||
|
||||
Writing this in full JavaScript can be quite involved. With observables, you can use a simple series of RxJS operators:
|
||||
|
||||
<code-example path="practical-observable-usage/src/typeahead.ts" header="Typeahead"></code-example>
|
||||
|
||||
## Exponential backoff
|
||||
|
||||
Exponential backoff is a technique in which you retry an API after failure, making the time in between retries longer after each consecutive failure, with a maximum number of retries after which the request is considered to have failed. This can be quite complex to implement with promises and other methods of tracking AJAX calls. With observables, it is very easy:
|
||||
|
||||
<code-example path="practical-observable-usage/src/backoff.ts" header="Exponential backoff"></code-example>
|
@ -1,23 +1,23 @@
|
||||
# Practical observable usage
|
||||
|
||||
Here are some examples of domains in which observables are particularly useful.
|
||||
Aquí tienes algunos ejemplos de dominios en los que las observables son particularmente útiles.
|
||||
|
||||
## Type-ahead suggestions
|
||||
## Sugerencias de autocompletado
|
||||
|
||||
Observables can simplify the implementation of type-ahead suggestions. Typically, a type-ahead has to do a series of separate tasks:
|
||||
Las observables pueden simplificar la implementación de las sugerencias del autocompletado. Normalmente, un autocompletado realiza una serie de tareas:
|
||||
|
||||
* Listen for data from an input.
|
||||
* Trim the value (remove whitespace) and make sure it’s a minimum length.
|
||||
* Debounce (so as not to send off API requests for every keystroke, but instead wait for a break in keystrokes).
|
||||
* Don’t send a request if the value stays the same (rapidly hit a character, then backspace, for instance).
|
||||
* Cancel ongoing AJAX requests if their results will be invalidated by the updated results.
|
||||
* Recibe la información desde una entrada.
|
||||
* Recorta el valor (eliminando espacios) y se asegura de que tiene una longitud mínima.
|
||||
* Hacer debounce (no manda solicitudes a la API por cada tecla pulsada, sino que espera una parada entre letras).
|
||||
* No se manda una solicitud si el valor es el mismo (por ejemplo, teclear un caracter y, al momento, borrarlo)
|
||||
* Cancelar solicitudes AJAX activas si sus resultados van a ser invalidados por los resultados actualizados siguientes.
|
||||
|
||||
Writing this in full JavaScript can be quite involved. With observables, you can use a simple series of RxJS operators:
|
||||
Escribir esto íntegramente en JavaScript puede ser bastante tedioso. Con las observables, puedes utilizar una serie de simples operadores RxJS:
|
||||
|
||||
<code-example path="practical-observable-usage/src/typeahead.ts" header="Typeahead"></code-example>
|
||||
|
||||
## Exponential backoff
|
||||
## Retroceso exponencial
|
||||
|
||||
Exponential backoff is a technique in which you retry an API after failure, making the time in between retries longer after each consecutive failure, with a maximum number of retries after which the request is considered to have failed. This can be quite complex to implement with promises and other methods of tracking AJAX calls. With observables, it is very easy:
|
||||
El retroceso exponencial es una técnica en la cual vuelves a intentar la API después de un fracaso, haciendo que el tiempo entre intentos tras cada fracaso consecutivo sea cada vez más largo, con un número máximo de intentos hasta que consideras que la solicitud ha sido fallida. Esto puede ser bastante complejo de implementar con promesas y otros métodos de tracking que AJAX emplea. Con observables, es muy fácil:
|
||||
|
||||
<code-example path="practical-observable-usage/src/backoff.ts" header="Exponential backoff"></code-example>
|
||||
|
93
aio/content/guide/roadmap.en.md
Normal file
93
aio/content/guide/roadmap.en.md
Normal file
@ -0,0 +1,93 @@
|
||||
# Angular Roadmap
|
||||
|
||||
Angular receives a large number of feature requests, both from inside Google and from the broader open-source community. At the same time, our list of projects contains plenty of maintenance tasks, code refactorings, potential performance improvements, and so on. We bring together representatives from developer relations, product management, and engineering to prioritize this list. As new projects come into the queue, we regularly position them based on relative priority to other projects. As work gets done, projects will move up in the queue.
|
||||
|
||||
The projects below are not associated with a particular Angular version. We'll release them on completion, and they will be part of a specific version based on our release schedule, following semantic versioning. For example, features are released in the next minor after they are complete, or the next major if they include breaking changes.
|
||||
|
||||
## In Progress
|
||||
|
||||
### Operation Bye Bye Backlog (aka Operation Byelog)
|
||||
|
||||
We are actively investing up to 50% of our engineering capacity on triaging issues and PRs until we have a clear understanding of broader community needs. After that, we'll commit up to 20% of our engineering capacity to keep up with new submissions promptly.
|
||||
|
||||
### Support TypeScript 4.0
|
||||
|
||||
We're working on adding support for TypeScript 4.0 ahead of its stable release. We always want Angular to stay up-to-date with the latest version of TypeScript so that developers get the best the language has to offer.
|
||||
|
||||
### Update our e2e testing strategy
|
||||
|
||||
To ensure we provide a future-proof e2e testing strategy, we want to evaluate the state of Protractor, community innovations, e2e best practices, and explore novel opportunities.
|
||||
|
||||
### Angular libraries use Ivy
|
||||
|
||||
We are investing in the design and development of Ivy library distribution plan, which will include an update of the library package format to use Ivy compilation, unblock the deprecation of the View Engine library format, and [ngcc](guide/glossary#ngcc).
|
||||
|
||||
### Evaluate future RxJS changes (v7 and beyond)
|
||||
|
||||
We want to ensure Angular developers are taking advantage of the latest capabilities of RxJS and have a smooth transition to the next major releases of the framework. For this purpose, we will explore and document the scope of the changes in v7 and beyond of RxJS and plan an update strategy.
|
||||
|
||||
### Angular language service uses Ivy
|
||||
|
||||
Today the language service still uses the View Engine compiler and type checking, even for Ivy applications. We want to use the Ivy template parser and improved type checking for the Angular Language service to match application behavior. This migration will also be a step towards unblocking the removal of View Engine, which will simplify Angular, reduce the npm package size, and improve the framework's maintainability.
|
||||
|
||||
### Expand component harnesses best practices
|
||||
|
||||
Angular CDK introduced the concept of [component test harnesses](https://material.angular.io/cdk/test-harnesses) to Angular in version 9. Test harnesses allow component authors to create supported APIs for testing component interactions. We're continuing to improve this harness infrastructure and clarifying the best practices around using harnesses. We're also working to drive more harness adoption inside of Google.
|
||||
|
||||
### Support native [Trusted Types](https://web.dev/trusted-types/) in Angular
|
||||
|
||||
In collaboration with Google's security team, we're adding support for the new Trusted Types API. This web platform API will help developers build more secure web applications.
|
||||
|
||||
### Integrate [MDC Web](https://material.io/develop/web/) into Angular Material
|
||||
|
||||
MDC Web is a library created by Google's Material Design team that provides reusable primitives for building Material Design components. The Angular team is incorporating these primitives into Angular Material. Using MDC Web will align Angular Material more closely with the Material Design specification, expand accessibility, overall improve component quality, and improve our team's velocity.
|
||||
|
||||
### Offer Google engineers better integration with Angular and Google's internal server stack
|
||||
|
||||
This is an internal project to add support for Angular front-ends to Google's internal integrated server stack.
|
||||
|
||||
### Angular versioning & branching
|
||||
|
||||
We want to consolidate release management tooling between Angular's multiple GitHub repositories ([angular/angular](https://github.com/angular/angular), [angular/angular-cli](https://github.com/angular/angular-cli), and [angular/components](https://github.com/angular/components)). This effort will allow us to reuse infrastructure, unify and simplify processes, and improve our release process's reliability.
|
||||
|
||||
## Future
|
||||
|
||||
### Refresh introductory documentation
|
||||
|
||||
We will redefine the user learning journeys and refresh the introductory documentation. We will clearly state the benefits of Angular, how to explore its capabilities, and provide guidance so developers can become proficient with the framework in as little time as possible.
|
||||
|
||||
### Strict typing for `@angular/forms`
|
||||
|
||||
We will work on implementing stricter type checking for reactive forms. This way, we will allow developers to catch more issues during development time, enable better text editor and IDE support, and improve the type checking for reactive forms.
|
||||
|
||||
### webpack 5 in the Angular CLI
|
||||
|
||||
Webpack 5 brings a lot of build speed and bundle size improvements. To make them available for Angular developers, we will invest in migrating Angular CLI from using deprecated and removed webpack APIs.
|
||||
|
||||
### Commit message standardization
|
||||
|
||||
We want to unify commit message requirements and conformance across Angular repositories ([angular/angular](https://github.com/angular/angular), [angular/components](https://github.com/angular/components), [angular/angular-cli](https://github.com/angular/angular-cli)) to bring consistency to our development process and reuse infrastructure tooling.
|
||||
|
||||
### Optional Zone.js
|
||||
|
||||
We are going to design and implement a plan to make Zone.js optional from Angular applications. This way, we will simplify the framework, improve debugging, and reduce application bundle size. Additionally, this will allow us to take advantage of native async/await syntax, which currently Zone.js does not support.
|
||||
|
||||
### Remove legacy [View Engine](guide/ivy)
|
||||
|
||||
After the transition of all our internal tooling to Ivy has completed, we want to remove the legacy View Engine for smaller Angular conceptual overhead, smaller package size, lower maintenance cost, and lower complexity of the codebase.
|
||||
|
||||
### Angular DevTools
|
||||
|
||||
We’ll be working on development tooling for Angular that will provide utilities for debugging and performance profiling. This project aims to help developers understand the component structure and the change detection in an Angular application.
|
||||
|
||||
### Optional NgModules
|
||||
|
||||
To simplify the Angular mental model and learning journey, we’ll be working on making NgModules optional. This work will allow developers to develop standalone components and implement an alternative API for declaring the component’s compilation scope.
|
||||
|
||||
### Ergonomic component level code-splitting APIs
|
||||
|
||||
A common problem of web applications is their slow initial load time. A way to improve it is to apply more granular code-splitting on a component level. To encourage this practice, we’ll be working on more ergonomic code-splitting APIs.
|
||||
|
||||
### Migration to ESLint
|
||||
|
||||
With the deprecation of TSLint we will be moving to ESLint. As part of the process, we will work on ensuring backward compatibility with our current recommended TSLint configuration, implement a migration strategy for existing Angular applications and introduce new tooling to the Angular CLI toolchain.
|
@ -1,93 +1,93 @@
|
||||
# Angular Roadmap
|
||||
# Hoja de ruta Angular
|
||||
|
||||
Angular receives a large number of feature requests, both from inside Google and from the broader open-source community. At the same time, our list of projects contains plenty of maintenance tasks, code refactorings, potential performance improvements, and so on. We bring together representatives from developer relations, product management, and engineering to prioritize this list. As new projects come into the queue, we regularly position them based on relative priority to other projects. As work gets done, projects will move up in the queue.
|
||||
Angular recibe una gran cantidad de solicitudes de fucionalidades, tanto desde dentro de Google como desde la comunidad de código abierto en general. Al mismo tiempo, nuestra lista de proyectos contiene muchas tareas de mantenimiento, refactorizaciones de código, posibles mejoras de rendimiento, etc. Reunimos a representantes de relaciones con desarrolladores, gestión de productos e ingeniería para priorizar esta lista. A medida que nuevos proyectos entran en la cola, los posicionamos regularmente en función de la prioridad relativa a otros proyectos. A medida que se realiza el trabajo, los proyectos avanzarán en la cola.
|
||||
|
||||
The projects below are not associated with a particular Angular version. We'll release them on completion, and they will be part of a specific version based on our release schedule, following semantic versioning. For example, features are released in the next minor after they are complete, or the next major if they include breaking changes.
|
||||
Los proyectos a continuación no están asociados con una versión de Angular en particular. Los publicaremos una vez finalizados, y serán parte de una versión específica basada en nuestro calendario de lanzamientos, siguiendo el control de versiones semántico. Por ejemplo, las funciones se publican en el siguiente menor después de que se completan, o el siguiente mayor si incluyen cambios importantes.
|
||||
|
||||
## In Progress
|
||||
## En progreso
|
||||
|
||||
### Operation Bye Bye Backlog (aka Operation Byelog)
|
||||
### Operación Bye Bye Backlog (también conocida como Operación Byelog)
|
||||
|
||||
We are actively investing up to 50% of our engineering capacity on triaging issues and PRs until we have a clear understanding of broader community needs. After that, we'll commit up to 20% of our engineering capacity to keep up with new submissions promptly.
|
||||
Estamos invirtiendo activamente hasta el 50% de nuestra capacidad de ingeniería para clasificación de _issues_ y PRs hasta que tengamos una comprensión clara de las necesidades de la comunidad en general. Después de eso, comprometeremos hasta el 20% de nuestra capacidad de ingeniería para mantenernos al día con los nuevos envíos de _issues_ y PRs rápidamente.
|
||||
|
||||
### Support TypeScript 4.0
|
||||
### Soporte a TypeScript 4.0
|
||||
|
||||
We're working on adding support for TypeScript 4.0 ahead of its stable release. We always want Angular to stay up-to-date with the latest version of TypeScript so that developers get the best the language has to offer.
|
||||
Estamos trabajando para agregar soporte para TypeScript 4.0 antes de su versión estable. Siempre queremos que Angular se mantenga actualizado con la última versión de TypeScript para que los desarrolladores obtengan lo mejor que el lenguaje tiene para ofrecer.
|
||||
|
||||
### Update our e2e testing strategy
|
||||
### Actualizar nuestra estrategia de pruebas e2e
|
||||
|
||||
To ensure we provide a future-proof e2e testing strategy, we want to evaluate the state of Protractor, community innovations, e2e best practices, and explore novel opportunities.
|
||||
Para garantizar que proporcionamos una estrategia de prueba de e2e preparada para el futuro, queremos evaluar el estado de Protractor, las innovaciones de la comunidad, las mejores prácticas de e2e y explorar nuevas oportunidades.
|
||||
|
||||
### Angular libraries use Ivy
|
||||
### Las librerías de Angular usan Ivy
|
||||
|
||||
We are investing in the design and development of Ivy library distribution plan, which will include an update of the library package format to use Ivy compilation, unblock the deprecation of the View Engine library format, and [ngcc](guide/glossary#ngcc).
|
||||
Estamos invirtiendo en el diseño y desarrollo del plan de distribución de la librería Ivy, que incluirá una actualización del formato del paquete de la librería para usar la compilación de Ivy, desbloquear la obsolescencia del formato de la librería View Engine y [ngcc](guide/glossary#ngcc).
|
||||
|
||||
### Evaluate future RxJS changes (v7 and beyond)
|
||||
### Evaluar los cambios futuros de RxJS (v7 y posteriores)
|
||||
|
||||
We want to ensure Angular developers are taking advantage of the latest capabilities of RxJS and have a smooth transition to the next major releases of the framework. For this purpose, we will explore and document the scope of the changes in v7 and beyond of RxJS and plan an update strategy.
|
||||
Queremos asegurarnos de que los desarrolladores Angular aprovechen las últimas capacidades de RxJS y tengan una transición sin problemas a las próximas versiones principales del framework. Para este propósito, exploraremos y documentaremos el alcance de los cambios en la versión 7 y posteriores de RxJS y planificaremos una estrategia de actualización.
|
||||
|
||||
### Angular language service uses Ivy
|
||||
### El servicio de lenguaje Angular usa Ivy
|
||||
|
||||
Today the language service still uses the View Engine compiler and type checking, even for Ivy applications. We want to use the Ivy template parser and improved type checking for the Angular Language service to match application behavior. This migration will also be a step towards unblocking the removal of View Engine, which will simplify Angular, reduce the npm package size, and improve the framework's maintainability.
|
||||
Hoy en día, el servicio de lenguaje todavía utiliza el compilador de View Engine y la verificación de tipos, incluso para aplicaciones Ivy. Queremos utilizar el analizador de plantillas Ivy y la verificación de tipos mejorada para que el servicio Angular Language coincida con el comportamiento de la aplicación. Esta migración también será un paso hacia el desbloqueo de la eliminación de View Engine, que simplificará Angular, reducirá el tamaño del paquete npm y mejorará la capacidad de mantenimiento del marco.
|
||||
|
||||
### Expand component harnesses best practices
|
||||
### Ampliar las buenas prácticas en componentes harnesses
|
||||
|
||||
Angular CDK introduced the concept of [component test harnesses](https://material.angular.io/cdk/test-harnesses) to Angular in version 9. Test harnesses allow component authors to create supported APIs for testing component interactions. We're continuing to improve this harness infrastructure and clarifying the best practices around using harnesses. We're also working to drive more harness adoption inside of Google.
|
||||
Angular CDK introdujo el concepto de [component test harnesses](https://material.angular.io/cdk/test-harnesses) en Angular en la versión 9. Los harnesses de prueba permiten a los autores de componentes crear API compatibles para probar interacciones de componentes. Continuamos mejorando esta infraestructura de harness y aclarando las mejores prácticas en torno al uso de harnesses. También estamos trabajando para impulsar una mayor adopción de harness dentro de Google.
|
||||
|
||||
### Support native [Trusted Types](https://web.dev/trusted-types/) in Angular
|
||||
### Soporte nativo de [Trusted Types](https://web.dev/trusted-types/) en Angular
|
||||
|
||||
In collaboration with Google's security team, we're adding support for the new Trusted Types API. This web platform API will help developers build more secure web applications.
|
||||
En colaboración con el equipo de seguridad de Google, estamos agregando soporte para la nueva API Trusted Types. Esta API de plataforma web ayudará a los desarrolladores a crear aplicaciones web más seguras.
|
||||
|
||||
### Integrate [MDC Web](https://material.io/develop/web/) into Angular Material
|
||||
### Integrar [MDC Web](https://material.io/develop/web/) en Angular Material
|
||||
|
||||
MDC Web is a library created by Google's Material Design team that provides reusable primitives for building Material Design components. The Angular team is incorporating these primitives into Angular Material. Using MDC Web will align Angular Material more closely with the Material Design specification, expand accessibility, overall improve component quality, and improve our team's velocity.
|
||||
MDC Web es una librería creada por el equipo de Material Design de Google que proporciona primitivas reutilizables para construir componentes de Material Design. El equipo de Angular está incorporando estas primitivas en Angular Material. El uso de MDC Web alineará Angular Material más estrechamente con la especificación de Material Design, expandirá la accesibilidad, mejorará en general la calidad de los componentes y mejorará la velocidad de nuestro equipo.
|
||||
|
||||
### Offer Google engineers better integration with Angular and Google's internal server stack
|
||||
### Ofrecer a los ingenieros de Google una mejor integración con Angular y la pila de servidores internos de Google
|
||||
|
||||
This is an internal project to add support for Angular front-ends to Google's internal integrated server stack.
|
||||
Este es un proyecto interno para agregar soporte para interfaces Angular a la pila de servidores integrados internos de Google.
|
||||
|
||||
### Angular versioning & branching
|
||||
### Control de versiones y ramificación Angular
|
||||
|
||||
We want to consolidate release management tooling between Angular's multiple GitHub repositories ([angular/angular](https://github.com/angular/angular), [angular/angular-cli](https://github.com/angular/angular-cli), and [angular/components](https://github.com/angular/components)). This effort will allow us to reuse infrastructure, unify and simplify processes, and improve our release process's reliability.
|
||||
Queremos consolidar las herramientas de administración de versiones entre los múltiples repositorios de GitHub de Angular ([angular/angular](https://github.com/angular/angular), [angular/angular-cli](https://github.com/angular/angular-cli), y [angular/components](https://github.com/angular/components)). Este esfuerzo nos permitirá reutilizar la infraestructura, unificar y simplificar procesos y mejorar la confiabilidad de nuestro proceso de lanzamiento.
|
||||
|
||||
## Future
|
||||
## Futuro
|
||||
|
||||
### Refresh introductory documentation
|
||||
### Actualizar la documentación introductoria
|
||||
|
||||
We will redefine the user learning journeys and refresh the introductory documentation. We will clearly state the benefits of Angular, how to explore its capabilities, and provide guidance so developers can become proficient with the framework in as little time as possible.
|
||||
Redefiniremos las rutas de aprendizaje del usuario y actualizaremos la documentación introductoria. Expresaremos claramente los beneficios de Angular, cómo explorar sus capacidades y brindaremos orientación para que los desarrolladores puedan dominar el framework en el menor tiempo posible.
|
||||
|
||||
### Strict typing for `@angular/forms`
|
||||
### Tipos de datos estrictos para `@angular/forms`
|
||||
|
||||
We will work on implementing stricter type checking for reactive forms. This way, we will allow developers to catch more issues during development time, enable better text editor and IDE support, and improve the type checking for reactive forms.
|
||||
Trabajaremos en la implementación de una verificación de tipo más estricta para los formularios reactivos. De esta manera, permitiremos a los desarrolladores detectar más problemas durante el tiempo de desarrollo, habilitar un mejor editor de texto y soporte IDE, y mejorar la verificación de tipos para formularios reactivos.
|
||||
|
||||
### webpack 5 in the Angular CLI
|
||||
### webpack 5 en Angular CLI
|
||||
|
||||
Webpack 5 brings a lot of build speed and bundle size improvements. To make them available for Angular developers, we will invest in migrating Angular CLI from using deprecated and removed webpack APIs.
|
||||
Webpack 5 trae muchas mejoras en la velocidad de compilación y el tamaño del paquete. Para que estén disponibles para los desarrolladores de Angular, invertiremos en migrar la CLI de Angular del uso de API de paquetes web obsoletos y eliminados.
|
||||
|
||||
### Commit message standardization
|
||||
### Estandarización del mensaje del commit
|
||||
|
||||
We want to unify commit message requirements and conformance across Angular repositories ([angular/angular](https://github.com/angular/angular), [angular/components](https://github.com/angular/components), [angular/angular-cli](https://github.com/angular/angular-cli)) to bring consistency to our development process and reuse infrastructure tooling.
|
||||
Queremos unificar los requisitos y la conformidad de los commit messages en los repositorios Angular ([angular/angular](https://github.com/angular/angular), [angular/components](https://github.com/angular/components), [angular/angular-cli](https://github.com/angular/angular-cli)) ara brindar coherencia a nuestro proceso de desarrollo y reutilizar las herramientas de infraestructura.
|
||||
|
||||
### Optional Zone.js
|
||||
### Zone.js opcional
|
||||
|
||||
We are going to design and implement a plan to make Zone.js optional from Angular applications. This way, we will simplify the framework, improve debugging, and reduce application bundle size. Additionally, this will allow us to take advantage of native async/await syntax, which currently Zone.js does not support.
|
||||
Vamos a diseñar e implementar un plan para que Zone.js sea opcional desde las aplicaciones Angular. De esta forma, simplificaremos el framework, mejoraremos la depuración y reduciremos el tamaño del paquete de aplicaciones. Además, esto nos permitirá aprovechar la sintaxis nativa async/await, que actualmente Zone.js no admite.
|
||||
|
||||
### Remove legacy [View Engine](guide/ivy)
|
||||
### Eliminar legacy [View Engine](guide/ivy)
|
||||
|
||||
After the transition of all our internal tooling to Ivy has completed, we want to remove the legacy View Engine for smaller Angular conceptual overhead, smaller package size, lower maintenance cost, and lower complexity of the codebase.
|
||||
Una vez que se haya completado la transición de todas nuestras herramientas internas a Ivy, queremos eliminar el legacy View Engine para una sobrecarga conceptual Angular más pequeña, un tamaño de paquete más pequeño, un costo de mantenimiento más bajo y una menor complejidad del código base.
|
||||
|
||||
### Angular DevTools
|
||||
### Herramientas de desarrollo Angular
|
||||
|
||||
We’ll be working on development tooling for Angular that will provide utilities for debugging and performance profiling. This project aims to help developers understand the component structure and the change detection in an Angular application.
|
||||
Trabajaremos en herramientas de desarrollo para Angular que proporcionarán utilidades para depuración y generación de perfiles de rendimiento. Este proyecto tiene como objetivo ayudar a los desarrolladores a comprender la estructura del componente y la detección de cambios en una aplicación Angular.
|
||||
|
||||
### Optional NgModules
|
||||
### NgModules opcionales
|
||||
|
||||
To simplify the Angular mental model and learning journey, we’ll be working on making NgModules optional. This work will allow developers to develop standalone components and implement an alternative API for declaring the component’s compilation scope.
|
||||
Para simplificar el modelo mental Angular y la ruta de aprendizaje, trabajaremos para hacer que NgModules sea opcional. Este trabajo permitirá a los desarrolladores desarrollar componentes independientes e implementar una API alternativa para declarar el alcance de compilación del componente.
|
||||
|
||||
### Ergonomic component level code-splitting APIs
|
||||
### API de división de código a nivel de componente ergonómico
|
||||
|
||||
A common problem of web applications is their slow initial load time. A way to improve it is to apply more granular code-splitting on a component level. To encourage this practice, we’ll be working on more ergonomic code-splitting APIs.
|
||||
Un problema común de las aplicaciones web es su lento tiempo de carga inicial. Una forma de mejorarlo es aplicar una división de código más granular a nivel de componente. Para fomentar esta práctica, trabajaremos en API de división de código más ergonómicas.
|
||||
|
||||
### Migration to ESLint
|
||||
### Migración a ESLint
|
||||
|
||||
With the deprecation of TSLint we will be moving to ESLint. As part of the process, we will work on ensuring backward compatibility with our current recommended TSLint configuration, implement a migration strategy for existing Angular applications and introduce new tooling to the Angular CLI toolchain.
|
||||
Con la deprecación de TSLint, nos trasladaremos a ESLint. Como parte del proceso, trabajaremos para garantizar la compatibilidad con versiones anteriores de nuestra configuración TSLint recomendada actual, implementaremos una estrategia de migración para las aplicaciones Angular existentes e introduciremos nuevas herramientas en la cadena de herramientas Angular CLI.
|
||||
|
74
aio/content/guide/set-document-title.en.md
Normal file
74
aio/content/guide/set-document-title.en.md
Normal file
@ -0,0 +1,74 @@
|
||||
{@a top}
|
||||
|
||||
# Set the document title
|
||||
|
||||
Your app should be able to make the browser title bar say whatever you want it to say.
|
||||
This cookbook explains how to do it.
|
||||
|
||||
See the <live-example name="set-document-title"></live-example>.
|
||||
|
||||
## The problem with *<title>*
|
||||
|
||||
The obvious approach is to bind a property of the component to the HTML `<title>` like this:
|
||||
|
||||
<code-example format=''>
|
||||
<title>{{This_Does_Not_Work}}</title>
|
||||
</code-example>
|
||||
|
||||
Sorry but that won't work.
|
||||
The root component of the application is an element contained within the `<body>` tag.
|
||||
The HTML `<title>` is in the document `<head>`, outside the body, making it inaccessible to Angular data binding.
|
||||
|
||||
You could grab the browser `document` object and set the title manually.
|
||||
That's dirty and undermines your chances of running the app outside of a browser someday.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
Running your app outside a browser means that you can take advantage of server-side
|
||||
pre-rendering for near-instant first app render times and for SEO. It means you could run from
|
||||
inside a Web Worker to improve your app's responsiveness by using multiple threads. And it
|
||||
means that you could run your app inside Electron.js or Windows Universal to deliver it to the desktop.
|
||||
|
||||
</div>
|
||||
|
||||
## Use the `Title` service
|
||||
|
||||
Fortunately, Angular bridges the gap by providing a `Title` service as part of the *Browser platform*.
|
||||
The [Title](api/platform-browser/Title) service is a simple class that provides an API
|
||||
for getting and setting the current HTML document title:
|
||||
|
||||
* `getTitle() : string`—Gets the title of the current HTML document.
|
||||
* `setTitle( newTitle : string )`—Sets the title of the current HTML document.
|
||||
|
||||
You can inject the `Title` service into the root `AppComponent` and expose a bindable `setTitle` method that calls it:
|
||||
|
||||
|
||||
<code-example path="set-document-title/src/app/app.component.ts" region="class" header="src/app/app.component.ts (class)"></code-example>
|
||||
|
||||
Bind that method to three anchor tags and voilà!
|
||||
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/set-document-title/set-title-anim.gif" alt="Set title">
|
||||
</div>
|
||||
|
||||
Here's the complete solution:
|
||||
|
||||
<code-tabs>
|
||||
<code-pane header="src/main.ts" path="set-document-title/src/main.ts"></code-pane>
|
||||
<code-pane header="src/app/app.module.ts" path="set-document-title/src/app/app.module.ts"></code-pane>
|
||||
<code-pane header="src/app/app.component.ts" path="set-document-title/src/app/app.component.ts"></code-pane>
|
||||
</code-tabs>
|
||||
|
||||
## Why provide the `Title` service in `bootstrap`
|
||||
|
||||
Generally you want to provide application-wide services in the root application component, `AppComponent`.
|
||||
|
||||
This cookbook recommends registering the title service during bootstrapping,
|
||||
a location you reserve for configuring the runtime Angular environment.
|
||||
|
||||
That's exactly what you're doing.
|
||||
The `Title` service is part of the Angular *browser platform*.
|
||||
If you bootstrap your application into a different platform,
|
||||
you'll have to provide a different `Title` service that understands
|
||||
the concept of a "document title" for that specific platform.
|
||||
Ideally, the application itself neither knows nor cares about the runtime environment.
|
@ -1,57 +1,54 @@
|
||||
{@a top}
|
||||
|
||||
# Set the document title
|
||||
# Establecer el título del documento
|
||||
|
||||
Your app should be able to make the browser title bar say whatever you want it to say.
|
||||
This cookbook explains how to do it.
|
||||
Tu aplicación debería poder hacer que el título de la barra del navegador diga lo que quieras que diga.
|
||||
Esta guía explica cómo hacerlo.
|
||||
|
||||
See the <live-example name="set-document-title"></live-example>.
|
||||
Ve el <live-example name="set-document-title"></live-example>.
|
||||
|
||||
## The problem with *<title>*
|
||||
## El problema con el *<título>*
|
||||
|
||||
The obvious approach is to bind a property of the component to the HTML `<title>` like this:
|
||||
La manera mas obvia es enlazar una propiedad del componente al HTML `<title>` como este:
|
||||
|
||||
<code-example format=''>
|
||||
<title>{{This_Does_Not_Work}}</title>
|
||||
<title>{{Esto_No_Funciona}}</title>
|
||||
</code-example>
|
||||
|
||||
Sorry but that won't work.
|
||||
The root component of the application is an element contained within the `<body>` tag.
|
||||
The HTML `<title>` is in the document `<head>`, outside the body, making it inaccessible to Angular data binding.
|
||||
Lamentablemente eso no funcionará. El componente raíz de la aplicación es un elemento contenido en la etiqueta `<body>`. El `<title>` HTML está en el `<head>` del documento, fuera del `<body>`, lo que lo hace inaccesible para el enlace de datos de Angular.
|
||||
|
||||
You could grab the browser `document` object and set the title manually.
|
||||
That's dirty and undermines your chances of running the app outside of a browser someday.
|
||||
Tu podrías tomar el objeto `document` del navegador y establecer el título manualmente.
|
||||
Eso no es ideal y socava tus posibilidades de ejecutar la aplicación fuera de un navegador algún día.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
Running your app outside a browser means that you can take advantage of server-side
|
||||
pre-rendering for near-instant first app render times and for SEO. It means you could run from
|
||||
inside a Web Worker to improve your app's responsiveness by using multiple threads. And it
|
||||
means that you could run your app inside Electron.js or Windows Universal to deliver it to the desktop.
|
||||
Ejecutar tu aplicación fuera de un navegador significa que puedes aprovechar las ventajas del renderizado del lado del servidor
|
||||
para tiempos del primer renderizado de la primera aplicación casi instantáneos y para SEO. Significa que puedes correr la aplicación
|
||||
dentro de un Web Worker para mejorar la capacidad de respuesta de tu aplicación mediante el uso de varios subprocesos. Y también
|
||||
significa que puedes ejecutar tu aplicación dentro de Electron.js o Windows Universal para enviarla al escritorio.
|
||||
|
||||
</div>
|
||||
|
||||
## Use the `Title` service
|
||||
## Utiliza el servicio `Title`
|
||||
|
||||
Fortunately, Angular bridges the gap by providing a `Title` service as part of the *Browser platform*.
|
||||
The [Title](api/platform-browser/Title) service is a simple class that provides an API
|
||||
for getting and setting the current HTML document title:
|
||||
Afortunadamente, Angular reduce las diferencias al proporcionar un servicio `Title` como parte de la *plataforma del navegador*.
|
||||
El servicio [Title](api/platform-browser/Title) es una clase simple que proporciona un API
|
||||
para obtener y configurar el título del documento HTML actual:
|
||||
|
||||
* `getTitle() : string`—Gets the title of the current HTML document.
|
||||
* `setTitle( newTitle : string )`—Sets the title of the current HTML document.
|
||||
|
||||
You can inject the `Title` service into the root `AppComponent` and expose a bindable `setTitle` method that calls it:
|
||||
* `getTitle() : string`—Obtiene el título del documento HTML actual.
|
||||
* `setTitle( newTitle : string )`—Establece el título del documento HTML actual.
|
||||
|
||||
Puedes inyectar el servicio `Title` en la raíz de `AppComponent` y exponer un método `setTitle` enlazable que lo llame:
|
||||
|
||||
<code-example path="set-document-title/src/app/app.component.ts" region="class" header="src/app/app.component.ts (class)"></code-example>
|
||||
|
||||
Bind that method to three anchor tags and voilà!
|
||||
¡Enlaza ese método a tres etiquetas de anclaje y listo!
|
||||
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/set-document-title/set-title-anim.gif" alt="Set title">
|
||||
</div>
|
||||
|
||||
Here's the complete solution:
|
||||
Aquí está la solución completa:
|
||||
|
||||
<code-tabs>
|
||||
<code-pane header="src/main.ts" path="set-document-title/src/main.ts"></code-pane>
|
||||
@ -59,16 +56,16 @@ Here's the complete solution:
|
||||
<code-pane header="src/app/app.component.ts" path="set-document-title/src/app/app.component.ts"></code-pane>
|
||||
</code-tabs>
|
||||
|
||||
## Why provide the `Title` service in `bootstrap`
|
||||
## ¿Por qué proporcionar el servicio `Title` en el `arranque`?
|
||||
|
||||
Generally you want to provide application-wide services in the root application component, `AppComponent`.
|
||||
Por lo general, deseas proporcionar servicios para toda la aplicación en el componente de la aplicación raíz, `AppComponent`.
|
||||
|
||||
This cookbook recommends registering the title service during bootstrapping,
|
||||
a location you reserve for configuring the runtime Angular environment.
|
||||
Esta guía recomienda registrar el servicio de títulos durante el arranque (boostrapping),
|
||||
una ubicación que se reserva para configurar el ambiente de ejecución de Angular.
|
||||
|
||||
That's exactly what you're doing.
|
||||
The `Title` service is part of the Angular *browser platform*.
|
||||
If you bootstrap your application into a different platform,
|
||||
you'll have to provide a different `Title` service that understands
|
||||
the concept of a "document title" for that specific platform.
|
||||
Ideally, the application itself neither knows nor cares about the runtime environment.
|
||||
Eso es exactamente lo que está haciendo.
|
||||
El servicio `Title` es parte de la *plataforma del navegador* de Angular.
|
||||
Si inicias tu aplicación en una plataforma diferente,
|
||||
tendrás que proporcionar un servicio de `Title` diferente que comprenda
|
||||
el concepto de un "título de documento" para esa plataforma específica.
|
||||
Idealmente, la aplicación en sí no conoce ni se preocupa por el ambiente de ejecución.
|
||||
|
132
aio/content/guide/setup-local.en.md
Normal file
132
aio/content/guide/setup-local.en.md
Normal file
@ -0,0 +1,132 @@
|
||||
# Setting up the local environment and workspace
|
||||
|
||||
|
||||
This guide explains how to set up your environment for Angular development using the [Angular CLI tool](cli "CLI command reference").
|
||||
It includes information about prerequisites, installing the CLI, creating an initial workspace and starter app, and running that app locally to verify your setup.
|
||||
|
||||
|
||||
<div class="callout is-helpful">
|
||||
<header>Try Angular without local setup</header>
|
||||
|
||||
If you are new to Angular, you might want to start with [Try it now!](start), which introduces the essentials of Angular in the context of a ready-made basic online store app that you can examine and modify. This standalone tutorial takes advantage of the interactive [StackBlitz](https://stackblitz.com/) environment for online development. You don't need to set up your local environment until you're ready.
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
{@a devenv}
|
||||
{@a prerequisites}
|
||||
## Prerequisites
|
||||
|
||||
To use the Angular framework, you should be familiar with the following:
|
||||
|
||||
* [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
|
||||
* [HTML](https://developer.mozilla.org/docs/Learn/HTML/Introduction_to_HTML)
|
||||
* [CSS](https://developer.mozilla.org/docs/Learn/CSS/First_steps)
|
||||
|
||||
Knowledge of [TypeScript](https://www.typescriptlang.org/) is helpful, but not required.
|
||||
|
||||
To install Angular on your local system, you need the following:
|
||||
|
||||
{@a nodejs}
|
||||
|
||||
* **Node.js**
|
||||
|
||||
Angular requires a [current, active LTS, or maintenance LTS](https://nodejs.org/about/releases) version of Node.js.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For information about specific version requirements, see the `engines` key in the [package.json](https://unpkg.com/@angular/cli/package.json) file.
|
||||
|
||||
</div>
|
||||
|
||||
For more information on installing Node.js, see [nodejs.org](http://nodejs.org "Nodejs.org").
|
||||
If you are unsure what version of Node.js runs on your system, run `node -v` in a terminal window.
|
||||
|
||||
{@a npm}
|
||||
|
||||
* **npm package manager**
|
||||
|
||||
Angular, the Angular CLI, and Angular applications depend on [npm packages](https://docs.npmjs.com/getting-started/what-is-npm) for many features and functions.
|
||||
To download and install npm packages, you need an npm package manager.
|
||||
This guide uses the [npm client](https://docs.npmjs.com/cli/install) command line interface, which is installed with `Node.js` by default.
|
||||
To check that you have the npm client installed, run `npm -v` in a terminal window.
|
||||
|
||||
|
||||
{@a install-cli}
|
||||
|
||||
## Install the Angular CLI
|
||||
|
||||
You use the Angular CLI to create projects, generate application and library code, and perform a variety of ongoing development tasks such as testing, bundling, and deployment.
|
||||
|
||||
To install the Angular CLI, open a terminal window and run the following command:
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
npm install -g @angular/cli
|
||||
</code-example>
|
||||
|
||||
{@a create-proj}
|
||||
|
||||
## Create a workspace and initial application
|
||||
|
||||
You develop apps in the context of an Angular [**workspace**](guide/glossary#workspace).
|
||||
|
||||
To create a new workspace and initial starter app:
|
||||
|
||||
1. Run the CLI command `ng new` and provide the name `my-app`, as shown here:
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
ng new my-app
|
||||
|
||||
</code-example>
|
||||
|
||||
2. The `ng new` command prompts you for information about features to include in the initial app. Accept the defaults by pressing the Enter or Return key.
|
||||
|
||||
The Angular CLI installs the necessary Angular npm packages and other dependencies. This can take a few minutes.
|
||||
|
||||
The CLI creates a new workspace and a simple Welcome app, ready to run.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
You also have the option to use Angular's strict mode, which can help you write better, more maintainable code.
|
||||
For more information, see [Strict mode](/guide/strict-mode).
|
||||
|
||||
</div>
|
||||
|
||||
{@a serve}
|
||||
|
||||
## Run the application
|
||||
|
||||
The Angular CLI includes a server, so that you can build and serve your app locally.
|
||||
|
||||
1. Navigate to the workspace folder, such as `my-app`.
|
||||
|
||||
1. Run the following command:
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
cd my-app
|
||||
ng serve --open
|
||||
</code-example>
|
||||
|
||||
The `ng serve` command launches the server, watches your files,
|
||||
and rebuilds the app as you make changes to those files.
|
||||
|
||||
The `--open` (or just `-o`) option automatically opens your browser
|
||||
to `http://localhost:4200/`.
|
||||
|
||||
If your installation and setup was successful, you should see a page similar to the following.
|
||||
|
||||
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/setup-local/app-works.png' alt="Welcome to my-app!">
|
||||
</div>
|
||||
|
||||
|
||||
## Next steps
|
||||
|
||||
* For a more thorough introduction to the fundamental concepts and terminology of Angular single-page app architecture and design principles, read the [Angular Concepts](guide/architecture) section.
|
||||
|
||||
* Work through the [Tour of Heroes Tutorial](tutorial), a complete hands-on exercise that introduces you to the app development process using the Angular CLI and walks through important subsystems.
|
||||
|
||||
* To learn more about using the Angular CLI, see the [CLI Overview](cli "CLI Overview"). In addition to creating the initial workspace and app scaffolding, you can use the CLI to generate Angular code such as components and services. The CLI supports the full development cycle, including building, testing, bundling, and deployment.
|
||||
|
||||
* For more information about the Angular files generated by `ng new`, see [Workspace and Project File Structure](guide/file-structure).
|
@ -1,64 +1,64 @@
|
||||
# Setting up the local environment and workspace
|
||||
# Configurar el ambiente y el espacio de trabajo locales
|
||||
|
||||
|
||||
This guide explains how to set up your environment for Angular development using the [Angular CLI tool](cli "CLI command reference").
|
||||
It includes information about prerequisites, installing the CLI, creating an initial workspace and starter app, and running that app locally to verify your setup.
|
||||
Esta guía explica cómo configurar tu ambiente para el desarrollo Angular usando la [Herramienta CLI de Angular](cli "CLI command reference").
|
||||
Incluye información sobre los requisitos previos, la instalación de la CLI, la creación de un espacio de trabajo inicial y una aplicación de inicio, y la ejecución de esa aplicación localmente para verificar su configuración.
|
||||
|
||||
|
||||
<div class="callout is-helpful">
|
||||
<header>Try Angular without local setup</header>
|
||||
<header>Prueba Angular sin configuración local</header>
|
||||
|
||||
If you are new to Angular, you might want to start with [Try it now!](start), which introduces the essentials of Angular in the context of a ready-made basic online store app that you can examine and modify. This standalone tutorial takes advantage of the interactive [StackBlitz](https://stackblitz.com/) environment for online development. You don't need to set up your local environment until you're ready.
|
||||
Si eres nuevo en Angular, quizás quieras comenzar con [¡Pruebalo ahora!](start), que presenta los aspectos esenciales de Angular en el contexto de una aplicación de tienda en línea básica lista para usar que puedes examinar y modificar. Este tutorial independiente aprovecha lo interactivo del ambiente [StackBlitz](https://stackblitz.com/) para el desarrollo online. No es necesario que configures tu entorno local hasta que estes listo.
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
{@a devenv}
|
||||
{@a prerequisites}
|
||||
## Prerequisites
|
||||
## Prerrequisitos
|
||||
|
||||
To use the Angular framework, you should be familiar with the following:
|
||||
Para usar el framewok Angular, debes estar familiarizado con lo siguiente:
|
||||
|
||||
* [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
|
||||
* [HTML](https://developer.mozilla.org/docs/Learn/HTML/Introduction_to_HTML)
|
||||
* [CSS](https://developer.mozilla.org/docs/Learn/CSS/First_steps)
|
||||
|
||||
Knowledge of [TypeScript](https://www.typescriptlang.org/) is helpful, but not required.
|
||||
Conocimiento de [TypeScript](https://www.typescriptlang.org/) es útil, pero no obligatorio.
|
||||
|
||||
To install Angular on your local system, you need the following:
|
||||
Para instalar Angular en su sistema local, necesitas lo siguiente:
|
||||
|
||||
{@a nodejs}
|
||||
|
||||
* **Node.js**
|
||||
|
||||
Angular requires a [current, active LTS, or maintenance LTS](https://nodejs.org/about/releases) version of Node.js.
|
||||
Angular requiere una versión [actual, LTS activa o LTS de mantenimiento](https://nodejs.org/about/releases) de Node.js.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For information about specific version requirements, see the `engines` key in the [package.json](https://unpkg.com/@angular/cli/package.json) file.
|
||||
Para obtener información sobre los requisitos específicos de la versión, consulta la llave `engines` en el archivo [package.json](https://unpkg.com/@angular/cli/package.json).
|
||||
|
||||
</div>
|
||||
|
||||
For more information on installing Node.js, see [nodejs.org](http://nodejs.org "Nodejs.org").
|
||||
If you are unsure what version of Node.js runs on your system, run `node -v` in a terminal window.
|
||||
Para obtener más información sobre la instalación de Node.js, consulta [nodejs.org](http://nodejs.org "Nodejs.org").
|
||||
Si no estas seguro de qué versión de Node.js se ejecuta en tu sistema, ejecuta `node -v` en una terminal.
|
||||
|
||||
{@a npm}
|
||||
|
||||
* **npm package manager**
|
||||
|
||||
Angular, the Angular CLI, and Angular applications depend on [npm packages](https://docs.npmjs.com/getting-started/what-is-npm) for many features and functions.
|
||||
To download and install npm packages, you need an npm package manager.
|
||||
This guide uses the [npm client](https://docs.npmjs.com/cli/install) command line interface, which is installed with `Node.js` by default.
|
||||
To check that you have the npm client installed, run `npm -v` in a terminal window.
|
||||
Angular, CLI de Angular, y las aplicaciones de Angular dependen de [paquetes npm](https://docs.npmjs.com/getting-started/what-is-npm) para muchas funcionalidades y funciones.
|
||||
Para descargar e instalar paquetes npm, necesitas un administrador de paquetes npm.
|
||||
Esta guía utiliza la interfaz de línea de comandos del [cliente npm](https://docs.npmjs.com/cli/install), que se instala con `Node.js` por defecto.
|
||||
Para comprobar que tiene instalado el cliente npm, ejecute `npm -v` en una terminal.
|
||||
|
||||
|
||||
{@a install-cli}
|
||||
|
||||
## Install the Angular CLI
|
||||
## Instalar la CLI de Angular
|
||||
|
||||
You use the Angular CLI to create projects, generate application and library code, and perform a variety of ongoing development tasks such as testing, bundling, and deployment.
|
||||
Utilizaraz la CLI de Angular para crear proyectos, generar código de aplicaciones y bibliotecas, y realizar una variedad de tareas de desarrollo, como pruebas, agrupación e implementación.
|
||||
|
||||
To install the Angular CLI, open a terminal window and run the following command:
|
||||
Para instalar CLI de Angular, abre una terminal y ejecuta el siguiente comando:
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
npm install -g @angular/cli
|
||||
@ -66,54 +66,54 @@ To install the Angular CLI, open a terminal window and run the following command
|
||||
|
||||
{@a create-proj}
|
||||
|
||||
## Create a workspace and initial application
|
||||
## Crea un espacio de trabajo y una aplicación inicial
|
||||
|
||||
You develop apps in the context of an Angular [**workspace**](guide/glossary#workspace).
|
||||
Desarrollas aplicaciones en el contexto de un [**espacio de trabajo**](guide/glossary#workspace) de Angular.
|
||||
|
||||
To create a new workspace and initial starter app:
|
||||
Para crear un nuevo espacio de trabajo y una aplicación inicial:
|
||||
|
||||
1. Run the CLI command `ng new` and provide the name `my-app`, as shown here:
|
||||
1. Ejecuta el comando CLI `ng new` y proporciona el nombre `my-app`, como se muestra aquí:
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
ng new my-app
|
||||
|
||||
</code-example>
|
||||
|
||||
2. The `ng new` command prompts you for information about features to include in the initial app. Accept the defaults by pressing the Enter or Return key.
|
||||
2. El comando `ng new` te solicitara información sobre las funciones que debe incluir en la aplicación inicial. Acepta los valores predeterminados presionando la tecla Enter o Return.
|
||||
|
||||
The Angular CLI installs the necessary Angular npm packages and other dependencies. This can take a few minutes.
|
||||
La CLI de Angular instala los paquetes npm de Angular necesarios y otras dependencias. Esto puede tardar unos minutos.
|
||||
|
||||
The CLI creates a new workspace and a simple Welcome app, ready to run.
|
||||
La CLI crea un nuevo espacio de trabajo y una aplicación de bienvenida simple, lista para ejecutarse.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
You also have the option to use Angular's strict mode, which can help you write better, more maintainable code.
|
||||
For more information, see [Strict mode](/guide/strict-mode).
|
||||
También tienes la opción de usar el modo estricto de Angular, que puede ayudarte a escribir un código mejor y más fácil de mantener.
|
||||
Para más información, mira [Modo estricto](/guide/strict-mode).
|
||||
|
||||
</div>
|
||||
|
||||
{@a serve}
|
||||
|
||||
## Run the application
|
||||
## Ejecutar la aplicación
|
||||
|
||||
The Angular CLI includes a server, so that you can build and serve your app locally.
|
||||
La CLI de Angular incluye un servidor, de modo que puede crear y servir su aplicación localmente.
|
||||
|
||||
1. Navigate to the workspace folder, such as `my-app`.
|
||||
1. Navega a la carpeta del espacio de trabajo, como `my-app`.
|
||||
|
||||
1. Run the following command:
|
||||
1. Ejecuta el siguiente comando:
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
cd my-app
|
||||
ng serve --open
|
||||
</code-example>
|
||||
|
||||
The `ng serve` command launches the server, watches your files,
|
||||
and rebuilds the app as you make changes to those files.
|
||||
El comando `ng serve` inicia el servidor, observa sus archivos,
|
||||
y reconstruye la aplicación a medida que realizas cambios en esos archivos.
|
||||
|
||||
The `--open` (or just `-o`) option automatically opens your browser
|
||||
to `http://localhost:4200/`.
|
||||
La opción `--open` (o simplemente` -o`) abre automáticamente su navegador
|
||||
en `http://localhost:4200/`.
|
||||
|
||||
If your installation and setup was successful, you should see a page similar to the following.
|
||||
Si tu instalación y configuración fue exitosa, deberías ver una página similar a la siguiente.
|
||||
|
||||
|
||||
<div class="lightbox">
|
||||
@ -121,12 +121,12 @@ If your installation and setup was successful, you should see a page similar to
|
||||
</div>
|
||||
|
||||
|
||||
## Next steps
|
||||
## Pasos siguientes
|
||||
|
||||
* For a more thorough introduction to the fundamental concepts and terminology of Angular single-page app architecture and design principles, read the [Angular Concepts](guide/architecture) section.
|
||||
* Para obtener una introducción más completa a los conceptos fundamentales y la terminología de la arquitectura de aplicaciones de una sola página y los principios de diseño de Angular, lee la sección [Conceptos Angular](guide/architecture) .
|
||||
|
||||
* Work through the [Tour of Heroes Tutorial](tutorial), a complete hands-on exercise that introduces you to the app development process using the Angular CLI and walks through important subsystems.
|
||||
* Trabaja en el [Tutorial de Tour de los Heroes](tutorial), un ejercicio práctico completo que te presenta el proceso de desarrollo de aplicaciones mediante la CLI de Angular y te explica los subsistemas importantes.
|
||||
|
||||
* To learn more about using the Angular CLI, see the [CLI Overview](cli "CLI Overview"). In addition to creating the initial workspace and app scaffolding, you can use the CLI to generate Angular code such as components and services. The CLI supports the full development cycle, including building, testing, bundling, and deployment.
|
||||
* Para obtener más información sobre el uso de la CLI de Angular, consulta la [Descripción general del CLI](cli "CLI Overview"). Además de crear el espacio de trabajo inicial y andamios de la aplicación, puedes usar la CLI para generar código de Angular como componentes y servicios. La CLI soporta el ciclo de desarrollo completo, incluida la creación, las pruebas, la agrupación y la implementación.
|
||||
|
||||
* For more information about the Angular files generated by `ng new`, see [Workspace and Project File Structure](guide/file-structure).
|
||||
* Para obtener más información sobre los archivos de Angular generados por `ng new`, consulta [Espacio de trabajo y Estructura de archivos del proyecto](guide/file-structure).
|
||||
|
27
aio/content/guide/svg-in-templates.en.md
Normal file
27
aio/content/guide/svg-in-templates.en.md
Normal file
@ -0,0 +1,27 @@
|
||||
# SVG in templates
|
||||
|
||||
It is possible to use SVG as valid templates in Angular. All of the template syntax below is
|
||||
applicable to both SVG and HTML. Learn more in the SVG [1.1](https://www.w3.org/TR/SVG11/) and
|
||||
[2.0](https://www.w3.org/TR/SVG2/) specifications.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
See the <live-example name="template-syntax"></live-example> for a working example containing the code snippets in this guide.
|
||||
|
||||
</div>
|
||||
|
||||
Why would you use SVG as template, instead of simply adding it as image to your application?
|
||||
|
||||
When you use an SVG as the template, you are able to use directives and bindings just like with HTML
|
||||
templates. This means that you will be able to dynamically generate interactive graphics.
|
||||
|
||||
Refer to the sample code snippet below for a syntax example:
|
||||
|
||||
<code-example path="template-syntax/src/app/svg.component.ts" header="src/app/svg.component.ts"></code-example>
|
||||
|
||||
Add the following code to your `svg.component.svg` file:
|
||||
|
||||
<code-example path="template-syntax/src/app/svg.component.svg" header="src/app/svg.component.svg"></code-example>
|
||||
|
||||
Here you can see the use of a `click()` event binding and the property binding syntax
|
||||
(`[attr.fill]="fillColor"`).
|
@ -1,27 +1,21 @@
|
||||
# SVG in templates
|
||||
# SVG en templates
|
||||
|
||||
It is possible to use SVG as valid templates in Angular. All of the template syntax below is
|
||||
applicable to both SVG and HTML. Learn more in the SVG [1.1](https://www.w3.org/TR/SVG11/) and
|
||||
[2.0](https://www.w3.org/TR/SVG2/) specifications.
|
||||
Es posible utilizar SVG como un template válido en Angular. Toda la sintaxis de templates a continuación es aplicable tanto a SVG como a HTML. Puedes consultar más en las especificaciones SVG [1.1](https://www.w3.org/TR/SVG11/) y [2.0](https://www.w3.org/TR/SVG2/) .
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
See the <live-example name="template-syntax"></live-example> for a working example containing the code snippets in this guide.
|
||||
Consulta <live-example name="template-syntax"></live-example> para ver un ejemplo funcional que contiene los fragmentos de código mostrados en esta guía. </div>
|
||||
|
||||
</div>
|
||||
¿Por qué usar un template SVG, cuando puedes simplemente añadirlo como una imagen a tu aplicación?
|
||||
|
||||
Why would you use SVG as template, instead of simply adding it as image to your application?
|
||||
Cuando utilizas SVG como template, puedes emplear directivas y enlaces de la misma forma que harías con templates HTML. Esto significa que puedes generar gráficos interactivos dinámicamente
|
||||
|
||||
When you use an SVG as the template, you are able to use directives and bindings just like with HTML
|
||||
templates. This means that you will be able to dynamically generate interactive graphics.
|
||||
|
||||
Refer to the sample code snippet below for a syntax example:
|
||||
Consulta el fragmento de código proporcionado para un ejemplo de la sintaxis:
|
||||
|
||||
<code-example path="template-syntax/src/app/svg.component.ts" header="src/app/svg.component.ts"></code-example>
|
||||
|
||||
Add the following code to your `svg.component.svg` file:
|
||||
Añade este código a tu archivo`svg.component.svg`:
|
||||
|
||||
<code-example path="template-syntax/src/app/svg.component.svg" header="src/app/svg.component.svg"></code-example>
|
||||
|
||||
Here you can see the use of a `click()` event binding and the property binding syntax
|
||||
(`[attr.fill]="fillColor"`).
|
||||
Aquí puedes ver el uso de un enlace de evento `click()` y la sintaxis de un enlace de propiedad (`[attr.fill]="fillColor"`).
|
||||
|
65
aio/content/guide/template-statements.en.md
Normal file
65
aio/content/guide/template-statements.en.md
Normal file
@ -0,0 +1,65 @@
|
||||
# Template statements
|
||||
|
||||
A template **statement** responds to an **event** raised by a binding target
|
||||
such as an element, component, or directive.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
See the <live-example name="template-syntax">Template syntax</live-example> for
|
||||
the syntax and code snippets in this guide.
|
||||
|
||||
</div>
|
||||
|
||||
The following template statement appears in quotes to the right of the `=` symbol as in `(event)="statement"`.
|
||||
|
||||
<code-example path="template-syntax/src/app/app.component.html" region="context-component-statement" header="src/app/app.component.html"></code-example>
|
||||
|
||||
A template statement *has a side effect*.
|
||||
That's the whole point of an event.
|
||||
It's how you update application state from user action.
|
||||
|
||||
Responding to events is the other side of Angular's "unidirectional data flow".
|
||||
You're free to change anything, anywhere, during this turn of the event loop.
|
||||
|
||||
Like template expressions, template *statements* use a language that looks like JavaScript.
|
||||
The template statement parser differs from the template expression parser and
|
||||
specifically supports both basic assignment (`=`) and chaining expressions with <code>;</code>.
|
||||
|
||||
However, certain JavaScript and template expression syntax is not allowed:
|
||||
|
||||
* <code>new</code>
|
||||
* increment and decrement operators, `++` and `--`
|
||||
* operator assignment, such as `+=` and `-=`
|
||||
* the bitwise operators, such as `|` and `&`
|
||||
* the [pipe operator](guide/template-expression-operators#pipe)
|
||||
|
||||
## Statement context
|
||||
|
||||
As with expressions, statements can refer only to what's in the statement context
|
||||
such as an event handling method of the component instance.
|
||||
|
||||
The *statement context* is typically the component instance.
|
||||
The *deleteHero* in `(click)="deleteHero()"` is a method of the data-bound component.
|
||||
|
||||
<code-example path="template-syntax/src/app/app.component.html" region="context-component-statement" header="src/app/app.component.html"></code-example>
|
||||
|
||||
The statement context may also refer to properties of the template's own context.
|
||||
In the following examples, the template `$event` object,
|
||||
a [template input variable](guide/built-in-directives#template-input-variable) (`let hero`),
|
||||
and a [template reference variable](guide/template-reference-variables) (`#heroForm`)
|
||||
are passed to an event handling method of the component.
|
||||
|
||||
<code-example path="template-syntax/src/app/app.component.html" region="context-var-statement" header="src/app/app.component.html"></code-example>
|
||||
|
||||
Template context names take precedence over component context names.
|
||||
In `deleteHero(hero)` above, the `hero` is the template input variable,
|
||||
not the component's `hero` property.
|
||||
|
||||
## Statement guidelines
|
||||
|
||||
Template statements cannot refer to anything in the global namespace. They
|
||||
can't refer to `window` or `document`.
|
||||
They can't call `console.log` or `Math.max`.
|
||||
|
||||
As with expressions, avoid writing complex template statements.
|
||||
A method call or simple property assignment should be the norm.
|
@ -1,65 +1,65 @@
|
||||
# Template statements
|
||||
# Declaraciones de plantilla
|
||||
|
||||
A template **statement** responds to an **event** raised by a binding target
|
||||
such as an element, component, or directive.
|
||||
Una **declaración** de plantilla responde a un **evento** provocado por un enlace a un objetivo
|
||||
como un elemento, componente o directiva.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
See the <live-example name="template-syntax">Template syntax</live-example> for
|
||||
the syntax and code snippets in this guide.
|
||||
Mira la <live-example name="template-syntax">sintaxis de la plantilla</live-example> para
|
||||
la sintaxis y los fragmentos de código de esta guía.
|
||||
|
||||
</div>
|
||||
|
||||
The following template statement appears in quotes to the right of the `=` symbol as in `(event)="statement"`.
|
||||
La siguiente declaración de plantilla aparece entre comillas a la derecha del símbolo `=` como en `(event)="statement"`.
|
||||
|
||||
<code-example path="template-syntax/src/app/app.component.html" region="context-component-statement" header="src/app/app.component.html"></code-example>
|
||||
|
||||
A template statement *has a side effect*.
|
||||
That's the whole point of an event.
|
||||
It's how you update application state from user action.
|
||||
Una declaración de plantilla *tiene un efecto secundario*.
|
||||
Ese es el objetivo de un evento.
|
||||
Es la forma de actualizar el estado de la aplicación a partir de la acción del usuario.
|
||||
|
||||
Responding to events is the other side of Angular's "unidirectional data flow".
|
||||
You're free to change anything, anywhere, during this turn of the event loop.
|
||||
Responder a los eventos es el otro lado del "flujo de datos unidireccional" de Angular.
|
||||
Eres libre de cambiar cualquier cosa, en cualquier lugar, durante este ciclo del evento.
|
||||
|
||||
Like template expressions, template *statements* use a language that looks like JavaScript.
|
||||
The template statement parser differs from the template expression parser and
|
||||
specifically supports both basic assignment (`=`) and chaining expressions with <code>;</code>.
|
||||
Al igual que las expresiones de plantilla, las *declaraciones* de plantilla utilizan un lenguaje que se parece a JavaScript.
|
||||
El analizador de declaraciones de plantilla difiere del analizador de expresiones de plantilla y
|
||||
admite específicamente tanto la asignación básica (`=`) como el encadenamiento de expresiones con <code>;</code>.
|
||||
|
||||
However, certain JavaScript and template expression syntax is not allowed:
|
||||
Sin embargo, no se permiten determinadas sintaxis de expresión de plantilla y JavaScript:
|
||||
|
||||
* <code>new</code>
|
||||
* increment and decrement operators, `++` and `--`
|
||||
* operator assignment, such as `+=` and `-=`
|
||||
* the bitwise operators, such as `|` and `&`
|
||||
* the [pipe operator](guide/template-expression-operators#pipe)
|
||||
* Operadores de incremento y decremento, `++` y `--`
|
||||
* operador de asignación , como `+=` y `-=`
|
||||
* los operadores bit a bit, como `|` y `&`
|
||||
* el [operador pipe](guide/template-expression-operators#pipe)
|
||||
|
||||
## Statement context
|
||||
## Contexto de la declaración
|
||||
|
||||
As with expressions, statements can refer only to what's in the statement context
|
||||
such as an event handling method of the component instance.
|
||||
Al igual que con las expresiones, las declaraciones solo pueden ver lo que está en el contexto de la declaración
|
||||
como un método de manejo de eventos de la instancia del componente.
|
||||
|
||||
The *statement context* is typically the component instance.
|
||||
The *deleteHero* in `(click)="deleteHero()"` is a method of the data-bound component.
|
||||
El *contexto de la declaración* es típicamente la instancia del componente.
|
||||
El *deleteHero* en `(click)="deleteHero()"` es un método del componente enlazado a datos.
|
||||
|
||||
<code-example path="template-syntax/src/app/app.component.html" region="context-component-statement" header="src/app/app.component.html"></code-example>
|
||||
|
||||
The statement context may also refer to properties of the template's own context.
|
||||
In the following examples, the template `$event` object,
|
||||
a [template input variable](guide/built-in-directives#template-input-variable) (`let hero`),
|
||||
and a [template reference variable](guide/template-reference-variables) (`#heroForm`)
|
||||
are passed to an event handling method of the component.
|
||||
El contexto de la declaración también puede ver las propiedades del propio contexto de la plantilla.
|
||||
En los siguientes ejemplos, el objeto de plantilla `$event`,
|
||||
una [variable de entrada de plantilla](guide/built-in-directives#template-input-variable) (`let hero`),
|
||||
y una [variable de referencia de plantilla](guide/template-reference-variables) (`#heroForm`)
|
||||
se pasan a un método de manejo de eventos del componente.
|
||||
|
||||
<code-example path="template-syntax/src/app/app.component.html" region="context-var-statement" header="src/app/app.component.html"></code-example>
|
||||
|
||||
Template context names take precedence over component context names.
|
||||
In `deleteHero(hero)` above, the `hero` is the template input variable,
|
||||
not the component's `hero` property.
|
||||
Los nombres de contexto de plantilla tienen prioridad sobre los nombres de contexto de componentes.
|
||||
En `deleteHero(hero)` anterior, el `hero` es la variable de entrada de la plantilla
|
||||
no la propiedad `hero` del componente.
|
||||
|
||||
## Statement guidelines
|
||||
## Pautas de la declaración
|
||||
|
||||
Template statements cannot refer to anything in the global namespace. They
|
||||
can't refer to `window` or `document`.
|
||||
They can't call `console.log` or `Math.max`.
|
||||
Las declaraciones de plantilla no pueden ver nada en el espacio de nombres global. No
|
||||
pueden ver `window` o `document`.
|
||||
No pueden llamar `console.log` o `Math.max`.
|
||||
|
||||
As with expressions, avoid writing complex template statements.
|
||||
A method call or simple property assignment should be the norm.
|
||||
Al igual que con las expresiones, evita escribir declaraciones de plantilla complejas.
|
||||
Una llamada a un método o una simple asignación de propiedad debería ser la norma.
|
||||
|
41
aio/content/guide/testing-pipes.en.md
Normal file
41
aio/content/guide/testing-pipes.en.md
Normal file
@ -0,0 +1,41 @@
|
||||
# Testing Pipes
|
||||
|
||||
You can test [pipes](guide/pipes) without the Angular testing utilities.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For the sample app that the testing guides describe, see the <live-example name="testing" embedded-style noDownload>sample app</live-example>.
|
||||
|
||||
For the tests features in the testing guides, see <live-example name="testing" stackblitz="specs" noDownload>tests</live-example>.
|
||||
|
||||
</div>
|
||||
|
||||
## Testing the `TitleCasePipe`
|
||||
|
||||
A pipe class has one method, `transform`, that manipulates the input
|
||||
value into a transformed output value.
|
||||
The `transform` implementation rarely interacts with the DOM.
|
||||
Most pipes have no dependence on Angular other than the `@Pipe`
|
||||
metadata and an interface.
|
||||
|
||||
Consider a `TitleCasePipe` that capitalizes the first letter of each word.
|
||||
Here's an implementation with a regular expression.
|
||||
|
||||
<code-example path="testing/src/app/shared/title-case.pipe.ts" header="app/shared/title-case.pipe.ts"></code-example>
|
||||
|
||||
Anything that uses a regular expression is worth testing thoroughly.
|
||||
Use simple Jasmine to explore the expected cases and the edge cases.
|
||||
|
||||
<code-example path="testing/src/app/shared/title-case.pipe.spec.ts" region="excerpt" header="app/shared/title-case.pipe.spec.ts"></code-example>
|
||||
|
||||
{@a write-tests}
|
||||
|
||||
## Writing DOM tests to support a pipe test
|
||||
|
||||
These are tests of the pipe _in isolation_.
|
||||
They can't tell if the `TitleCasePipe` is working properly as applied in the application components.
|
||||
|
||||
Consider adding component tests such as this one:
|
||||
|
||||
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="title-case-pipe" header="app/hero/hero-detail.component.spec.ts (pipe test)"></code-example>
|
||||
|
@ -1,41 +1,39 @@
|
||||
# Testing Pipes
|
||||
# Probando los Pipes
|
||||
|
||||
You can test [pipes](guide/pipes) without the Angular testing utilities.
|
||||
Puedes probar los [pipes](guide/pipes) sin las utilidades para pruebas de Angular.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For the sample app that the testing guides describe, see the <live-example name="testing" embedded-style noDownload>sample app</live-example>.
|
||||
Para la aplicación de muestra que indican las guías de prueba, visita <live-example name="testing" embedded-style noDownload>la aplicación de prueba</live-example>.
|
||||
|
||||
For the tests features in the testing guides, see <live-example name="testing" stackblitz="specs" noDownload>tests</live-example>.
|
||||
Para las pruebas de funcionalidades en las guías de prueba, visita <live-example name="testing" stackblitz="specs" noDownload>pruebas</live-example>.
|
||||
|
||||
</div>
|
||||
|
||||
## Testing the `TitleCasePipe`
|
||||
## Probando el `TitleCasePipe`
|
||||
|
||||
A pipe class has one method, `transform`, that manipulates the input
|
||||
value into a transformed output value.
|
||||
The `transform` implementation rarely interacts with the DOM.
|
||||
Most pipes have no dependence on Angular other than the `@Pipe`
|
||||
metadata and an interface.
|
||||
La clase de un pipe contiene un método, `transform`, que manipula el valor de entrada y lo transforma en un valor de salida.
|
||||
La implementación del `transform` rara vez interactúa con el DOM.
|
||||
La mayoría de los pipes no dependen de Angular más allá de los metadatos del `@Pipe` y una interfaz.
|
||||
|
||||
Consider a `TitleCasePipe` that capitalizes the first letter of each word.
|
||||
Here's an implementation with a regular expression.
|
||||
Considera una `TitleCasePipe` que pone en mayúscula la primera letra de cada palabra.
|
||||
Aquí está una implementación con una expresión regular.
|
||||
|
||||
<code-example path="testing/src/app/shared/title-case.pipe.ts" header="app/shared/title-case.pipe.ts"></code-example>
|
||||
|
||||
Anything that uses a regular expression is worth testing thoroughly.
|
||||
Use simple Jasmine to explore the expected cases and the edge cases.
|
||||
Cualquier cosa que use una expresión regular vale la pena probarla a fondo.
|
||||
Simplemente usa Jasmine para explorar todos los casos esperados y todos los casos extremos.
|
||||
|
||||
<code-example path="testing/src/app/shared/title-case.pipe.spec.ts" region="excerpt" header="app/shared/title-case.pipe.spec.ts"></code-example>
|
||||
|
||||
{@a write-tests}
|
||||
|
||||
## Writing DOM tests to support a pipe test
|
||||
## Escribiendo pruebas DOM para soportar una prueba de un pipe
|
||||
|
||||
These are tests of the pipe _in isolation_.
|
||||
They can't tell if the `TitleCasePipe` is working properly as applied in the application components.
|
||||
Estas son pruebas de un pipe _en aislamiento_.
|
||||
No pueden decir si el `TitleCasePipe` está funcionando correctamente tal y como se aplica en los componentes de la aplicación.
|
||||
|
||||
Consider adding component tests such as this one:
|
||||
Considera añadir pruebas de componente como por ejemplo esta:
|
||||
|
||||
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="title-case-pipe" header="app/hero/hero-detail.component.spec.ts (pipe test)"></code-example>
|
||||
|
||||
|
199
aio/content/guide/testing-services.en.md
Normal file
199
aio/content/guide/testing-services.en.md
Normal file
@ -0,0 +1,199 @@
|
||||
# Testing services
|
||||
|
||||
|
||||
To check that your services are working as you intend, you can write tests specifically for them.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For the sample app that the testing guides describe, see the <live-example name="testing" embedded-style noDownload>sample app</live-example>.
|
||||
|
||||
For the tests features in the testing guides, see <live-example name="testing" stackblitz="specs" noDownload>tests</live-example>.
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
Services are often the easiest files to unit test.
|
||||
Here are some synchronous and asynchronous unit tests of the `ValueService`
|
||||
written without assistance from Angular testing utilities.
|
||||
|
||||
<code-example path="testing/src/app/demo/demo.spec.ts" region="ValueService" header="app/demo/demo.spec.ts"></code-example>
|
||||
|
||||
{@a services-with-dependencies}
|
||||
|
||||
## Services with dependencies
|
||||
|
||||
Services often depend on other services that Angular injects into the constructor.
|
||||
In many cases, it's easy to create and _inject_ these dependencies by hand while
|
||||
calling the service's constructor.
|
||||
|
||||
The `MasterService` is a simple example:
|
||||
|
||||
<code-example path="testing/src/app/demo/demo.ts" region="MasterService" header="app/demo/demo.ts"></code-example>
|
||||
|
||||
`MasterService` delegates its only method, `getValue`, to the injected `ValueService`.
|
||||
|
||||
Here are several ways to test it.
|
||||
|
||||
<code-example path="testing/src/app/demo/demo.spec.ts" region="MasterService" header="app/demo/demo.spec.ts"></code-example>
|
||||
|
||||
The first test creates a `ValueService` with `new` and passes it to the `MasterService` constructor.
|
||||
|
||||
However, injecting the real service rarely works well as most dependent services are difficult to create and control.
|
||||
|
||||
Instead you can mock the dependency, use a dummy value, or create a
|
||||
[spy](https://jasmine.github.io/2.0/introduction.html#section-Spies)
|
||||
on the pertinent service method.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
Prefer spies as they are usually the easiest way to mock services.
|
||||
|
||||
</div>
|
||||
|
||||
These standard testing techniques are great for unit testing services in isolation.
|
||||
|
||||
However, you almost always inject services into application classes using Angular
|
||||
dependency injection and you should have tests that reflect that usage pattern.
|
||||
Angular testing utilities make it easy to investigate how injected services behave.
|
||||
|
||||
## Testing services with the _TestBed_
|
||||
|
||||
Your app relies on Angular [dependency injection (DI)](guide/dependency-injection)
|
||||
to create services.
|
||||
When a service has a dependent service, DI finds or creates that dependent service.
|
||||
And if that dependent service has its own dependencies, DI finds-or-creates them as well.
|
||||
|
||||
As service _consumer_, you don't worry about any of this.
|
||||
You don't worry about the order of constructor arguments or how they're created.
|
||||
|
||||
As a service _tester_, you must at least think about the first level of service dependencies
|
||||
but you _can_ let Angular DI do the service creation and deal with constructor argument order
|
||||
when you use the `TestBed` testing utility to provide and create services.
|
||||
|
||||
{@a testbed}
|
||||
|
||||
## Angular _TestBed_
|
||||
|
||||
The `TestBed` is the most important of the Angular testing utilities.
|
||||
The `TestBed` creates a dynamically-constructed Angular _test_ module that emulates
|
||||
an Angular [@NgModule](guide/ngmodules).
|
||||
|
||||
The `TestBed.configureTestingModule()` method takes a metadata object that can have most of the properties of an [@NgModule](guide/ngmodules).
|
||||
|
||||
To test a service, you set the `providers` metadata property with an
|
||||
array of the services that you'll test or mock.
|
||||
|
||||
<code-example path="testing/src/app/demo/demo.testbed.spec.ts" region="value-service-before-each" header="app/demo/demo.testbed.spec.ts (provide ValueService in beforeEach)"></code-example>
|
||||
|
||||
Then inject it inside a test by calling `TestBed.inject()` with the service class as the argument.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
**Note:** `TestBed.get()` was deprecated as of Angular version 9.
|
||||
To help minimize breaking changes, Angular introduces a new function called `TestBed.inject()`, which you should use instead.
|
||||
For information on the removal of `TestBed.get()`,
|
||||
see its entry in the [Deprecations index](guide/deprecations#index).
|
||||
|
||||
</div>
|
||||
|
||||
<code-example path="testing/src/app/demo/demo.testbed.spec.ts" region="value-service-inject-it"></code-example>
|
||||
|
||||
Or inside the `beforeEach()` if you prefer to inject the service as part of your setup.
|
||||
|
||||
<code-example path="testing/src/app/demo/demo.testbed.spec.ts" region="value-service-inject-before-each"> </code-example>
|
||||
|
||||
When testing a service with a dependency, provide the mock in the `providers` array.
|
||||
|
||||
In the following example, the mock is a spy object.
|
||||
|
||||
<code-example path="testing/src/app/demo/demo.testbed.spec.ts" region="master-service-before-each"></code-example>
|
||||
|
||||
The test consumes that spy in the same way it did earlier.
|
||||
|
||||
<code-example path="testing/src/app/demo/demo.testbed.spec.ts" region="master-service-it">
|
||||
</code-example>
|
||||
|
||||
{@a no-before-each}
|
||||
|
||||
## Testing without _beforeEach()_
|
||||
|
||||
Most test suites in this guide call `beforeEach()` to set the preconditions for each `it()` test
|
||||
and rely on the `TestBed` to create classes and inject services.
|
||||
|
||||
There's another school of testing that never calls `beforeEach()` and prefers to create classes explicitly rather than use the `TestBed`.
|
||||
|
||||
Here's how you might rewrite one of the `MasterService` tests in that style.
|
||||
|
||||
Begin by putting re-usable, preparatory code in a _setup_ function instead of `beforeEach()`.
|
||||
|
||||
<code-example
|
||||
path="testing/src/app/demo/demo.spec.ts"
|
||||
region="no-before-each-setup"
|
||||
header="app/demo/demo.spec.ts (setup)"></code-example>
|
||||
|
||||
The `setup()` function returns an object literal
|
||||
with the variables, such as `masterService`, that a test might reference.
|
||||
You don't define _semi-global_ variables (e.g., `let masterService: MasterService`)
|
||||
in the body of the `describe()`.
|
||||
|
||||
Then each test invokes `setup()` in its first line, before continuing
|
||||
with steps that manipulate the test subject and assert expectations.
|
||||
|
||||
<code-example
|
||||
path="testing/src/app/demo/demo.spec.ts"
|
||||
region="no-before-each-test"></code-example>
|
||||
|
||||
Notice how the test uses
|
||||
[_destructuring assignment_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)
|
||||
to extract the setup variables that it needs.
|
||||
|
||||
<code-example
|
||||
path="testing/src/app/demo/demo.spec.ts"
|
||||
region="no-before-each-setup-call">
|
||||
</code-example>
|
||||
|
||||
Many developers feel this approach is cleaner and more explicit than the
|
||||
traditional `beforeEach()` style.
|
||||
|
||||
Although this testing guide follows the traditional style and
|
||||
the default [CLI schematics](https://github.com/angular/angular-cli)
|
||||
generate test files with `beforeEach()` and `TestBed`,
|
||||
feel free to adopt _this alternative approach_ in your own projects.
|
||||
|
||||
## Testing HTTP services
|
||||
|
||||
Data services that make HTTP calls to remote servers typically inject and delegate
|
||||
to the Angular [`HttpClient`](guide/http) service for XHR calls.
|
||||
|
||||
You can test a data service with an injected `HttpClient` spy as you would
|
||||
test any service with a dependency.
|
||||
<code-example
|
||||
path="testing/src/app/model/hero.service.spec.ts"
|
||||
region="test-with-spies"
|
||||
header="app/model/hero.service.spec.ts (tests with spies)">
|
||||
</code-example>
|
||||
|
||||
<div class="alert is-important">
|
||||
|
||||
The `HeroService` methods return `Observables`. You must
|
||||
_subscribe_ to an observable to (a) cause it to execute and (b)
|
||||
assert that the method succeeds or fails.
|
||||
|
||||
The `subscribe()` method takes a success (`next`) and fail (`error`) callback.
|
||||
Make sure you provide _both_ callbacks so that you capture errors.
|
||||
Neglecting to do so produces an asynchronous uncaught observable error that
|
||||
the test runner will likely attribute to a completely different test.
|
||||
|
||||
</div>
|
||||
|
||||
## _HttpClientTestingModule_
|
||||
|
||||
Extended interactions between a data service and the `HttpClient` can be complex
|
||||
and difficult to mock with spies.
|
||||
|
||||
The `HttpClientTestingModule` can make these testing scenarios more manageable.
|
||||
|
||||
While the _code sample_ accompanying this guide demonstrates `HttpClientTestingModule`,
|
||||
this page defers to the [Http guide](guide/http#testing-http-requests),
|
||||
which covers testing with the `HttpClientTestingModule` in detail.
|
||||
|
@ -1,172 +1,172 @@
|
||||
# Testing services
|
||||
# Probando servicios
|
||||
|
||||
|
||||
To check that your services are working as you intend, you can write tests specifically for them.
|
||||
Para comprobar que tus servicios funcionan como deseas, puedes escribir pruebas específicamente para ellos.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For the sample app that the testing guides describe, see the <live-example name="testing" embedded-style noDownload>sample app</live-example>.
|
||||
Para la aplicación de muestra que describe las guías de prueba, consulta la <live-example name="testing" embedded-style noDownload>aplicación de muestra</live-example>.
|
||||
|
||||
For the tests features in the testing guides, see <live-example name="testing" stackblitz="specs" noDownload>tests</live-example>.
|
||||
Para las funcionalidades de las pruebas en las guías de prueba, consulta las <live-example name="testing" stackblitz="specs" noDownload>pruebas</live-example>.
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
Services are often the easiest files to unit test.
|
||||
Here are some synchronous and asynchronous unit tests of the `ValueService`
|
||||
written without assistance from Angular testing utilities.
|
||||
Los servicios suelen ser los archivos en los que es mas fácil realizar pruebas unitarias.
|
||||
Estas son algunas pruebas unitarias sincrónicas y asincrónicas del `ValueService`
|
||||
escritas sin ayuda de las utilidades de prueba Angular.
|
||||
|
||||
<code-example path="testing/src/app/demo/demo.spec.ts" region="ValueService" header="app/demo/demo.spec.ts"></code-example>
|
||||
|
||||
{@a services-with-dependencies}
|
||||
|
||||
## Services with dependencies
|
||||
## Servicios con dependencias
|
||||
|
||||
Services often depend on other services that Angular injects into the constructor.
|
||||
In many cases, it's easy to create and _inject_ these dependencies by hand while
|
||||
calling the service's constructor.
|
||||
Los servicios a menudo dependen de otros servicios que Angular inyecta en el constructor.
|
||||
En muchos casos, es fácil crear e _inyectar_ estas dependencias a mano mientras
|
||||
se llama al constructor del servicio.
|
||||
|
||||
The `MasterService` is a simple example:
|
||||
El `MasterService` es un ejemplo simple:
|
||||
|
||||
<code-example path="testing/src/app/demo/demo.ts" region="MasterService" header="app/demo/demo.ts"></code-example>
|
||||
|
||||
`MasterService` delegates its only method, `getValue`, to the injected `ValueService`.
|
||||
`MasterService` delega su único método, `getValue`, al `ValueService` inyectado.
|
||||
|
||||
Here are several ways to test it.
|
||||
Aquí hay varias formas de probarlo.
|
||||
|
||||
<code-example path="testing/src/app/demo/demo.spec.ts" region="MasterService" header="app/demo/demo.spec.ts"></code-example>
|
||||
|
||||
The first test creates a `ValueService` with `new` and passes it to the `MasterService` constructor.
|
||||
La primera prueba crea un `ValueService` con `new` y lo pasa al constructor de `MasterService`.
|
||||
|
||||
However, injecting the real service rarely works well as most dependent services are difficult to create and control.
|
||||
Sin embargo, inyectar el servicio real rara vez funciona bien, ya que la mayoría de los servicios dependientes son difíciles de crear y controlar.
|
||||
|
||||
Instead you can mock the dependency, use a dummy value, or create a
|
||||
[spy](https://jasmine.github.io/2.0/introduction.html#section-Spies)
|
||||
on the pertinent service method.
|
||||
En su lugar, puedes hacer un mock de la dependencia, usar un valor ficticio o crear un
|
||||
[espía](https://jasmine.github.io/2.0/introduction.html#section-Spies)
|
||||
sobre el método del servicio pertinente.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
Prefer spies as they are usually the easiest way to mock services.
|
||||
Utiliza espías, ya que suelen ser la forma más fácil de hacer mocks a los servicios.
|
||||
|
||||
</div>
|
||||
|
||||
These standard testing techniques are great for unit testing services in isolation.
|
||||
Estas técnicas de prueba estándar son excelentes para hacer pruebas unitarias de servicios de forma aislada.
|
||||
|
||||
However, you almost always inject services into application classes using Angular
|
||||
dependency injection and you should have tests that reflect that usage pattern.
|
||||
Angular testing utilities make it easy to investigate how injected services behave.
|
||||
Sin embargo, casi siempre inyecta servicios en clases de aplicación usando
|
||||
la inyección de dependencias de Angular y debe tener pruebas que reflejen ese patrón de uso.
|
||||
Las utilidades de pruebas de Angular facilitan la investigación de cómo se comportan los servicios inyectados.
|
||||
|
||||
## Testing services with the _TestBed_
|
||||
## Probando los servicios con _TestBed_
|
||||
|
||||
Your app relies on Angular [dependency injection (DI)](guide/dependency-injection)
|
||||
to create services.
|
||||
When a service has a dependent service, DI finds or creates that dependent service.
|
||||
And if that dependent service has its own dependencies, DI finds-or-creates them as well.
|
||||
Tu aplicación se basa en la [inyección de dependencias (ID)](guide/dependency-injection) de Angular
|
||||
para crear servicios.
|
||||
Cuando un servicio tiene un servicio dependiente, la inyección de dependencia busca o crea ese servicio dependiente.
|
||||
Y si ese servicio dependiente tiene sus propias dependencias, la inyección de dependencia también las encuentra o crea.
|
||||
|
||||
As service _consumer_, you don't worry about any of this.
|
||||
You don't worry about the order of constructor arguments or how they're created.
|
||||
Como _consumidor_ de servicios, no te preocupas por nada de esto.
|
||||
No te preocupes por el orden de los argumentos del constructor o cómo se crean.
|
||||
|
||||
As a service _tester_, you must at least think about the first level of service dependencies
|
||||
but you _can_ let Angular DI do the service creation and deal with constructor argument order
|
||||
when you use the `TestBed` testing utility to provide and create services.
|
||||
Como _probador_ de servicios, debes pensar al menos en el primer nivel de dependencias del servicio
|
||||
pero _puedes_ dejar que la inyección de dependencia de Angular haga la creación del servicio y se ocupe del orden de los argumentos del constructor
|
||||
cuando uses la utilidad de prueba `TestBed` para proporcionar y crear servicios.
|
||||
|
||||
{@a testbed}
|
||||
|
||||
## Angular _TestBed_
|
||||
|
||||
The `TestBed` is the most important of the Angular testing utilities.
|
||||
The `TestBed` creates a dynamically-constructed Angular _test_ module that emulates
|
||||
an Angular [@NgModule](guide/ngmodules).
|
||||
El `TestBed` es la más importante de las utilidades de prueba de Angular.
|
||||
El `TestBed` crea un modulo Angular _test_ construido dinámicamente que emula
|
||||
un [@NgModule](guide/ngmodules) de Angular.
|
||||
|
||||
The `TestBed.configureTestingModule()` method takes a metadata object that can have most of the properties of an [@NgModule](guide/ngmodules).
|
||||
El método `TestBed.configureTestingModule()` toma un objeto de metadatos que puede tener la mayoría de las propiedades de un [@NgModule](guide/ngmodules).
|
||||
|
||||
To test a service, you set the `providers` metadata property with an
|
||||
array of the services that you'll test or mock.
|
||||
Para probar un servicio, estableces la propiedad de metadatos de `providers` con un
|
||||
array de los servicios que probarás o simularás.
|
||||
|
||||
<code-example path="testing/src/app/demo/demo.testbed.spec.ts" region="value-service-before-each" header="app/demo/demo.testbed.spec.ts (provide ValueService in beforeEach)"></code-example>
|
||||
|
||||
Then inject it inside a test by calling `TestBed.inject()` with the service class as the argument.
|
||||
Luego inyéctalo dentro de una prueba llamando `TestBed.inject()` con la clase del servicio como argumento.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
**Note:** `TestBed.get()` was deprecated as of Angular version 9.
|
||||
To help minimize breaking changes, Angular introduces a new function called `TestBed.inject()`, which you should use instead.
|
||||
For information on the removal of `TestBed.get()`,
|
||||
see its entry in the [Deprecations index](guide/deprecations#index).
|
||||
**Nota:** `TestBed.get()` quedó obsoleto a partir de la versión 9 de Angular.
|
||||
Para ayudar a minimizar los cambios importantes, Angular presenta una nueva función llamada `TestBed.inject()`, que deberas usar en su lugar.
|
||||
Para obtener información sobre la eliminación de `TestBed.get()`,
|
||||
consulta su entrada en el [Índice de bajas](guide/deprecations#index).
|
||||
|
||||
</div>
|
||||
|
||||
<code-example path="testing/src/app/demo/demo.testbed.spec.ts" region="value-service-inject-it"></code-example>
|
||||
|
||||
Or inside the `beforeEach()` if you prefer to inject the service as part of your setup.
|
||||
O dentro del `beforeEach()` si prefieres inyectar el servicio como parte de tu configuración.
|
||||
|
||||
<code-example path="testing/src/app/demo/demo.testbed.spec.ts" region="value-service-inject-before-each"> </code-example>
|
||||
|
||||
When testing a service with a dependency, provide the mock in the `providers` array.
|
||||
Al probar un servicio con una dependencia, proporcione un mock en el array de `providers`.
|
||||
|
||||
In the following example, the mock is a spy object.
|
||||
En el siguiente ejemplo, el mock es un objeto espía.
|
||||
|
||||
<code-example path="testing/src/app/demo/demo.testbed.spec.ts" region="master-service-before-each"></code-example>
|
||||
|
||||
The test consumes that spy in the same way it did earlier.
|
||||
La prueba consume ese espía de la misma manera que lo hizo antes.
|
||||
|
||||
<code-example path="testing/src/app/demo/demo.testbed.spec.ts" region="master-service-it">
|
||||
</code-example>
|
||||
|
||||
{@a no-before-each}
|
||||
|
||||
## Testing without _beforeEach()_
|
||||
## Pruebas sin _beforeEach()_
|
||||
|
||||
Most test suites in this guide call `beforeEach()` to set the preconditions for each `it()` test
|
||||
and rely on the `TestBed` to create classes and inject services.
|
||||
La mayoría de los conjuntos de pruebas en esta guía llaman a `beforeEach()` para establecer las condiciones previas para cada prueba `it()`
|
||||
y confían en `TestBed` para crear clases e inyectar servicios.
|
||||
|
||||
There's another school of testing that never calls `beforeEach()` and prefers to create classes explicitly rather than use the `TestBed`.
|
||||
Hay otra escuela de pruebas que nunca llama a `beforeEach()` y prefiere crear clases explícitamente en lugar de usar el `TestBed`.
|
||||
|
||||
Here's how you might rewrite one of the `MasterService` tests in that style.
|
||||
Así es como podrías reescribir una de las pruebas del `MasterService` en ese estilo.
|
||||
|
||||
Begin by putting re-usable, preparatory code in a _setup_ function instead of `beforeEach()`.
|
||||
Empieza poniendo código preparatorio reutilizable en una función _setup_ en lugar de `beforeEach()`.
|
||||
|
||||
<code-example
|
||||
path="testing/src/app/demo/demo.spec.ts"
|
||||
region="no-before-each-setup"
|
||||
header="app/demo/demo.spec.ts (setup)"></code-example>
|
||||
|
||||
The `setup()` function returns an object literal
|
||||
with the variables, such as `masterService`, that a test might reference.
|
||||
You don't define _semi-global_ variables (e.g., `let masterService: MasterService`)
|
||||
in the body of the `describe()`.
|
||||
La función `setup()` devuelve un objeto literal
|
||||
con las variables, como `masterService`, a las que una prueba podría hacer referencia.
|
||||
No defines variables _semi-globales_ (por ejemplo, `let masterService: MasterService`)
|
||||
en el cuerpo de `describe()`.
|
||||
|
||||
Then each test invokes `setup()` in its first line, before continuing
|
||||
with steps that manipulate the test subject and assert expectations.
|
||||
Luego, cada prueba invoca `setup()` en su primera línea, antes de continuar
|
||||
con pasos que manipulan al sujeto de prueba y afirman expectativas.
|
||||
|
||||
<code-example
|
||||
path="testing/src/app/demo/demo.spec.ts"
|
||||
region="no-before-each-test"></code-example>
|
||||
|
||||
Notice how the test uses
|
||||
[_destructuring assignment_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)
|
||||
to extract the setup variables that it needs.
|
||||
Observe cómo la prueba usa
|
||||
[_desestructuración de asignación_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)
|
||||
para extraer las variables de configuración que necesita.
|
||||
|
||||
<code-example
|
||||
path="testing/src/app/demo/demo.spec.ts"
|
||||
region="no-before-each-setup-call">
|
||||
</code-example>
|
||||
|
||||
Many developers feel this approach is cleaner and more explicit than the
|
||||
traditional `beforeEach()` style.
|
||||
Muchos desarrolladores sienten que este enfoque es más limpio y explícito que el
|
||||
que el estilo tradicional `beforeEach()`.
|
||||
|
||||
Although this testing guide follows the traditional style and
|
||||
the default [CLI schematics](https://github.com/angular/angular-cli)
|
||||
generate test files with `beforeEach()` and `TestBed`,
|
||||
feel free to adopt _this alternative approach_ in your own projects.
|
||||
Aunque esta guía de prueba sigue el estilo tradicional y
|
||||
los [esquemas CLI](https://github.com/angular/angular-cli) predeterminados
|
||||
generan archivos de prueba con `beforeEach()` y `TestBed`,
|
||||
no dudes en adoptar _este enfoque alternativo_ en tus propios proyectos.
|
||||
|
||||
## Testing HTTP services
|
||||
## Pruebas de servicios HTTP
|
||||
|
||||
Data services that make HTTP calls to remote servers typically inject and delegate
|
||||
to the Angular [`HttpClient`](guide/http) service for XHR calls.
|
||||
Los servicios de datos que realizan llamadas HTTP a servidores remotos normalmente inyectan y delegan
|
||||
al servicio Angular [`HttpClient`](guide/http) para llamadas XHR.
|
||||
|
||||
You can test a data service with an injected `HttpClient` spy as you would
|
||||
test any service with a dependency.
|
||||
Puedes probar un servicio de datos con un espía `HttpClient` inyectado como lo harías
|
||||
con cualquier servicio con una dependencia.
|
||||
<code-example
|
||||
path="testing/src/app/model/hero.service.spec.ts"
|
||||
region="test-with-spies"
|
||||
@ -175,25 +175,24 @@ test any service with a dependency.
|
||||
|
||||
<div class="alert is-important">
|
||||
|
||||
The `HeroService` methods return `Observables`. You must
|
||||
_subscribe_ to an observable to (a) cause it to execute and (b)
|
||||
assert that the method succeeds or fails.
|
||||
Los métodos del `HeroService` devuelven `Observables`. Debes
|
||||
_subscribirte_ a un observable para (a) hacer que se ejecute y (b)
|
||||
afirmar que el método funciona o no.
|
||||
|
||||
The `subscribe()` method takes a success (`next`) and fail (`error`) callback.
|
||||
Make sure you provide _both_ callbacks so that you capture errors.
|
||||
Neglecting to do so produces an asynchronous uncaught observable error that
|
||||
the test runner will likely attribute to a completely different test.
|
||||
El método `subscribe()` toma una callback de éxito (`next`) y una de falla (`error`).
|
||||
Asegurate de proporcionar _ambas_ callback para capturar errores.
|
||||
Si no lo haces, se produce un error observable asincrónico no detectado que el
|
||||
test runner probablemente atribuirá a una prueba completamente diferente.
|
||||
|
||||
</div>
|
||||
|
||||
## _HttpClientTestingModule_
|
||||
|
||||
Extended interactions between a data service and the `HttpClient` can be complex
|
||||
and difficult to mock with spies.
|
||||
Las interacciones extendidas entre un servicio de datos y el `HttpClient` pueden ser complejas
|
||||
y difícil de crear un mock con los espías.
|
||||
|
||||
The `HttpClientTestingModule` can make these testing scenarios more manageable.
|
||||
|
||||
While the _code sample_ accompanying this guide demonstrates `HttpClientTestingModule`,
|
||||
this page defers to the [Http guide](guide/http#testing-http-requests),
|
||||
which covers testing with the `HttpClientTestingModule` in detail.
|
||||
El `HttpClientTestingModule` puede hacer que estos escenarios de prueba sean más manejables.
|
||||
|
||||
Si bien el _ejemplo de código_ que acompaña a esta guía muestra `HttpClientTestingModule`,
|
||||
esta página se remite a la [guía Http](guide/http#testing-http-requests),
|
||||
que cubre las pruebas con el `HttpClientTestingModule` en detalle.
|
||||
|
76
aio/content/guide/two-way-binding.en.md
Normal file
76
aio/content/guide/two-way-binding.en.md
Normal file
@ -0,0 +1,76 @@
|
||||
# Two-way binding `[(...)]`
|
||||
|
||||
Two-way binding gives your app a way to share data between a component class and
|
||||
its template.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
See the <live-example></live-example> for a working example containing the code snippets in this guide.
|
||||
|
||||
</div>
|
||||
|
||||
## Basics of two-way binding
|
||||
|
||||
Two-way binding does two things:
|
||||
|
||||
1. Sets a specific element property.
|
||||
1. Listens for an element change event.
|
||||
|
||||
Angular offers a special _two-way data binding_ syntax for this purpose, `[()]`.
|
||||
The `[()]` syntax combines the brackets
|
||||
of property binding, `[]`, with the parentheses of event binding, `()`.
|
||||
|
||||
<div class="callout is-important">
|
||||
|
||||
<header>
|
||||
[( )] = banana in a box
|
||||
</header>
|
||||
|
||||
Visualize a *banana in a box* to remember that the parentheses go _inside_ the brackets.
|
||||
|
||||
</div>
|
||||
|
||||
The `[()]` syntax is easy to demonstrate when the element has a settable
|
||||
property called `x` and a corresponding event named `xChange`.
|
||||
Here's a `SizerComponent` that fits this pattern.
|
||||
It has a `size` value property and a companion `sizeChange` event:
|
||||
|
||||
<code-example path="two-way-binding/src/app/sizer/sizer.component.ts" header="src/app/sizer.component.ts"></code-example>
|
||||
|
||||
<code-example path="two-way-binding/src/app/sizer/sizer.component.html" header="src/app/sizer.component.html"></code-example>
|
||||
|
||||
The initial `size` is an input value from a property binding.
|
||||
Clicking the buttons increases or decreases the `size`, within
|
||||
min/max value constraints,
|
||||
and then raises, or emits, the `sizeChange` event with the adjusted size.
|
||||
|
||||
Here's an example in which the `AppComponent.fontSizePx` is two-way bound to the `SizerComponent`:
|
||||
|
||||
<code-example path="two-way-binding/src/app/app.component.html" header="src/app/app.component.html (two-way-1)" region="two-way-1"></code-example>
|
||||
|
||||
The `AppComponent.fontSizePx` establishes the initial `SizerComponent.size` value.
|
||||
|
||||
<code-example path="two-way-binding/src/app/app.component.ts" header="src/app/app.component.ts" region="font-size"></code-example>
|
||||
|
||||
Clicking the buttons updates the `AppComponent.fontSizePx` via the two-way binding.
|
||||
The revised `AppComponent.fontSizePx` value flows through to the _style_ binding,
|
||||
making the displayed text bigger or smaller.
|
||||
|
||||
The two-way binding syntax is really just syntactic sugar for a _property_ binding and an _event_ binding.
|
||||
Angular desugars the `SizerComponent` binding into this:
|
||||
|
||||
<code-example path="two-way-binding/src/app/app.component.html" header="src/app/app.component.html (two-way-2)" region="two-way-2"></code-example>
|
||||
|
||||
The `$event` variable contains the payload of the `SizerComponent.sizeChange` event.
|
||||
Angular assigns the `$event` value to the `AppComponent.fontSizePx` when the user clicks the buttons.
|
||||
|
||||
## Two-way binding in forms
|
||||
|
||||
The two-way binding syntax is a great convenience compared to
|
||||
separate property and event bindings. It would be convenient to
|
||||
use two-way binding with HTML form elements like `<input>` and
|
||||
`<select>`. However, no native HTML element follows the `x`
|
||||
value and `xChange` event pattern.
|
||||
|
||||
For more on how to use two-way binding in forms, see
|
||||
Angular [NgModel](guide/built-in-directives#ngModel).
|
@ -1,76 +1,76 @@
|
||||
# Two-way binding `[(...)]`
|
||||
# Enlace bidireccional `[(...)]`
|
||||
|
||||
Two-way binding gives your app a way to share data between a component class and
|
||||
its template.
|
||||
El enlace bidireccional le brinda a su aplicación una forma de compartir datos entre una clase de componente y la plantilla.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
See the <live-example></live-example> for a working example containing the code snippets in this guide.
|
||||
Consulta el <live-example></live-example> para ver un ejemplo funcional que contiene los fragmentos de código de esta guía.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
## Basics of two-way binding
|
||||
## Conceptos básicos del enlace bidireccional
|
||||
|
||||
Two-way binding does two things:
|
||||
El enlace bidireccional hace dos cosas:
|
||||
|
||||
1. Sets a specific element property.
|
||||
1. Listens for an element change event.
|
||||
1. Establece una propiedad de elemento específica.
|
||||
1. Escucha un evento de cambio de elemento.
|
||||
|
||||
Angular offers a special _two-way data binding_ syntax for this purpose, `[()]`.
|
||||
The `[()]` syntax combines the brackets
|
||||
of property binding, `[]`, with the parentheses of event binding, `()`.
|
||||
Angular ofrece una sintaxis especial _enlace de datos bidireccional_ para este propósito, `[()]`.
|
||||
La sintaxis `[()]` combina los corchetes
|
||||
de enlace de propiedad, `[]`, con el paréntesis de vinculación de eventos, `()`.
|
||||
|
||||
<div class="callout is-important">
|
||||
|
||||
<header>
|
||||
[( )] = banana in a box
|
||||
[( )] = banana en una caja
|
||||
</header>
|
||||
|
||||
Visualize a *banana in a box* to remember that the parentheses go _inside_ the brackets.
|
||||
Visualiza una *banana en una caja* para recordar que los paréntesis van _dentro_ de los corchetes.
|
||||
|
||||
</div>
|
||||
|
||||
The `[()]` syntax is easy to demonstrate when the element has a settable
|
||||
property called `x` and a corresponding event named `xChange`.
|
||||
Here's a `SizerComponent` that fits this pattern.
|
||||
It has a `size` value property and a companion `sizeChange` event:
|
||||
La sintaxis `[()]` es fácil de demostrar cuando el elemento tiene un valor configurable
|
||||
propiedad llamada `x` y un evento correspondiente llamado `xChange`.
|
||||
Aquí hay un `SizerComponent` que se ajusta a este patrón.
|
||||
Tiene una propiedad de valor `size` y un evento acompañante `sizeChange`:
|
||||
|
||||
<code-example path="two-way-binding/src/app/sizer/sizer.component.ts" header="src/app/sizer.component.ts"></code-example>
|
||||
|
||||
<code-example path="two-way-binding/src/app/sizer/sizer.component.html" header="src/app/sizer.component.html"></code-example>
|
||||
|
||||
The initial `size` is an input value from a property binding.
|
||||
Clicking the buttons increases or decreases the `size`, within
|
||||
min/max value constraints,
|
||||
and then raises, or emits, the `sizeChange` event with the adjusted size.
|
||||
El `size` inicial es un valor de entrada de un enlace de propiedad.
|
||||
Al hacer clic en los botones, aumenta o disminuye el `size`, dentro de
|
||||
restricciones de valor mínimo/máximo,
|
||||
y luego genera, o emite, el evento `sizeChange` con el tamaño ajustado.
|
||||
|
||||
Here's an example in which the `AppComponent.fontSizePx` is two-way bound to the `SizerComponent`:
|
||||
Aquí hay un ejemplo en el que `AppComponent.fontSizePx` está enlazado en dos direcciones al `SizerComponent`:
|
||||
|
||||
<code-example path="two-way-binding/src/app/app.component.html" header="src/app/app.component.html (two-way-1)" region="two-way-1"></code-example>
|
||||
|
||||
The `AppComponent.fontSizePx` establishes the initial `SizerComponent.size` value.
|
||||
El `AppComponent.fontSizePx` establece el valor inicial de `SizerComponent.size`.
|
||||
|
||||
<code-example path="two-way-binding/src/app/app.component.ts" header="src/app/app.component.ts" region="font-size"></code-example>
|
||||
|
||||
Clicking the buttons updates the `AppComponent.fontSizePx` via the two-way binding.
|
||||
The revised `AppComponent.fontSizePx` value flows through to the _style_ binding,
|
||||
making the displayed text bigger or smaller.
|
||||
Al hacer clic en los botones, se actualiza `AppComponent.fontSizePx` a través del enlace bidireccional.
|
||||
El valor revisado de `AppComponent.fontSizePx` fluye a través del enlace _style_,
|
||||
haciendo que el texto mostrado sea más grande o más pequeño.
|
||||
|
||||
The two-way binding syntax is really just syntactic sugar for a _property_ binding and an _event_ binding.
|
||||
Angular desugars the `SizerComponent` binding into this:
|
||||
La sintaxis de enlace bidireccional es en realidad sólo azúcar sintáctica para un enlace _property_ y un enlace _event_.
|
||||
Angular quita el azúcar de el enlace `SizerComponent` en esto:
|
||||
|
||||
<code-example path="two-way-binding/src/app/app.component.html" header="src/app/app.component.html (two-way-2)" region="two-way-2"></code-example>
|
||||
|
||||
The `$event` variable contains the payload of the `SizerComponent.sizeChange` event.
|
||||
Angular assigns the `$event` value to the `AppComponent.fontSizePx` when the user clicks the buttons.
|
||||
La variable `$event` contiene la carga útil del evento `SizerComponent.sizeChange`.
|
||||
Angular asigna el valor `$event` al ʻAppComponent.fontSizePx` cuando el usuario hace clic en los botones.
|
||||
|
||||
## Two-way binding in forms
|
||||
## Enlace bidireccional en formularios
|
||||
|
||||
The two-way binding syntax is a great convenience compared to
|
||||
separate property and event bindings. It would be convenient to
|
||||
use two-way binding with HTML form elements like `<input>` and
|
||||
`<select>`. However, no native HTML element follows the `x`
|
||||
value and `xChange` event pattern.
|
||||
La sintaxis de enlace bidireccional es una gran comodidad en comparación con
|
||||
propiedades independientes y enlaces de eventos. Seria conveniente
|
||||
utilizar enlace bidireccional con elementos de formulario HTML como `<input>` y
|
||||
`<select>`. Sin embargo, ningún elemento HTML nativo sigue a el valor `x`
|
||||
y el patrón de evento `xChange`.
|
||||
|
||||
For more on how to use two-way binding in forms, see
|
||||
Para obtener más información sobre cómo utilizar la vinculación bidireccional en formularios, consulte
|
||||
Angular [NgModel](guide/built-in-directives#ngModel).
|
||||
|
@ -1,9 +1,9 @@
|
||||
<h1 class="title center no-toc">Angular Contributors</h1>
|
||||
<h2>Building For the Future</h2>
|
||||
<h1 class="title center no-toc">Colaboradores de Angular</h1>
|
||||
<h2>Construyendo para el futuro</h2>
|
||||
<p>
|
||||
Angular is built by a team of engineers who share a passion for making web development feel
|
||||
effortless. We believe that writing beautiful apps should be joyful and fun. We're building a
|
||||
platform for the future.
|
||||
Angular está construido por un equipo de ingenieros que comparten la pasión por hacer que el desarrollo web se sienta
|
||||
fácil. Creemos que escribir aplicaciones hermosas debe ser placentero y divertido. Estamos construyendo una
|
||||
plataforma para el futuro.
|
||||
</p>
|
||||
|
||||
<aio-contributor-list></aio-contributor-list>
|
||||
|
53
aio/content/marketing/analytics.en.md
Normal file
53
aio/content/marketing/analytics.en.md
Normal file
@ -0,0 +1,53 @@
|
||||
# Usage Metrics Gathering
|
||||
You can help the Angular Team to prioritize features and improvements by permitting the Angular
|
||||
team to send command-line command usage statistics to Google. The Angular Team does not collect
|
||||
usage statistics unless you explicitly opt in during the Angular CLI installation or upgrade.
|
||||
|
||||
## What is collected?
|
||||
Usage analytics include the commands and selected flags for each execution. Usage analytics may
|
||||
include the following information:
|
||||
|
||||
- Your operating system (Mac, Linux distribution, Windows) and its version.
|
||||
- Number of CPUs, amount of RAM.
|
||||
- Node and Angular CLI version (local version only).
|
||||
- How long each command took to initialize and execute.
|
||||
- Command name that was run.
|
||||
- For Schematics commands (add, generate, new and update), a list of selected flags.
|
||||
- For build commands (build, serve), the number and size of bundles (initial and lazy),
|
||||
compilation units, the time it took to build and rebuild, and basic Angular-specific
|
||||
API usage.
|
||||
- Error code of exceptions and crash data. No stack trace is collected.
|
||||
|
||||
Only Angular owned and developed schematics and builders are reported. Third-party schematics and
|
||||
builders do not send data to the Angular Team.
|
||||
|
||||
## Opting in
|
||||
When installing the Angular CLI or upgrading an existing version, you are prompted to allow global
|
||||
collection of usage statistics. If you say no or skip the prompt, no data is collected.
|
||||
|
||||
Starting with version 8, we added the `analytics` command to the CLI. You can change your opt-in
|
||||
decision at any time using this command.
|
||||
|
||||
### Disabling usage analytics
|
||||
To disable analytics gathering, run the following command:
|
||||
|
||||
```bash
|
||||
# Disable all usage analytics.
|
||||
ng analytics off
|
||||
```
|
||||
|
||||
### Enabling usage analytics
|
||||
To enable usage analytics, run the following command:
|
||||
|
||||
```bash
|
||||
# Enable all usage analytics.
|
||||
ng analytics on
|
||||
```
|
||||
|
||||
### Prompting
|
||||
To prompt the user again about usage analytics, run the following command:
|
||||
|
||||
```bash
|
||||
# Prompt for all usage analytics.
|
||||
ng analytics prompt
|
||||
```
|
@ -1,51 +1,48 @@
|
||||
# Usage Metrics Gathering
|
||||
You can help the Angular Team to prioritize features and improvements by permitting the Angular
|
||||
team to send command-line command usage statistics to Google. The Angular Team does not collect
|
||||
usage statistics unless you explicitly opt in during the Angular CLI installation or upgrade.
|
||||
# Recopilación de métricas de uso
|
||||
Puede ayudar al equipo de Angular a priorizar funciones y mejoras al permitir el equipo de Angular pueda enviar estadísticas de uso de comandos del cli más utilizados a Google. El equipo de Angular no recolecta
|
||||
estadísticas de uso a menos que aceptes compartir esta información durante la instalación o actualización de Angular CLI.
|
||||
|
||||
## What is collected?
|
||||
Usage analytics include the commands and selected flags for each execution. Usage analytics may
|
||||
include the following information:
|
||||
## ¿Qué se recolecta?
|
||||
El análisis de uso incluye los comandos y las banderas seleccionadas para cada ejecución. El análisis de uso puede
|
||||
incluye la siguiente información:
|
||||
|
||||
- Your operating system (Mac, Linux distribution, Windows) and its version.
|
||||
- Number of CPUs, amount of RAM.
|
||||
- Node and Angular CLI version (local version only).
|
||||
- How long each command took to initialize and execute.
|
||||
- Command name that was run.
|
||||
- For Schematics commands (add, generate, new and update), a list of whitelisted flags.
|
||||
- For build commands (build, serve), the number and size of bundles (initial and lazy),
|
||||
compilation units, the time it took to build and rebuild, and basic Angular-specific
|
||||
API usage.
|
||||
- Error code of exceptions and crash data. No stack trace is collected.
|
||||
- Su sistema operativo (Mac, distribución de Linux, Windows) y su versión.
|
||||
- Número de CPU, cantidad de RAM.
|
||||
- Versión CLI de Node y Angular (solo versión local).
|
||||
- Cuánto tiempo tardó cada comando en inicializarse y ejecutarse.
|
||||
- Nombre del comando que se ejecutó.
|
||||
- Para los comandos de Schematics (add, generate, new y update), una lista de banderas en la lista blanca.
|
||||
- Para los comandos de compilación (build, serve), la cantidad y el tamaño de los paquetes (initial y lazy),
|
||||
unidades de compilación, el tiempo que tomó compilar y reconstruir, y las unidades básicas específicas de Angular
|
||||
Uso de API.
|
||||
- Código de error de excepciones y datos de fallos. No se recopila ningún rastro de pila.
|
||||
|
||||
Only Angular owned and developed schematics and builders are reported. Third-party schematics and
|
||||
builders do not send data to the Angular Team.
|
||||
Solo se informan los schematics y builders desarrollados y de propiedad de Angular. Schematics y Builders de terceros no envían datos al equipo de Angular.
|
||||
|
||||
## Opting in
|
||||
When installing the Angular CLI or upgrading an existing version, you are prompted to allow global
|
||||
collection of usage statistics. If you say no or skip the prompt, no data is collected.
|
||||
## Participar
|
||||
Al instalar Angular CLI o actualizar una versión existente, se le solicitara que permita la recopilación de estadísticas de uso de manera global. Si dice que no u omite la indicación, no se recopilan datos.
|
||||
|
||||
Starting with version 8, we added the `analytics` command to the CLI. You can change your opt-in
|
||||
decision at any time using this command.
|
||||
Comenzando con la versión 8, agregamos el comando `analytics` a la CLI. Puede cambiar su suscripción
|
||||
decisión en cualquier momento utilizando este comando.
|
||||
|
||||
### Disabling usage analytics
|
||||
To disable analytics gathering, run the following command:
|
||||
### Desactivación de análisis de uso
|
||||
Para deshabilitar la recopilación de análisis, ejecute el siguiente comando:
|
||||
|
||||
```bash
|
||||
# Disable all usage analytics.
|
||||
ng analytics off
|
||||
```
|
||||
|
||||
### Enabling usage analytics
|
||||
To enable usage analytics, run the following command:
|
||||
### Habilitación de análisis de uso
|
||||
Para habilitar el análisis de uso, ejecute el siguiente comando:
|
||||
|
||||
```bash
|
||||
# Enable all usage analytics.
|
||||
ng analytics on
|
||||
```
|
||||
|
||||
### Prompting
|
||||
To prompt the user again about usage analytics, run the following command:
|
||||
### Volver a mostrar aviso de Analiticas
|
||||
Para volver a preguntar al usuario sobre el análisis de uso, ejecute el siguiente comando:
|
||||
|
||||
```bash
|
||||
# Prompt for all usage analytics.
|
||||
|
@ -1,54 +1,53 @@
|
||||
<header class="marketing-banner">
|
||||
<h1 class="banner-headline no-toc no-anchor">Contribute to Angular</h1>
|
||||
<h1 class="banner-headline no-toc no-anchor">Contribuir a Angular</h1>
|
||||
</header>
|
||||
|
||||
<article class="contribute-container">
|
||||
<h2 class="no-anchor">Angular Projects</h2>
|
||||
<h2 class="no-anchor">Proyectos Angular</h2>
|
||||
|
||||
<p>We'd love for you to contribute to our source code and to make Angular projects even better.</p>
|
||||
<p>Nos encantaría que contribuyas a nuestro código fuente y que hicieras los proyectos de Angular aún mejores.</p>
|
||||
|
||||
<div class="card-section">
|
||||
<div>
|
||||
<h3 class="no-anchor">Angular</h3>
|
||||
|
||||
Angular is a next generation mobile and desktop application development platform.
|
||||
|
||||
Angular es una plataforma de desarrollo de aplicaciones móviles y de escritorio de próxima generación.
|
||||
</div>
|
||||
<a href="https://github.com/angular/angular/blob/master/CONTRIBUTING.md" class="button button-blue" md-button>Contribute</a>
|
||||
<a href="https://github.com/angular/angular/blob/master/CONTRIBUTING.md" class="button button-blue" md-button>Contribuir</a>
|
||||
</div>
|
||||
|
||||
<div class="card-section">
|
||||
<div>
|
||||
<h3 class="no-anchor">Angular CLI</h3>
|
||||
|
||||
Angular CLI makes it easy to create an application that already works, right out of the box. It already follows our best practices.
|
||||
Angular CLI facilita la creación de una aplicación que funciona desde el primer momento. Ya sigue nuestras mejores prácticas.
|
||||
|
||||
</div>
|
||||
|
||||
<a href="https://github.com/angular/angular-cli/blob/master/CONTRIBUTING.md" class="button button-blue" md-button>Contribute</a>
|
||||
<a href="https://github.com/angular/angular-cli/blob/master/CONTRIBUTING.md" class="button button-blue" md-button>Contribuir</a>
|
||||
</div>
|
||||
|
||||
<div class="card-section">
|
||||
<div>
|
||||
<h3 class="no-anchor">Angular Material</h3>
|
||||
|
||||
Our goal is to deliver a lean, lightweight set of Angular-based UI elements that implement the material design specification
|
||||
for use in Angular single-page applications (SPAs).
|
||||
Nuestro objetivo es ofrecer un conjunto delgado y liviano de elementos de UI basados en Angular que implementen la especificación de diseño de material.
|
||||
para su uso en aplicaciones Angular de una sola página (SPA).
|
||||
|
||||
</div>
|
||||
|
||||
<a href="https://github.com/angular/material2/blob/master/CONTRIBUTING.md" class="button button-blue" md-button>Contribute</a>
|
||||
<a href="https://github.com/angular/material2/blob/master/CONTRIBUTING.md" class="button button-blue" md-button>Contribuir</a>
|
||||
</div>
|
||||
|
||||
<div class="card-section">
|
||||
<div>
|
||||
<h3 class="no-anchor">AngularFire</h3>
|
||||
|
||||
AngularFire is the officially supported Angular binding for Firebase. Firebase is a full backend so you don't need servers
|
||||
to build your Angular app.
|
||||
AngularFire es el enlace Angular oficialmente compatible para Firebase. Firebase es un backend completo, por lo que no necesita servidores
|
||||
para construir su aplicación Angular.
|
||||
|
||||
</div>
|
||||
<a href="https://github.com/angular/angularfire2/blob/master/CONTRIBUTING.md" class="button button-blue" md-button> Contribute</a>
|
||||
<a href="https://github.com/angular/angularfire2/blob/master/CONTRIBUTING.md" class="button button-blue" md-button> Contribuir</a>
|
||||
</div>
|
||||
|
||||
</article>
|
||||
|
@ -272,7 +272,7 @@
|
||||
"website": "https://www.softwarearchitekt.at",
|
||||
"bio": "Trainer and Consultant with focus on Angular. Writes for O'Reilly, the German Java Magazine and Heise. Regularly speaks at conferences.",
|
||||
"mentor": "mgechev",
|
||||
"groups": ["GDE", "Collaborators"]
|
||||
"groups": ["GDE", "Colaboradores"]
|
||||
},
|
||||
"maximsalnikov": {
|
||||
"name": "Maxim Salnikov",
|
||||
@ -549,7 +549,7 @@
|
||||
"twitter": "samjulien",
|
||||
"website": "http://www.samjulien.com/",
|
||||
"bio": "Sam Julien builds software, articles, video courses, and campfires. A developer, speaker, writer, and GDE in the Pacific Northwest, Sam's favorite thing in the world is changing someone's life by teaching them to code.",
|
||||
"groups": ["Collaborators", "GDE"],
|
||||
"groups": ["Colaboradores", "GDE"],
|
||||
"mentor": "gkalpak"
|
||||
},
|
||||
"tracylee": {
|
||||
@ -562,7 +562,7 @@
|
||||
},
|
||||
"jiali": {
|
||||
"name": "Jia Li",
|
||||
"groups": ["Collaborators"],
|
||||
"groups": ["Colaboradores"],
|
||||
"mentor": "mhevery",
|
||||
"picture": "JiaLiPassion.jpg",
|
||||
"twitter": "Jialipassion",
|
||||
@ -572,32 +572,32 @@
|
||||
"cexbrayat": {
|
||||
"name": "Cédric Exbrayat",
|
||||
"mentor": "petebacondarwin",
|
||||
"groups": ["Collaborators"],
|
||||
"groups": ["Colaboradores"],
|
||||
"picture": "cexbrayat.jpg",
|
||||
"bio": "Author of `Become a ninja with Angular (2+)` https://books.ninja-squad.com/angular - Angular trainer and @Ninja-Squad co-founder"
|
||||
},
|
||||
"ajitsinghkaler": {
|
||||
"name": "Ajit Singh",
|
||||
"groups": ["Collaborators"],
|
||||
"groups": ["Colaboradores"],
|
||||
"picture": "ajitsinghkaler.jpg",
|
||||
"twitter": "ajitsinghkaler",
|
||||
"bio": "Software Engineer in Bangalore, India who loves to learn something new and is interested in front end technologies"
|
||||
},
|
||||
"CaerusKaru": {
|
||||
"name": "Adam Plumer",
|
||||
"groups": ["Collaborators"],
|
||||
"groups": ["Colaboradores"],
|
||||
"mentor": "vikerman",
|
||||
"picture": "CaerusKaru.jpg"
|
||||
},
|
||||
"jbedard": {
|
||||
"name": "Jason Bedard",
|
||||
"groups": ["Collaborators"],
|
||||
"groups": ["Colaboradores"],
|
||||
"mentor": "kyliau",
|
||||
"picture": "jbedard.jpg"
|
||||
},
|
||||
"JoostK": {
|
||||
"name": "Joost Koehoorn",
|
||||
"groups": ["Collaborators"],
|
||||
"groups": ["Colaboradores"],
|
||||
"mentor": "alxhub",
|
||||
"picture": "joostk.jpg",
|
||||
"twitter": "devjoost",
|
||||
@ -605,7 +605,7 @@
|
||||
},
|
||||
"sonukapoor": {
|
||||
"name": "Sonu Kapoor",
|
||||
"groups": ["Collaborators"],
|
||||
"groups": ["Colaboradores"],
|
||||
"picture": "sonukapoor.jpg",
|
||||
"website": "https://www.linkedin.com/in/sonu-kapoor/",
|
||||
"bio": "Sonu is a Software Engineer from Toronto, with a high interest in front-end technologies and algorithms."
|
||||
@ -702,7 +702,7 @@
|
||||
},
|
||||
"ayazhafiz": {
|
||||
"name": "Ayaz Hafiz",
|
||||
"groups": ["Collaborators"],
|
||||
"groups": ["Colaboradores"],
|
||||
"picture": "hafiz.jpg",
|
||||
"website": "https://github.com/ayazhafiz",
|
||||
"bio": "Ayaz is an undergraduate student with interests in free software."
|
||||
|
58
aio/content/marketing/docs.en.md
Normal file
58
aio/content/marketing/docs.en.md
Normal file
@ -0,0 +1,58 @@
|
||||
<h1 class="no-toc">Introduction to the Angular Docs</h1>
|
||||
|
||||
Angular is an application design framework and development platform for creating efficient and sophisticated single-page apps.
|
||||
|
||||
These Angular docs help you learn and use the Angular framework and development platform, from your first application to optimizing complex single-page apps for enterprises.
|
||||
Tutorials and guides include downloadable examples to accelerate your projects.
|
||||
|
||||
|
||||
<div class="card-container">
|
||||
<a href="guide/setup-local" class="docs-card"
|
||||
title="Angular Local Environment Setup">
|
||||
<section>Get Started</section>
|
||||
<p>Set up your local environment for development with the Angular CLI.</p>
|
||||
<p class="card-footer">Local setup</p>
|
||||
</a>
|
||||
<a href="guide/architecture" class="docs-card" title="Angular Concepts">
|
||||
<section>Learn and Explore</section>
|
||||
<p>Learn about the fundamental design concepts and architecture of Angular apps.</p>
|
||||
<p class="card-footer">Introduction to Angular concepts</p>
|
||||
</a>
|
||||
<a href="start" class="docs-card" title="Try out Angular">
|
||||
<section>Take a Look</section>
|
||||
<p>Examine and work with a small ready-made Angular app, without any setup.</p>
|
||||
<p class="card-footer">Try it now</p>
|
||||
</a>
|
||||
<a href="tutorial" class="docs-card" title="Create an app">
|
||||
<section>Hello World</section>
|
||||
<p>Work through a full tutorial to create your first app.</p>
|
||||
<p class="card-footer">Tour of Heroes tutorial</p>
|
||||
</a>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
## Assumptions
|
||||
|
||||
|
||||
These docs assume that you are already familiar with [HTML](https://developer.mozilla.org/docs/Learn/HTML/Introduction_to_HTML "Learn HTML"), [CSS](https://developer.mozilla.org/docs/Learn/CSS/First_steps "Learn CSS"), [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript "Learn JavaScript"),
|
||||
and some of the tools from the [latest standards](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Language_Resources "Latest JavaScript standards"), such as [classes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes "ES2015 Classes") and [modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import "ES2015 Modules").
|
||||
The code samples are written using [TypeScript](https://www.typescriptlang.org/ "TypeScript").
|
||||
Most Angular code can be written with just the latest JavaScript, using [types](https://www.typescriptlang.org/docs/handbook/classes.html "TypeScript Types") for dependency injection, and using [decorators](https://www.typescriptlang.org/docs/handbook/decorators.html "Decorators") for metadata.
|
||||
|
||||
|
||||
## Feedback
|
||||
|
||||
<h3>You can sit with us!</h3>
|
||||
|
||||
We want to hear from you. [Report problems or submit suggestions for future docs.](https://github.com/angular/angular/issues/new/choose "Angular GitHub repository new issue form")
|
||||
|
||||
Contribute to Angular docs by creating
|
||||
[pull requests](https://github.com/angular/angular/pulls "Angular Github pull requests")
|
||||
on the Angular Github repository.
|
||||
See [Contributing to Angular](https://github.com/angular/angular/blob/master/CONTRIBUTING.md "Contributing guide")
|
||||
for information about submission guidelines.
|
||||
|
||||
Our community values respectful, supportive communication.
|
||||
Please consult and adhere to the [Code of Conduct](https://github.com/angular/code-of-conduct/blob/master/CODE_OF_CONDUCT.md "Contributor code of conduct").
|
@ -1,58 +1,71 @@
|
||||
<h1 class="no-toc">Introduction to the Angular Docs</h1>
|
||||
<h1 class="no-toc">Introducción a la Documentación de Angular</h1>
|
||||
|
||||
Angular is an application design framework and development platform for creating efficient and sophisticated single-page apps.
|
||||
Angular es un framework de diseño de aplicaciones y plataforma de desarrollo para crear aplicaciones de una
|
||||
sola página eficientes y sofisticadas
|
||||
|
||||
These Angular docs help you learn and use the Angular framework and development platform, from your first application to optimizing complex single-page apps for enterprises.
|
||||
Tutorials and guides include downloadable examples to accelerate your projects.
|
||||
Esta documentación de Angular te ayuda a aprender y usar el framework y la plataforma de desarrollo, desde tu
|
||||
primera aplicación hasta la optimización de aplicaciones complejas de una sola página, para empresas.
|
||||
Los tutoriales y guías incluyen ejemplos descargables para acelerar tus proyectos.
|
||||
|
||||
|
||||
<div class="card-container">
|
||||
<a href="guide/setup-local" class="docs-card"
|
||||
title="Angular Local Environment Setup">
|
||||
<section>Get Started</section>
|
||||
<p>Set up your local environment for development with the Angular CLI.</p>
|
||||
<p class="card-footer">Local setup</p>
|
||||
<section>Comienza</section>
|
||||
<p>Configura tu entorno local para el desarrollo, con Angular CLI.</p>
|
||||
<p class="card-footer">Configuración local</p>
|
||||
</a>
|
||||
<a href="guide/architecture" class="docs-card" title="Angular Concepts">
|
||||
<section>Learn and Explore</section>
|
||||
<p>Learn about the fundamental design concepts and architecture of Angular apps.</p>
|
||||
<p class="card-footer">Introduction to Angular concepts</p>
|
||||
<section>Aprende y Explora</section>
|
||||
<p>Aprende sobre arquitectura y conceptos de diseño fundamentales de aplicaciones Angular.</p>
|
||||
<p class="card-footer">Introducción a conceptos de Angular</p>
|
||||
</a>
|
||||
<a href="start" class="docs-card" title="Try out Angular">
|
||||
<section>Take a Look</section>
|
||||
<p>Examine and work with a small ready-made Angular app, without any setup.</p>
|
||||
<p class="card-footer">Try it now</p>
|
||||
<section>Echa un vistazo</section>
|
||||
<p>Examina y trabaja con una pequeña aplicación Angular lista para usar, sin configuraciónes.</p>
|
||||
<p class="card-footer">Pruébalo ahora</p>
|
||||
</a>
|
||||
<a href="tutorial" class="docs-card" title="Create an app">
|
||||
<section>Hello World</section>
|
||||
<p>Work through a full tutorial to create your first app.</p>
|
||||
<p class="card-footer">Tour of Heroes tutorial</p>
|
||||
<section>Hola Mundo</section>
|
||||
<p>Trabaja mediante un tutorial completo para crear tu primera aplicación.</p>
|
||||
<p class="card-footer">Tutorial Tour de Héroes</p>
|
||||
</a>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
## Assumptions
|
||||
## Supuestos
|
||||
|
||||
|
||||
These docs assume that you are already familiar with [HTML](https://developer.mozilla.org/docs/Learn/HTML/Introduction_to_HTML "Learn HTML"), [CSS](https://developer.mozilla.org/docs/Learn/CSS/First_steps "Learn CSS"), [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript "Learn JavaScript"),
|
||||
and some of the tools from the [latest standards](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Language_Resources "Latest JavaScript standards"), such as [classes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes "ES2015 Classes") and [modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import "ES2015 Modules").
|
||||
The code samples are written using [TypeScript](https://www.typescriptlang.org/ "TypeScript").
|
||||
Most Angular code can be written with just the latest JavaScript, using [types](https://www.typescriptlang.org/docs/handbook/classes.html "TypeScript Types") for dependency injection, and using [decorators](https://www.typescriptlang.org/docs/handbook/decorators.html "Decorators") for metadata.
|
||||
Esta documentación asume que estás familiarizado con
|
||||
[HTML](https://developer.mozilla.org/es/docs/Learn/HTML/Introduccion_a_HTML "Aprende HTML"),
|
||||
[CSS](https://developer.mozilla.org/es/docs/Learn/CSS/First_steps "Aprende CSS"),
|
||||
[JavaScript](https://developer.mozilla.org/es/docs/Web/JavaScript/Una_re-introducci%C3%B3n_a_JavaScript "Aprende JavaScript"),
|
||||
y algunas herramientas de los
|
||||
[últimos estándares javascript](https://developer.mozilla.org/es/docs/Web/JavaScript/Language_Resources "Últimos estándares JavaScript"),
|
||||
como son las [clases](https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Classes "Clases ES2015")
|
||||
y [módulos](https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Sentencias/import "Modulos ES2015").
|
||||
Los ejemplos de código son escritos usando [TypeScript](https://www.typescriptlang.org/ "TypeScript").
|
||||
La mayor parte del código Angular se puede escribir tan solo con la versión más reciente de JavaScript, usando
|
||||
[tipos](https://www.typescriptlang.org/docs/handbook/classes.html "Tipos TypeScript") para inyección de
|
||||
dependencia, y usando [decoradores](https://www.typescriptlang.org/docs/handbook/decorators.html "Decoradores")
|
||||
para metadatos.
|
||||
|
||||
|
||||
## Feedback
|
||||
## Retrolimentación
|
||||
|
||||
<h3>You can sit with us!</h3>
|
||||
<h3>¡Puedes sentarte con nosotros!</h3>
|
||||
|
||||
We want to hear from you. [Report problems or submit suggestions for future docs.](https://github.com/angular/angular/issues/new/choose "Angular GitHub repository new issue form")
|
||||
Queremos saber de ti.
|
||||
[Informa problemas o envía sugerencias para nueva documentación.](https://github.com/angular-hispano/angular/issues/new/choose "Repositorio GitHub de Angular, form para nuevo issue")
|
||||
|
||||
Contribute to Angular docs by creating
|
||||
[pull requests](https://github.com/angular/angular/pulls "Angular Github pull requests")
|
||||
on the Angular Github repository.
|
||||
See [Contributing to Angular](https://github.com/angular/angular/blob/master/CONTRIBUTING.md "Contributing guide")
|
||||
for information about submission guidelines.
|
||||
Colabora con la documentación de Angular creando
|
||||
[pull requests](https://github.com/angular-hispano/angular/pulls "Angular Github pull requests")
|
||||
en el repositorio Github de Angular en español.
|
||||
Mira [Colaborando a Angular](https://github.com/angular-hispano/angular/blob/master/CONTRIBUTING.md "Guía de Colaboración")
|
||||
para obtener información sobre las pautas de envío de nuevas colaboraciones.
|
||||
|
||||
Our community values respectful, supportive communication.
|
||||
Please consult and adhere to the [Code of Conduct](https://github.com/angular/code-of-conduct/blob/master/CODE_OF_CONDUCT.md "Contributor code of conduct").
|
||||
Nuestra comunidad valora la comunicación respetuosa y solidaria.
|
||||
Consulta y adhiérete al
|
||||
[Código de Conducta](https://angular.lat/coc "Código de Conducta del comunidad").
|
||||
|
@ -3,26 +3,26 @@
|
||||
</header>
|
||||
|
||||
<article class="events-container">
|
||||
<p>Where we'll be presenting:</p>
|
||||
<p>Dónde estaremos presentando:</p>
|
||||
<table class="is-full-width">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Event</th>
|
||||
<th>Location</th>
|
||||
<th>Date</th>
|
||||
<th>Evento</th>
|
||||
<th>Ubicación</th>
|
||||
<th>Fecha</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p>Where we already presented:</p>
|
||||
<p>Eventos Pasados:</p>
|
||||
<table class="is-full-width">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Event</th>
|
||||
<th>Location</th>
|
||||
<th>Date</th>
|
||||
<th>Eventos</th>
|
||||
<th>Ubicación</th>
|
||||
<th>Fecha</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<header class="marketing-banner">
|
||||
<h1 class="banner-headline no-toc no-anchor">Features & Benefits</h1>
|
||||
<h1 class="banner-headline no-toc no-anchor">Funcionalidades & Ventajas</h1>
|
||||
</header>
|
||||
|
||||
<article>
|
||||
@ -7,25 +7,28 @@
|
||||
<div>
|
||||
<div class="feature-section">
|
||||
<div class="feature-header">
|
||||
<div class="text-headline">Cross Platform</div>
|
||||
<div class="text-headline">Multiplataforma</div>
|
||||
<img src="generated/images/marketing/features/feature-icon.svg" height="70px" alt="">
|
||||
</div>
|
||||
<div class="feature-row">
|
||||
|
||||
<div class="feature">
|
||||
<div class="feature-title">Progressive Web Apps</div>
|
||||
<p class="text-body">Use modern web platform capabilities to deliver app-like experiences.
|
||||
High performance, offline, and zero-step installation.</p>
|
||||
<div class="feature-title">Aplicaciones Web Progresivas "PWA"</div>
|
||||
<p class="text-body">Utiliza las capacidades modernas de la plataforma web para ofrecer experiencias
|
||||
similares a las de las aplicaciones.
|
||||
Instalación de alto rendimiento, sin conexión y en cero pasos.</p>
|
||||
</div>
|
||||
|
||||
<div class="feature">
|
||||
<div class="feature-title">Native</div>
|
||||
<p class="text-body">Build native mobile apps with strategies from Cordova, Ionic, or NativeScript.</p>
|
||||
<div class="feature-title">Nativo</div>
|
||||
<p class="text-body">Crea aplicaciones móviles nativas con estrategias de Cordova, Ionic o NativeScript.</p>
|
||||
</div>
|
||||
|
||||
<div class="feature">
|
||||
<div class="feature-title">Desktop</div>
|
||||
<p class="text-body">Create desktop-installed apps across Mac, Windows, and Linux using the same Angular methods you've learned for the web plus the ability to access native OS APIs.</p>
|
||||
<div class="feature-title">Escritorio</div>
|
||||
<p class="text-body">Crea aplicaciones instaladas en el escritorio en Mac, Windows y Linux con los mismos
|
||||
métodos Angular que ha aprendido para la web, además de la capacidad de acceder a las API nativas del
|
||||
sistema operativo.</p>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
@ -33,24 +36,30 @@
|
||||
|
||||
<div class="feature-section">
|
||||
<div class="feature-header">
|
||||
<div class="text-headline">Speed and Performance</div>
|
||||
<div class="text-headline">Velocidad y Rendimiento</div>
|
||||
<img src="generated/images/marketing/features/feature-icon.svg" height="70px" alt="">
|
||||
</div>
|
||||
<div class="feature-row">
|
||||
|
||||
<div class="feature">
|
||||
<div class="feature-title">Code Generation</div>
|
||||
<p class="text-body">Angular turns your templates into code that's highly optimized for today's JavaScript virtual machines, giving you all the benefits of hand-written code with the productivity of a framework.</p>
|
||||
<div class="feature-title">Generación de código</div>
|
||||
<p class="text-body">Angular convierte sus plantillas en código altamente optimizado para las máquinas
|
||||
virtuales JavaScript de hoy en día, lo que le ofrece todas las ventajas del código escrito a mano con la
|
||||
productividad de un framework.</p>
|
||||
</div>
|
||||
|
||||
<div class="feature">
|
||||
<div class="feature-title">Universal</div>
|
||||
<p class="text-body">Serve the first view of your application on Node.js®, .NET, PHP, and other servers for near-instant rendering in just HTML and CSS. Also paves the way for sites that optimize for SEO.</p>
|
||||
<p class="text-body">Sirve la primera vista de tu aplicación en Node.js®, .NET, PHP y otros servidores para
|
||||
una representación casi instantánea en HTML y CSS. También allana el camino para sitios que optimizan para
|
||||
SEO.</p>
|
||||
</div>
|
||||
|
||||
<div class="feature">
|
||||
<div class="feature-title">Code Splitting</div>
|
||||
<p class="text-body">Angular apps load quickly with the new Component Router, which delivers automatic code-splitting so users only load code required to render the view they request.</p>
|
||||
<div class="feature-title">División de código</div>
|
||||
<p class="text-body">Las aplicaciones de Angular se cargan rápidamente con el nuevo enrutador de
|
||||
componentes, que ofrece división automática de código para que los usuarios solo carguen el código
|
||||
necesario para representar la vista que solicitan.</p>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
@ -58,24 +67,27 @@
|
||||
|
||||
<div class="feature-section">
|
||||
<div class="feature-header">
|
||||
<div class="text-headline">Productivity</div>
|
||||
<div class="text-headline">Productividad</div>
|
||||
<img src="generated/images/marketing/features/feature-icon.svg" height="70px" alt="">
|
||||
</div>
|
||||
<div class="feature-row">
|
||||
|
||||
<div class="feature">
|
||||
<div class="feature-title">Templates</div>
|
||||
<p class="text-body">Quickly create UI views with simple and powerful template syntax.</p>
|
||||
<div class="feature-title">Plantillas</div>
|
||||
<p class="text-body">Crea rápidamente vistas de interfaz de usuario con una sintaxis de plantilla sencilla y
|
||||
potente.</p>
|
||||
</div>
|
||||
|
||||
<div class="feature">
|
||||
<div class="feature-title">Angular CLI</div>
|
||||
<p class="text-body">Command line tools: start building fast, add components and tests, then instantly deploy.</p>
|
||||
<p class="text-body">Herramienta de linea de comando: empieza a construir rápidamente, agregar componentes
|
||||
y pruebas, luego implementar instantáneamente.</p>
|
||||
</div>
|
||||
|
||||
<div class="feature">
|
||||
<div class="feature-title">IDEs</div>
|
||||
<p class="text-body">Get intelligent code completion, instant errors, and other feedback in popular editors and IDEs.</p>
|
||||
<p class="text-body">Obtén la finalización inteligente del código, errores instantáneos y otros comentarios
|
||||
en editores e IDE populares.</p>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
@ -83,24 +95,28 @@
|
||||
|
||||
<div class="feature-section">
|
||||
<div class="feature-header">
|
||||
<div class="text-headline">Full Development Story</div>
|
||||
<div class="text-headline">Historia De Desarrollo Completo</div>
|
||||
<img src="generated/images/marketing/features/feature-icon.svg" height="70px" alt="">
|
||||
</div>
|
||||
<div class="feature-row">
|
||||
|
||||
<div class="feature">
|
||||
<div class="feature-title">Testing</div>
|
||||
<p class="text-body">With Karma for unit tests, you can know if you've broken things every time you save. And Protractor makes your scenario tests run faster and in a stable manner.</p>
|
||||
<div class="feature-title">Pruebas</div>
|
||||
<p class="text-body">Con Karma para pruebas unitarias, puedes saber si has roto las cosas cada vez que
|
||||
ahorras. Y Protractor hace que sus pruebas de escenario se ejecuten más rápido y de una manera estable.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="feature">
|
||||
<div class="feature-title">Animation</div>
|
||||
<p class="text-body">Create high-performance, complex choreographies and animation timelines with very little code through Angular's intuitive API.</p>
|
||||
<p class="text-body">Crea coreografías complejas y de alto rendimiento y líneas de tiempo de animación con
|
||||
muy poco código a través de la API intuitiva de Angular.</p>
|
||||
</div>
|
||||
|
||||
<div class="feature">
|
||||
<div class="feature-title">Accessibility</div>
|
||||
<p class="text-body">Create accessible applications with ARIA-enabled components, developer guides, and built-in a11y test infrastructure.</p>
|
||||
<div class="feature-title">Accesibilidad</div>
|
||||
<p class="text-body">Crea aplicaciones accesibles con componentes habilitados para ARIA, guías para
|
||||
desarrolladores e infraestructura de prueba a11y integrada.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -108,7 +124,7 @@
|
||||
</div>
|
||||
|
||||
<div class="cta-bar announcement-bar">
|
||||
<a class="button" href="start">Get Started</a>
|
||||
<a class="button" href="start">Introducción</a>
|
||||
</div>
|
||||
|
||||
</article>
|
||||
|
@ -14,8 +14,8 @@
|
||||
|
||||
<!-- CONTAINER -->
|
||||
<div class="homepage-container">
|
||||
<div class="hero-headline no-toc">One framework.<br>Mobile & desktop.</div>
|
||||
<a class="button hero-cta" href="docs">Get Started</a>
|
||||
<div class="hero-headline no-toc">Un framework.<br>Móvil y escritorio.</div>
|
||||
<a class="button hero-cta" href="docs">Empezar</a>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
@ -41,8 +41,8 @@
|
||||
|
||||
<div class="text-container">
|
||||
<div class="text-block promo-1-desc l-pad-top-2">
|
||||
<div class="text-headline">Develop Across All Platforms</div>
|
||||
<p class="text-body">Learn one way to build applications with Angular and reuse your code and abilities to build apps for any deployment target. For web, mobile web, native mobile and native desktop.
|
||||
<div class="text-headline">Desarrolla en todas las plataformas</div>
|
||||
<p class="text-body">Aprende una forma de crear aplicaciones con Angular y reutiliza tu código y habilidades para crear aplicaciones para cualquier objetivo de implementación. Para web, web móvil, móvil nativo y escritorio nativo.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -53,9 +53,9 @@
|
||||
<div layout="row" layout-xs="column" class="home-row">
|
||||
<div class="text-container">
|
||||
<div class="text-block">
|
||||
<div class="text-headline">Speed & Performance</div>
|
||||
<p class="text-body">Achieve the maximum speed possible on the Web Platform today, and take it further, via Web Workers and server-side rendering.</p>
|
||||
<p class="text-body">Angular puts you in control over scalability. Meet huge data requirements by building data models on RxJS, Immutable.js or another push-model.</p>
|
||||
<div class="text-headline">Velocidad y Rendimiento</div>
|
||||
<p class="text-body">Logra la máxima velocidad posible en la Plataforma Web hoy y avance, a través de Web Workers y renderizado del lado del servidor.</p>
|
||||
<p class="text-body">Angular te permite controlar la escalabilidad. Satisface requerimientos enormes de datos construyendo modelos en RxJS, Immutable.js o algún otro.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -75,8 +75,8 @@
|
||||
|
||||
<div class="text-container">
|
||||
<div class="text-block promo-3-desc">
|
||||
<div class="text-headline">Incredible Tooling</div>
|
||||
<p class="text-body">Build features quickly with simple, declarative templates. Extend the template language with your own components and use a wide array of existing components. Get immediate Angular-specific help and feedback with nearly every IDE and editor. All this comes together so you can focus on building amazing apps rather than trying to make the code work.
|
||||
<div class="text-headline">Herramientas Increíbles</div>
|
||||
<p class="text-body">Crea funciones rápidamente con plantillas simples y declarativas. Extiende el lenguaje de plantilla con tus propios componentes y usa una amplia gama de componentes existentes. Obtén ayuda inmediata y comentarios específicos de Angular con casi todos los IDE y editores. Todo esto se une para que puedas concentrarte en crear aplicaciones increíbles en lugar de intentar que el código funcione.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -88,8 +88,9 @@
|
||||
<div layout="row" layout-xs="column" class="home-row">
|
||||
<div class="text-container">
|
||||
<div class="text-block l-pad-top-2">
|
||||
<div class="text-headline">Loved by Millions</div>
|
||||
<p class="text-body">From prototype through global deployment, Angular delivers the productivity and scalable infrastructure that supports Google's largest applications.</p>
|
||||
<div class="text-headline">Amada por millones</div>
|
||||
<p class="text-body">Desde el prototipo hasta la implementación global, Angular ofrece la productividad y la infraestructura escalable que soportan a las aplicaciones más grandes de Google.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -106,8 +107,9 @@
|
||||
<div class="card">
|
||||
<img src="generated/images/marketing/home/code-icon.svg" height="70px" alt="Get Started with Angular">
|
||||
<div class="card-text-container">
|
||||
<div class="text-headline">Try it now</div>
|
||||
<p>Explore Angular's capabilities with a ready-made sample app. No setup required.</p>
|
||||
<div class="text-headline">Pruebalo ahora</div>
|
||||
<p>Explora las capacidades de Angular con una aplicación de muestra preparada. No se requiere configuración.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
@ -1,13 +1,13 @@
|
||||
# Contributing to resources.json
|
||||
# Contribuir a resources.json
|
||||
|
||||
## About this list
|
||||
We maintain a small list of some of the top Angular resources from across the community, stored in `resources.json`. This list is not intended to be comprehensive, but to act as a starting point to connect Angular developers to the rest of the community.
|
||||
## Acerca de esta lista
|
||||
Mantenemos una pequeña lista de algunos de los principales recursos de Angular de toda la comunidad, almacenados en `resources.json`. Esta lista no pretende ser completa, sino actuar como un punto de partida para conectar a los desarrolladores de Angular con el resto de la comunidad.
|
||||
|
||||
## How do I get listed?
|
||||
While we can't accept all contributions, qualifying contributions can be submitted via a PR adding yourself to the `resources.json` file. All contributions should be in the appropriate section and must meet the following criteria:
|
||||
## ¿Cómo me incluyo?
|
||||
Si bien no podemos aceptar todas las contribuciones, las contribuciones que califiquen se pueden enviar a través de un PR que se agregue al archivo `resources.json`. Todas las contribuciones deben estar en la sección correspondiente y deben cumplir con los siguientes criterios:
|
||||
|
||||
1. Your contribution must be valid, and contain a link to a page talking specifically about using Angular
|
||||
1. Your contribution should have a clear and concise title and description
|
||||
1. Your resource should follow our brand guidelines (see our [Presskit](presskit))
|
||||
1. Your resource should have significant benefit to Angular developers
|
||||
1. Your resource should already have traction and praise from Angular developers
|
||||
1. Su contribución debe ser válida y contener un enlace a una página que hable específicamente sobre el uso de Angular
|
||||
1. Tu contribución debe tener un título y una descripción claros y concisos.
|
||||
1. Su recurso debe seguir nuestras pautas de marca (consulte nuestro [Presskit](presskit))
|
||||
1. Su recurso debería tener un beneficio significativo para los desarrolladores de Angular
|
||||
1. Su recurso ya debería tener tracción y elogios de los desarrolladores de Angular
|
@ -1,5 +1,5 @@
|
||||
<header class="marketing-banner">
|
||||
<h1 class="banner-headline no-toc no-anchor">Explore Angular Resources</h1>
|
||||
<h1 class="banner-headline no-toc no-anchor">Explore Recursos de Angular</h1>
|
||||
</header>
|
||||
|
||||
<article>
|
||||
|
@ -1,8 +1,8 @@
|
||||
<h1>Test Code Page</h1>
|
||||
<h1>Página de códigos de prueba </h1>
|
||||
|
||||
<h2><code-tabs></h2>
|
||||
<h2><Pestañas de código></h2>
|
||||
|
||||
<p>No linenums at code-tabs level</p>
|
||||
<p> No hay listas de linenums a nivel de etiquetas de código </p>
|
||||
<code-tabs>
|
||||
<code-pane header='TS code file' language='ts'>
|
||||
class {
|
||||
@ -26,7 +26,7 @@
|
||||
</code-tabs>
|
||||
<p></p>
|
||||
|
||||
<p>No linenums at code-tabs level; linenums=true for second HTML pane</p>
|
||||
<p>Sin linenums a nivel de etiquetas de código; linenums = verdadero para el segundo panel HTML</p>
|
||||
<code-tabs >
|
||||
<code-pane header='TS code file' language='ts'>
|
||||
class {
|
||||
@ -40,10 +40,10 @@
|
||||
|
||||
<h2><code-example></h2>
|
||||
|
||||
<p>One line.</p>
|
||||
<p>Una línea.</p>
|
||||
<code-example>const foo = 'bar'</code-example>
|
||||
|
||||
<p>Multi-line, linenums=true.</p>
|
||||
<p>Multi-línea, linenums=true.</p>
|
||||
<code-example linenums='true'>
|
||||
<hero-details <em>nghost-pmm-5>
|
||||
<h2 </em>ngcontent-pmm-5>Bah Dah Bing</h2>
|
||||
@ -53,7 +53,7 @@
|
||||
</hero-details>
|
||||
</code-example>
|
||||
|
||||
<p>Default linenums (false).</p>
|
||||
<p>linenums por defecto (false).</p>
|
||||
<code-example>
|
||||
<hero-details <em>nghost-pmm-5>
|
||||
<h2 </em>ngcontent-pmm-5>Mister Fantastic</h2>
|
||||
@ -63,7 +63,7 @@
|
||||
</hero-details>
|
||||
</code-example>
|
||||
|
||||
<p>Header on this one.</p>
|
||||
<p>Encabezado en este.</p>
|
||||
<code-example header="hero-details.component.ts (excerpt)">
|
||||
<hero-details <em>nghost-pmm-5>
|
||||
<h2 </em>ngcontent-pmm-5>Mister Fantastic</h2>
|
||||
@ -73,55 +73,55 @@
|
||||
</hero-details>
|
||||
</code-example>
|
||||
|
||||
<p>An "avoid" header on this one.</p>
|
||||
<p>Un encabezado "evitar" en este.</p>
|
||||
<code-example class="avoid" header="hero-details.component.ts (Avoid)">
|
||||
<hero-details <em>nghost-pmm-5>
|
||||
<h2 </em>ngcontent-pmm-5>Mister Fantastic</h2>
|
||||
<h2 </em>ngcontent-pmm-5>Señor fantástico</h2>
|
||||
<hero-team <em>ngcontent-pmm-5 </em>nghost-pmm-6>
|
||||
<h3 _ngcontent-pmm-6>Losing Team</h3>
|
||||
<h3 _ngcontent-pmm-6>Equipo Perdedor</h3>
|
||||
</hero-team>
|
||||
</hero-details>
|
||||
</code-example>
|
||||
|
||||
## Backticked code blocks
|
||||
## Bloques de código con tilde atrás
|
||||
|
||||
```html
|
||||
<hero-details>
|
||||
<h2>Mister Fantastic</h2>
|
||||
<h2>Señor fantástico</h2>
|
||||
<hero-team>
|
||||
<h3>Losing Team</h3>
|
||||
<h3>Equipo perdedor</h3>
|
||||
</hero-team>
|
||||
</hero-details>
|
||||
```
|
||||
|
||||
<h2><live-example></h2>
|
||||
<h2><ejemplo en vivo></h2>
|
||||
|
||||
<p>Plain live-example</p>
|
||||
Try this <live-example></live-example>.
|
||||
<p>Ejemplo simple en vivo</p>
|
||||
Prueba esto <live-example></live-example>.
|
||||
|
||||
<p>live-example with title atty</p>
|
||||
<p>ejemplo en vivo con título atty</p>
|
||||
<live-example title="Good Example"></live-example>
|
||||
|
||||
<p>live-example with title body</p>
|
||||
<live-example title="Good Example">Try this great example</live-example>
|
||||
<p>ejemplo en vivo con el cuerpo del título</p>
|
||||
<live-example title="Good Example">Prueba este gran ejemplo</live-example>
|
||||
|
||||
<p>live-example with name</p>
|
||||
<p>ejemplo en vivo con nombre</p>
|
||||
<live-example name="testy" title="Better Example"></live-example>
|
||||
|
||||
<p>live-example with spacey name and stackblitz</p>
|
||||
<p>ejemplo en vivo con nombre espacial y stackblitz</p>
|
||||
<live-example name=" testy " stackblitz="super-stackblitz"></live-example>
|
||||
|
||||
<p>live-example with name and stackblitz but no download</p>
|
||||
<p>ejemplo en vivo con nombre y stackblitz pero sin descarga</p>
|
||||
<live-example name="testy" stackblitz="super-stackblitz" noDownload></live-example>
|
||||
|
||||
<p>live-example embedded with name and stackblitz</p>
|
||||
<p>ejemplo en vivo incrustado con nombre y stackblitz</p>
|
||||
<live-example embedded name="testy" stackblitz="super-stackblitz"></live-example>
|
||||
|
||||
<p>More text follows ...</p>
|
||||
<p>Sigue más texto ...</p>
|
||||
|
||||
<p>Getting Started Widgets</p>
|
||||
<p>Widgets de introducción</p>
|
||||
|
||||
<p>Interpolation</p>
|
||||
<p>Interpolación</p>
|
||||
<aio-gs-interpolation></aio-gs-interpolation>
|
||||
|
||||
<p>Property Binding</p>
|
||||
@ -134,4 +134,4 @@ Try this <live-example></live-example>.
|
||||
<aio-gs-ng-if></aio-gs-ng-if>
|
||||
|
||||
<p>NgFor</p>
|
||||
<aio-gs-ng-for></aio-gs-ng-for>
|
||||
<aio-gs-ng-for></aio-gs-ng-for>
|
1099
aio/content/navigation.en.json
Normal file
1099
aio/content/navigation.en.json
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -12,7 +12,7 @@ This page guides you through creating the shopping cart in three phases:
|
||||
{@a services}
|
||||
## Services
|
||||
|
||||
Services are an integral part of Angular applications. In Angular, a service is an instance of a class that you can make available to any part of your application using Angular's [dependency injection system](guide/glossary#dependency-injection-di "Dependency injection definition").
|
||||
Services are an integral part of Angular applications. In Angular, a service is an instance of a class that you can make available to any part of your application using Angular's [dependency injection system](guide/glossary#dependency-injection "Dependency injection definition").
|
||||
|
||||
Services are the place where you share data between parts of your application. For the online store, the cart service is where you store your cart data and methods.
|
||||
|
||||
|
88
aio/content/tutorial/index.en.md
Normal file
88
aio/content/tutorial/index.en.md
Normal file
@ -0,0 +1,88 @@
|
||||
<h1 class="no-toc">Tour of Heroes app and tutorial</h1>
|
||||
|
||||
<div class="callout is-helpful">
|
||||
<header>Getting Started</header>
|
||||
|
||||
In this tutorial, you build your own app from the ground up, providing experience with the typical development process, as well as an introduction to basic app-design concepts, tools, and terminology.
|
||||
|
||||
If you're completely new to Angular, you might want to try the [**Try it now**](start) quick-start app first.
|
||||
It is based on a ready-made partially-completed project, which you can examine and modify in the StackBlitz interactive development environment, where you can see the results in real time.
|
||||
|
||||
The "Try it" tutorial covers the same major topics—components, template syntax, routing, services, and accessing data via HTTP—in a condensed format, following the most current best practices.
|
||||
|
||||
</div>
|
||||
|
||||
This _Tour of Heroes_ tutorial shows you how to set up your local development environment and develop an app using the [Angular CLI tool](cli "CLI command reference"), and provides an introduction to the fundamentals of Angular.
|
||||
|
||||
The _Tour of Heroes_ app that you build helps a staffing agency manage its stable of heroes.
|
||||
The app has many of the features you'd expect to find in any data-driven application.
|
||||
The finished app acquires and displays a list of heroes, edits a selected hero's detail, and navigates among different views of heroic data.
|
||||
|
||||
You will find references to and expansions of this app domain in many of the examples used throughout the Angular documentation, but you don't necessarily need to work through this tutorial to understand those examples.
|
||||
|
||||
By the end of this tutorial you will be able to do the following:
|
||||
|
||||
* Use built-in Angular [directives](guide/glossary#directive "Directives definition") to show and hide elements and display lists of hero data.
|
||||
* Create Angular [components](guide/glossary#component "Components definition") to display hero details and show an array of heroes.
|
||||
* Use one-way [data binding](guide/glossary#data-binding "Data binding definition") for read-only data.
|
||||
* Add editable fields to update a model with two-way data binding.
|
||||
* Bind component methods to user events, like keystrokes and clicks.
|
||||
* Enable users to select a hero from a master list and edit that hero in the details view.
|
||||
* Format data with [pipes](guide/glossary#pipe "Pipe definition").
|
||||
* Create a shared [service](guide/glossary#service "Service definition") to assemble the heroes.
|
||||
* Use [routing](guide/glossary#router "Router definition") to navigate among different views and their components.
|
||||
|
||||
You'll learn enough Angular to get started and gain confidence that
|
||||
Angular can do whatever you need it to do.
|
||||
|
||||
<div class="callout is-helpful">
|
||||
<header>Solution</header>
|
||||
|
||||
After completing all tutorial steps, the final app will look like this: <live-example name="toh-pt6"></live-example>.
|
||||
|
||||
</div>
|
||||
|
||||
## What you'll build
|
||||
|
||||
Here's a visual idea of where this tutorial leads, beginning with the "Dashboard"
|
||||
view and the most heroic heroes:
|
||||
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/toh/heroes-dashboard-1.png' alt="Output of heroes dashboard">
|
||||
</div>
|
||||
|
||||
You can click the two links above the dashboard ("Dashboard" and "Heroes")
|
||||
to navigate between this Dashboard view and a Heroes view.
|
||||
|
||||
If you click the dashboard hero "Magneta," the router opens a "Hero Details" view
|
||||
where you can change the hero's name.
|
||||
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/toh/hero-details-1.png' alt="Details of hero in app">
|
||||
</div>
|
||||
|
||||
Clicking the "Back" button returns you to the Dashboard.
|
||||
Links at the top take you to either of the main views.
|
||||
If you click "Heroes," the app displays the "Heroes" master list view.
|
||||
|
||||
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/toh/heroes-list-2.png' alt="Output of heroes list app">
|
||||
</div>
|
||||
|
||||
When you click a different hero name, the read-only mini detail beneath the list reflects the new choice.
|
||||
|
||||
You can click the "View Details" button to drill into the
|
||||
editable details of the selected hero.
|
||||
|
||||
The following diagram captures all of the navigation options.
|
||||
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/toh/nav-diagram.png' alt="View navigations">
|
||||
</div>
|
||||
|
||||
Here's the app in action:
|
||||
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/toh/toh-anim.gif' alt="Tour of Heroes in Action">
|
||||
</div>
|
@ -1,88 +1,89 @@
|
||||
<h1 class="no-toc">Tour of Heroes app and tutorial</h1>
|
||||
<h1 class="no-toc">Aplicación y tutorial Tour de héroes</h1>
|
||||
|
||||
<div class="callout is-helpful">
|
||||
<header>Getting Started</header>
|
||||
<header>Primeros Pasos </header>
|
||||
|
||||
In this tutorial, you build your own app from the ground up, providing experience with the typical development process, as well as an introduction to basic app-design concepts, tools, and terminology.
|
||||
En este tutorial, crearás tu propia aplicación desde cero, proporcionando experiencia con el proceso de desarrollo típico, así como una introducción a los conceptos básicos de diseño de aplicaciones, herramientas y terminología.
|
||||
|
||||
If you're completely new to Angular, you might want to try the [**Try it now**](start) quick-start app first.
|
||||
It is based on a ready-made partially-completed project, which you can examine and modify in the StackBlitz interactive development environment, where you can see the results in real time.
|
||||
Si eres completamente nuevo en Angular, es posible que desees probar la aplicación de inicio rápido [**Pruébelo ahora **](start) primero.
|
||||
Se basa en un proyecto listo y parcialmente completado, que puedes examinar y modificar en el entorno de desarrollo interactivo de StackBlitz, donde puedes ver los resultados en tiempo real.
|
||||
|
||||
El tutorial "Pruébalo" cubre los mismos temas principales—componentes, sintaxis de plantilla, enrutamiento, servicios y acceso a datos a través de HTTP— en un formato condensado, siguiendo las mejores prácticas más actuales.
|
||||
|
||||
The "Try it" tutorial covers the same major topics—components, template syntax, routing, services, and accessing data via HTTP—in a condensed format, following the most current best practices.
|
||||
|
||||
</div>
|
||||
|
||||
This _Tour of Heroes_ tutorial shows you how to set up your local development environment and develop an app using the [Angular CLI tool](cli "CLI command reference"), and provides an introduction to the fundamentals of Angular.
|
||||
Este tutorial de _Tour de héroes_ te muestra cómo configurar tu entorno de desarrollo local y desarrollar una aplicación utilizando la [Herramienta CLI de Angular](cli "referencia de comando de CLI"), y proporciona una introducción a los fundamentos de Angular.
|
||||
|
||||
The _Tour of Heroes_ app that you build helps a staffing agency manage its stable of heroes.
|
||||
The app has many of the features you'd expect to find in any data-driven application.
|
||||
The finished app acquires and displays a list of heroes, edits a selected hero's detail, and navigates among different views of heroic data.
|
||||
La aplicación _Tour de héroes_ que construyes ayuda a una agencia de personal a administrar su grupo de héroes.
|
||||
La aplicación tiene muchas de las características que esperarías encontrar en cualquier aplicación basada en datos.
|
||||
La aplicación final adquiere y muestra una lista de héroes, edita los detalles de un héroe seleccionado y navega entre diferentes vistas de datos heroicos.
|
||||
|
||||
You will find references to and expansions of this app domain in many of the examples used throughout the Angular documentation, but you don't necessarily need to work through this tutorial to understand those examples.
|
||||
Encontrarás referencias y expansiones de este dominio de aplicación en muchos de los ejemplos utilizados en toda la documentación de Angular, pero no necesariamente necesitas trabajar en este tutorial para comprender esos ejemplos.
|
||||
|
||||
By the end of this tutorial you will be able to do the following:
|
||||
Al final de este tutorial, podrás hacer lo siguiente:
|
||||
|
||||
* Use built-in Angular [directives](guide/glossary#directive "Directives definition") to show and hide elements and display lists of hero data.
|
||||
* Create Angular [components](guide/glossary#component "Components definition") to display hero details and show an array of heroes.
|
||||
* Use one-way [data binding](guide/glossary#data-binding "Data binding definition") for read-only data.
|
||||
* Add editable fields to update a model with two-way data binding.
|
||||
* Bind component methods to user events, like keystrokes and clicks.
|
||||
* Enable users to select a hero from a master list and edit that hero in the details view.
|
||||
* Format data with [pipes](guide/glossary#pipe "Pipe definition").
|
||||
* Create a shared [service](guide/glossary#service "Service definition") to assemble the heroes.
|
||||
* Use [routing](guide/glossary#router "Router definition") to navigate among different views and their components.
|
||||
* Utilizar las [directivas](guide/glossary#directive "Definición de directivas") Angular integradas para mostrar y ocultar elementos y mostrar listas de datos de héroes.
|
||||
* Crear [componentes](guide/glossary#component "Definición de componentes") Angular para mostrar los detalles del héroe y mostrar una lista de héroes.
|
||||
* Usar el [enlace de datos](guide/glossary#data-binding "Definición de enlace de datos")(data binding) unidireccional para datos de solo lectura.
|
||||
* Agregar campos editables para actualizar un modelo con enlace de datos bidireccional.
|
||||
* Enlazar métodos de componentes a eventos de usuario, como pulsaciones de teclas y clics.
|
||||
* Permitir a los usuarios seleccionar un héroe de una lista maestra y editar ese héroe en la vista de detalles.
|
||||
* Dar formato a datos con [pipes](guide/glossary#pipe "Definición de Pipe ")
|
||||
* Crear un [servicio](guide/glossary#service "Definición de Servicio") compartido para reunir a los héroes.
|
||||
* Utilizar [enrutamiento](guide/glossary#router "Definición de Enrutamiento ")(routing) para navegar entre diferentes vistas y sus componentes.
|
||||
|
||||
You'll learn enough Angular to get started and gain confidence that
|
||||
Angular can do whatever you need it to do.
|
||||
Aprenderás suficiente Angular para comenzar y ganarás la confianza de que
|
||||
Angular puede hacer lo que tú necesites que haga.
|
||||
|
||||
<div class="callout is-helpful">
|
||||
<header>Solution</header>
|
||||
<header>Solución</header>
|
||||
|
||||
After completing all tutorial steps, the final app will look like this: <live-example name="toh-pt6"></live-example>.
|
||||
Después de completar todos los pasos del tutorial, la aplicación final se verá así: <live-example name="toh-pt6"> </live-example>.
|
||||
|
||||
</div>
|
||||
|
||||
## What you'll build
|
||||
## Lo que construirás
|
||||
|
||||
Here's a visual idea of where this tutorial leads, beginning with the "Dashboard"
|
||||
view and the most heroic heroes:
|
||||
Aquí hay una idea visual de a dónde conduce este tutorial, comenzando con una vista del "Dashboard" y los héroes más heroicos:
|
||||
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/toh/heroes-dashboard-1.png' alt="Output of heroes dashboard">
|
||||
<img src='generated/images/guide/toh/heroes-dashboard-1.png' alt="Salida del panel de héroes">
|
||||
</div>
|
||||
|
||||
You can click the two links above the dashboard ("Dashboard" and "Heroes")
|
||||
to navigate between this Dashboard view and a Heroes view.
|
||||
Puedes hacer clic en los dos enlaces que se encuentran sobre el dashboard ("Dashboard" y "Héroes")
|
||||
para navegar entre esta vista de Panel y una vista de Héroes.
|
||||
|
||||
If you click the dashboard hero "Magneta," the router opens a "Hero Details" view
|
||||
where you can change the hero's name.
|
||||
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/toh/hero-details-1.png' alt="Details of hero in app">
|
||||
</div>
|
||||
|
||||
Clicking the "Back" button returns you to the Dashboard.
|
||||
Links at the top take you to either of the main views.
|
||||
If you click "Heroes," the app displays the "Heroes" master list view.
|
||||
Si haces clic en el héroe del panel "Magneta", el enrutador abre una vista de "Detalles del héroe"
|
||||
donde puedes cambiar el nombre del héroe.
|
||||
|
||||
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/toh/heroes-list-2.png' alt="Output of heroes list app">
|
||||
<img src='generated/images/guide/toh/hero-details-1.png' alt="Detalles del héroe en la aplicación">
|
||||
</div>
|
||||
|
||||
When you click a different hero name, the read-only mini detail beneath the list reflects the new choice.
|
||||
Al hacer clic en el botón "Atrás", vuelves al Panel de control.
|
||||
Los enlaces en la parte superior te llevan a cualquiera de las vistas principales.
|
||||
Si haces clic en "Héroes", la aplicación muestra la vista de lista maestra "Héroes".
|
||||
|
||||
You can click the "View Details" button to drill into the
|
||||
editable details of the selected hero.
|
||||
|
||||
The following diagram captures all of the navigation options.
|
||||
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/toh/nav-diagram.png' alt="View navigations">
|
||||
<img src='generated/images/guide/toh/heroes-list-2.png' alt="Salida de la aplicación de lista de héroes">
|
||||
</div>
|
||||
|
||||
Here's the app in action:
|
||||
Cuando haces clic en un nombre de héroe diferente, el mini detalle de solo lectura debajo de la lista refleja la nueva opción.
|
||||
|
||||
Puedes hacer clic en el botón "Ver detalles" para profundizar en
|
||||
detalles editables del héroe seleccionado.
|
||||
|
||||
El siguiente diagrama captura todas las opciones de navegación.
|
||||
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/toh/toh-anim.gif' alt="Tour of Heroes in Action">
|
||||
<img src='generated/images/guide/toh/nav-diagram.png' alt="Ver navegación">
|
||||
</div>
|
||||
|
||||
Aquí está la aplicación en acción:
|
||||
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/toh/toh-anim.gif' alt="Tour de Heroes en acción">
|
||||
</div>
|
||||
|
141
aio/content/tutorial/toh-pt0.en.md
Normal file
141
aio/content/tutorial/toh-pt0.en.md
Normal file
@ -0,0 +1,141 @@
|
||||
# Create a new project
|
||||
|
||||
You begin by creating an initial application using the Angular CLI. Throughout this tutorial, you’ll modify and extend that starter application to create the Tour of Heroes app.
|
||||
|
||||
In this part of the tutorial, you'll do the following:
|
||||
|
||||
1. Set up your environment.
|
||||
2. Create a new workspace and initial app project.
|
||||
3. Serve the application.
|
||||
4. Make changes to the application.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For the sample app that this page describes, see the <live-example></live-example>.
|
||||
|
||||
</div>
|
||||
|
||||
## Set up your environment
|
||||
|
||||
To set up your development environment, follow the instructions in [Local Environment Setup](guide/setup-local "Setting up for Local Development").
|
||||
|
||||
|
||||
## Create a new workspace and an initial application
|
||||
|
||||
You develop apps in the context of an Angular [workspace](guide/glossary#workspace). A workspace contains the files for one or more [projects](guide/glossary#project). A project is the set of files that comprise an app, a library, or end-to-end (e2e) tests. For this tutorial, you will create a new workspace.
|
||||
|
||||
To create a new workspace and an initial app project:
|
||||
|
||||
1. Ensure that you are not already in an Angular workspace folder. For example, if you have previously created the Getting Started workspace, change to the parent of that folder.
|
||||
2. Run the CLI command `ng new` and provide the name `angular-tour-of-heroes`, as shown here:
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
ng new angular-tour-of-heroes
|
||||
</code-example>
|
||||
|
||||
3. The `ng new` command prompts you for information about features to include in the initial app project. Accept the defaults by pressing the Enter or Return key.
|
||||
|
||||
The Angular CLI installs the necessary Angular `npm` packages and other dependencies. This can take a few minutes.
|
||||
|
||||
It also creates the following workspace and starter project files:
|
||||
|
||||
* A new workspace, with a root folder named `angular-tour-of-heroes`.
|
||||
* An initial skeleton app project, also called `angular-tour-of-heroes` (in the `src` subfolder).
|
||||
* An end-to-end test project (in the e2e subfolder).
|
||||
* Related configuration files.
|
||||
|
||||
The initial app project contains a simple Welcome app, ready to run.
|
||||
|
||||
## Serve the application
|
||||
|
||||
Go to the workspace directory and launch the application.
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
cd angular-tour-of-heroes
|
||||
ng serve --open
|
||||
</code-example>
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
The `ng serve` command builds the app, starts the development server,
|
||||
watches the source files, and rebuilds the app as you make changes to those files.
|
||||
|
||||
The `--open` flag opens a browser to `http://localhost:4200/`.
|
||||
|
||||
</div>
|
||||
|
||||
You should see the app running in your browser.
|
||||
|
||||
## Angular components
|
||||
|
||||
The page you see is the _application shell_.
|
||||
The shell is controlled by an Angular **component** named `AppComponent`.
|
||||
|
||||
_Components_ are the fundamental building blocks of Angular applications.
|
||||
They display data on the screen, listen for user input, and take action based on that input.
|
||||
|
||||
## Make changes to the application
|
||||
|
||||
Open the project in your favorite editor or IDE and navigate to the `src/app` folder to make some changes to the starter app.
|
||||
|
||||
You'll find the implementation of the shell `AppComponent` distributed over three files:
|
||||
|
||||
1. `app.component.ts`— the component class code, written in TypeScript.
|
||||
1. `app.component.html`— the component template, written in HTML.
|
||||
1. `app.component.css`— the component's private CSS styles.
|
||||
|
||||
### Change the application title
|
||||
|
||||
Open the component class file (`app.component.ts`) and change the value of the `title` property to 'Tour of Heroes'.
|
||||
|
||||
<code-example path="toh-pt0/src/app/app.component.ts" region="set-title" header="app.component.ts (class title property)"></code-example>
|
||||
|
||||
Open the component template file (`app.component.html`) and
|
||||
delete the default template generated by the Angular CLI.
|
||||
Replace it with the following line of HTML.
|
||||
|
||||
<code-example path="toh-pt0/src/app/app.component.html"
|
||||
header="app.component.html (template)"></code-example>
|
||||
|
||||
The double curly braces are Angular's *interpolation binding* syntax.
|
||||
This interpolation binding presents the component's `title` property value
|
||||
inside the HTML header tag.
|
||||
|
||||
The browser refreshes and displays the new application title.
|
||||
|
||||
{@a app-wide-styles}
|
||||
|
||||
### Add application styles
|
||||
|
||||
Most apps strive for a consistent look across the application.
|
||||
The CLI generated an empty `styles.css` for this purpose.
|
||||
Put your application-wide styles there.
|
||||
|
||||
Open `src/styles.css` and add the code below to the file.
|
||||
|
||||
<code-example path="toh-pt0/src/styles.1.css" header="src/styles.css (excerpt)">
|
||||
</code-example>
|
||||
|
||||
## Final code review
|
||||
|
||||
Here are the code files discussed on this page.
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane header="src/app/app.component.ts" path="toh-pt0/src/app/app.component.ts">
|
||||
</code-pane>
|
||||
|
||||
<code-pane header="src/app/app.component.html" path="toh-pt0/src/app/app.component.html">
|
||||
</code-pane>
|
||||
|
||||
<code-pane
|
||||
header="src/styles.css (excerpt)"
|
||||
path="toh-pt0/src/styles.1.css">
|
||||
</code-pane>
|
||||
</code-tabs>
|
||||
|
||||
## Summary
|
||||
|
||||
* You created the initial application structure using the Angular CLI.
|
||||
* You learned that Angular components display data.
|
||||
* You used the double curly braces of interpolation to display the app title.
|
@ -1,54 +1,54 @@
|
||||
# Create a new project
|
||||
# Crea un nuevo proyecto
|
||||
|
||||
You begin by creating an initial application using the Angular CLI. Throughout this tutorial, you’ll modify and extend that starter application to create the Tour of Heroes app.
|
||||
Primero, crea la aplicación inicial usando el Angular CLI. En este Tutorial, modificarás y ampliarás la aplicación inicial para crear la aplicación Tour de Héroes.
|
||||
|
||||
In this part of the tutorial, you'll do the following:
|
||||
En esta parte del tutorial, harás lo siguiente:
|
||||
|
||||
1. Set up your environment.
|
||||
2. Create a new workspace and initial app project.
|
||||
3. Serve the application.
|
||||
4. Make changes to the application.
|
||||
1. Establecer tu ambiente de desarrollo.
|
||||
2. Crear un nuevo espacio de trabajo y un proyecto de aplicación inicial.
|
||||
3. Servir la aplicación.
|
||||
4. Hacer cambios a la aplicación.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For the sample app that this page describes, see the <live-example></live-example>.
|
||||
Para ver la aplicación de ejemplo que describe esta página, consulta el <live-example></live-example>.
|
||||
|
||||
</div>
|
||||
|
||||
## Set up your environment
|
||||
## Configura tu entorno
|
||||
|
||||
To set up your development environment, follow the instructions in [Local Environment Setup](guide/setup-local "Setting up for Local Development").
|
||||
Para preparar tu entorno de desarrollo, sigue las instrucciones en [Creación de un entorno local](guide/setup-local "Configuración para el desarrollo local").
|
||||
|
||||
## Crear un nuevo espacio de trabajo y un enlace de aplicación inicial
|
||||
|
||||
## Create a new workspace and an initial application
|
||||
Desarrolla tu aplicación en el contexto del espacio de trabajo Angular. [Espacio de trabajo](guide/glossary#workspace). contiene uno o más archivos [proyecto]. Un proyecto es un conjunto de archivos que componen una aplicación, biblioteca o prueba de extremo a extremo (e2e).
|
||||
En este Tutorial, crearas un nuevo espacio de trabajo.
|
||||
|
||||
You develop apps in the context of an Angular [workspace](guide/glossary#workspace). A workspace contains the files for one or more [projects](guide/glossary#project). A project is the set of files that comprise an app, a library, or end-to-end (e2e) tests. For this tutorial, you will create a new workspace.
|
||||
Para crear un nuevo espacio de trabajo y un proyecto de aplicación inicial:
|
||||
|
||||
To create a new workspace and an initial app project:
|
||||
|
||||
1. Ensure that you are not already in an Angular workspace folder. For example, if you have previously created the Getting Started workspace, change to the parent of that folder.
|
||||
2. Run the CLI command `ng new` and provide the name `angular-tour-of-heroes`, as shown here:
|
||||
1. Asegurate de que no esté en la carpeta del espacio de trabajo Angular. Por ejemplo, si creó anteriormente el espacio de trabajo Introducción, cambia a la carpeta principal de esa carpeta.
|
||||
2. Ejecuta el comando CLI `ng new` y asígnale el nombre `angular-tour-of-heroes`, como se muestra a continuación.
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
ng new angular-tour-of-heroes
|
||||
ng new angular-tour-of-heroes
|
||||
</code-example>
|
||||
|
||||
3. The `ng new` command prompts you for information about features to include in the initial app project. Accept the defaults by pressing the Enter or Return key.
|
||||
3. Ejecuta el comando `ng new` y verá información sobre las funciones que desea incluir en su primer proyecto de aplicación. Presione Entrar o Volver para aceptar el valor predeterminado.
|
||||
|
||||
The Angular CLI installs the necessary Angular `npm` packages and other dependencies. This can take a few minutes.
|
||||
Angular CLI instala los paquetes Angular npm necesarios y otras dependencias. Esto puede tomar unos pocos minutos.
|
||||
|
||||
It also creates the following workspace and starter project files:
|
||||
También crea el siguiente espacio de trabajo y archivos de proyecto de inicio.
|
||||
|
||||
* A new workspace, with a root folder named `angular-tour-of-heroes`.
|
||||
* An initial skeleton app project, also called `angular-tour-of-heroes` (in the `src` subfolder).
|
||||
* An end-to-end test project (in the e2e subfolder).
|
||||
* Related configuration files.
|
||||
* Un nuevo espacio de trabajo con una carpeta raíz llamada `angular-tour-of-heroes`.
|
||||
* Un proyecto de aplicación esqueleto inicial también llamado `angular-tour-of-heroes`. (En la subcarpeta `src`)
|
||||
* Proyecto de prueba de extremo a extremo. (En la subcarpeta `e2e`)
|
||||
* Archivos de configuración relacionados.
|
||||
|
||||
The initial app project contains a simple Welcome app, ready to run.
|
||||
El primer proyecto de aplicación contiene una aplicación de bienvenida simple que puede ejecutar de inmediato.
|
||||
|
||||
## Serve the application
|
||||
## Servir la aplicación
|
||||
|
||||
Go to the workspace directory and launch the application.
|
||||
Ve al directorio de tu espacio de trabajo e inicia la aplicación.
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
cd angular-tour-of-heroes
|
||||
@ -57,68 +57,67 @@ Go to the workspace directory and launch the application.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
The `ng serve` command builds the app, starts the development server,
|
||||
watches the source files, and rebuilds the app as you make changes to those files.
|
||||
El comando `ng serve` crea la aplicación, inicia el servidor de desarrollo y observa los archivos de origen.
|
||||
Cuando realiza un cambio en un archivo que se está viendo, se realizará una reconstrucción en el archivo modificado.
|
||||
|
||||
The `--open` flag opens a browser to `http://localhost:4200/`.
|
||||
Si especificas la bandera `--open`, se abrirá `http://localhost:4200` en tu navegador.
|
||||
|
||||
</div>
|
||||
|
||||
You should see the app running in your browser.
|
||||
Asegúrate de que la aplicación se esté ejecutando en su navegador.
|
||||
|
||||
## Angular components
|
||||
## Componentes de Angular
|
||||
|
||||
The page you see is the _application shell_.
|
||||
The shell is controlled by an Angular **component** named `AppComponent`.
|
||||
La página que se muestra es _Shell de Aplicación_.
|
||||
Este shell funciona desde un **componente** Angular llamado `AppComponent`.
|
||||
|
||||
_Components_ are the fundamental building blocks of Angular applications.
|
||||
They display data on the screen, listen for user input, and take action based on that input.
|
||||
Los componentes son los bloques de construcción fundamentales de las aplicaciones Angular.
|
||||
Ellos muestran informacion en la pantalla, esperan el ingreso de datos del usuario y toman acciones basados en esa informacion ingresada.
|
||||
|
||||
## Make changes to the application
|
||||
## Cambiar la aplicación
|
||||
|
||||
Open the project in your favorite editor or IDE and navigate to the `src/app` folder to make some changes to the starter app.
|
||||
Para hacer algunos cambios en la aplicación de inicio, abre el proyecto en su editor de texto favorito o IDE y vaya a `src/app`.
|
||||
|
||||
You'll find the implementation of the shell `AppComponent` distributed over three files:
|
||||
Encontrará la implementación del shell `AppComponent`, dividido en tres archivos:
|
||||
|
||||
1. `app.component.ts`— the component class code, written in TypeScript.
|
||||
1. `app.component.html`— the component template, written in HTML.
|
||||
1. `app.component.css`— the component's private CSS styles.
|
||||
1. `app.component.ts`— Este es el código para la clase de componente escrita en TypeScript.
|
||||
1. `app.component.html`— Este es el componente Plantillas escrito en HTML.
|
||||
1. `app.component.css`— CSS solo para este componente.
|
||||
|
||||
### Change the application title
|
||||
### Cambiar el título de la aplicación
|
||||
|
||||
Open the component class file (`app.component.ts`) and change the value of the `title` property to 'Tour of Heroes'.
|
||||
Abre el archivo de clase de componente (`app.component.ts`) y cambia el valor de la propiedad `title` a `Tour de Heroes`.
|
||||
|
||||
<code-example path="toh-pt0/src/app/app.component.ts" region="set-title" header="app.component.ts (class title property)"></code-example>
|
||||
|
||||
Open the component template file (`app.component.html`) and
|
||||
delete the default template generated by the Angular CLI.
|
||||
Replace it with the following line of HTML.
|
||||
Abre el archivo de plantilla de componente (`app.component.html`) y
|
||||
Elimina la plantilla predeterminada generada por el Angular CLI.
|
||||
Coloca el siguiente HTML en su lugar.
|
||||
|
||||
<code-example path="toh-pt0/src/app/app.component.html"
|
||||
header="app.component.html (template)"></code-example>
|
||||
|
||||
The double curly braces are Angular's *interpolation binding* syntax.
|
||||
This interpolation binding presents the component's `title` property value
|
||||
inside the HTML header tag.
|
||||
Las llaves dobles son la sintaxis de *interpolación vinculante* de Angular.
|
||||
Este enlace de interpolación pasa el valor de la propiedad `title` del componente en la etiqueta de encabezado HTML.
|
||||
|
||||
The browser refreshes and displays the new application title.
|
||||
El navegador actualiza la página con el nuevo título de la aplicación.
|
||||
|
||||
{@a app-wide-styles}
|
||||
|
||||
### Add application styles
|
||||
### Añadir estilo de aplicación
|
||||
|
||||
Most apps strive for a consistent look across the application.
|
||||
The CLI generated an empty `styles.css` for this purpose.
|
||||
Put your application-wide styles there.
|
||||
La mayoría de las aplicaciones apuntan a una apariencia consistente en toda la aplicación.
|
||||
El CLI ha generado un `styles.css` vacío para este propósito.
|
||||
Escriba estilos que se apliquen a toda la aplicación, allí.
|
||||
|
||||
Open `src/styles.css` and add the code below to the file.
|
||||
Abre `src/style.css` y agrega el siguiente código al archivo.
|
||||
|
||||
<code-example path="toh-pt0/src/styles.1.css" header="src/styles.css (excerpt)">
|
||||
</code-example>
|
||||
|
||||
## Final code review
|
||||
## Revisión final del código
|
||||
|
||||
Here are the code files discussed on this page.
|
||||
A continuación se muestra un archivo del código mencionado en esta página.
|
||||
|
||||
<code-tabs>
|
||||
|
||||
@ -134,8 +133,8 @@ Here are the code files discussed on this page.
|
||||
</code-pane>
|
||||
</code-tabs>
|
||||
|
||||
## Summary
|
||||
## Resumen
|
||||
|
||||
* You created the initial application structure using the Angular CLI.
|
||||
* You learned that Angular components display data.
|
||||
* You used the double curly braces of interpolation to display the app title.
|
||||
* Creaste la estructura de la aplicación inicial utilizando el CLI Angular.
|
||||
* Aprendiste que los componentes de Angular muestran datos.
|
||||
* Utilizaste las llaves dobles de interpolación para mostrar el título de la aplicación.
|
||||
|
245
aio/content/tutorial/toh-pt1.en.md
Normal file
245
aio/content/tutorial/toh-pt1.en.md
Normal file
@ -0,0 +1,245 @@
|
||||
# The hero editor
|
||||
|
||||
The application now has a basic title.
|
||||
Next you will create a new component to display hero information
|
||||
and place that component in the application shell.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For the sample app that this page describes, see the <live-example></live-example>.
|
||||
|
||||
</div>
|
||||
|
||||
## Create the heroes component
|
||||
|
||||
Using the Angular CLI, generate a new component named `heroes`.
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
ng generate component heroes
|
||||
</code-example>
|
||||
|
||||
The CLI creates a new folder, `src/app/heroes/`, and generates
|
||||
the three files of the `HeroesComponent` along with a test file.
|
||||
|
||||
The `HeroesComponent` class file is as follows:
|
||||
|
||||
<code-example path="toh-pt1/src/app/heroes/heroes.component.ts" region="v1" header="app/heroes/heroes.component.ts (initial version)"></code-example>
|
||||
|
||||
You always import the `Component` symbol from the Angular core library
|
||||
and annotate the component class with `@Component`.
|
||||
|
||||
`@Component` is a decorator function that specifies the Angular metadata for the component.
|
||||
|
||||
The CLI generated three metadata properties:
|
||||
|
||||
1. `selector`— the component's CSS element selector
|
||||
1. `templateUrl`— the location of the component's template file.
|
||||
1. `styleUrls`— the location of the component's private CSS styles.
|
||||
|
||||
{@a selector}
|
||||
|
||||
The [CSS element selector](https://developer.mozilla.org/en-US/docs/Web/CSS/Type_selectors),
|
||||
`'app-heroes'`, matches the name of the HTML element that identifies this component within a parent component's template.
|
||||
|
||||
The `ngOnInit()` is a [lifecycle hook](guide/lifecycle-hooks#oninit).
|
||||
Angular calls `ngOnInit()` shortly after creating a component.
|
||||
It's a good place to put initialization logic.
|
||||
|
||||
Always `export` the component class so you can `import` it elsewhere ... like in the `AppModule`.
|
||||
|
||||
### Add a `hero` property
|
||||
|
||||
Add a `hero` property to the `HeroesComponent` for a hero named "Windstorm."
|
||||
|
||||
<code-example path="toh-pt1/src/app/heroes/heroes.component.ts" region="add-hero" header="heroes.component.ts (hero property)"></code-example>
|
||||
|
||||
### Show the hero
|
||||
|
||||
Open the `heroes.component.html` template file.
|
||||
Delete the default text generated by the Angular CLI and
|
||||
replace it with a data binding to the new `hero` property.
|
||||
|
||||
<code-example path="toh-pt1/src/app/heroes/heroes.component.1.html" header="heroes.component.html" region="show-hero-1"></code-example>
|
||||
|
||||
## Show the `HeroesComponent` view
|
||||
|
||||
To display the `HeroesComponent`, you must add it to the template of the shell `AppComponent`.
|
||||
|
||||
Remember that `app-heroes` is the [element selector](#selector) for the `HeroesComponent`.
|
||||
So add an `<app-heroes>` element to the `AppComponent` template file, just below the title.
|
||||
|
||||
<code-example path="toh-pt1/src/app/app.component.html" header="src/app/app.component.html"></code-example>
|
||||
|
||||
Assuming that the CLI `ng serve` command is still running,
|
||||
the browser should refresh and display both the application title and the hero name.
|
||||
|
||||
## Create a Hero interface
|
||||
|
||||
A real hero is more than a name.
|
||||
|
||||
Create a `Hero` interface in its own file in the `src/app` folder.
|
||||
Give it `id` and `name` properties.
|
||||
|
||||
<code-example path="toh-pt1/src/app/hero.ts" header="src/app/hero.ts"></code-example>
|
||||
|
||||
|
||||
Return to the `HeroesComponent` class and import the `Hero` interface.
|
||||
|
||||
Refactor the component's `hero` property to be of type `Hero`.
|
||||
Initialize it with an `id` of `1` and the name `Windstorm`.
|
||||
|
||||
The revised `HeroesComponent` class file should look like this:
|
||||
|
||||
<code-example path="toh-pt1/src/app/heroes/heroes.component.ts" header="src/app/heroes/heroes.component.ts"></code-example>
|
||||
|
||||
The page no longer displays properly because you changed the hero from a string to an object.
|
||||
|
||||
## Show the hero object
|
||||
|
||||
Update the binding in the template to announce the hero's name
|
||||
and show both `id` and `name` in a details layout like this:
|
||||
|
||||
<code-example path="toh-pt1/src/app/heroes/heroes.component.1.html" region="show-hero-2" header="heroes.component.html (HeroesComponent's template)"></code-example>
|
||||
|
||||
The browser refreshes and displays the hero's information.
|
||||
|
||||
## Format with the _UppercasePipe_
|
||||
|
||||
Modify the `hero.name` binding like this.
|
||||
<code-example path="toh-pt1/src/app/heroes/heroes.component.html" header="src/app/heroes/heroes.component.html" region="pipe">
|
||||
</code-example>
|
||||
|
||||
The browser refreshes and now the hero's name is displayed in capital letters.
|
||||
|
||||
The word `uppercase` in the interpolation binding,
|
||||
right after the pipe operator ( | ),
|
||||
activates the built-in `UppercasePipe`.
|
||||
|
||||
[Pipes](guide/pipes) are a good way to format strings, currency amounts, dates and other display data.
|
||||
Angular ships with several built-in pipes and you can create your own.
|
||||
|
||||
## Edit the hero
|
||||
|
||||
Users should be able to edit the hero name in an `<input>` textbox.
|
||||
|
||||
The textbox should both _display_ the hero's `name` property
|
||||
and _update_ that property as the user types.
|
||||
That means data flows from the component class _out to the screen_ and
|
||||
from the screen _back to the class_.
|
||||
|
||||
To automate that data flow, setup a two-way data binding between the `<input>` form element and the `hero.name` property.
|
||||
|
||||
### Two-way binding
|
||||
|
||||
Refactor the details area in the `HeroesComponent` template so it looks like this:
|
||||
|
||||
<code-example path="toh-pt1/src/app/heroes/heroes.component.1.html" region="name-input" header="src/app/heroes/heroes.component.html (HeroesComponent's template)"></code-example>
|
||||
|
||||
**[(ngModel)]** is Angular's two-way data binding syntax.
|
||||
|
||||
Here it binds the `hero.name` property to the HTML textbox so that data can flow _in both directions:_ from the `hero.name` property to the textbox, and from the textbox back to the `hero.name`.
|
||||
|
||||
### The missing _FormsModule_
|
||||
|
||||
Notice that the app stopped working when you added `[(ngModel)]`.
|
||||
|
||||
To see the error, open the browser development tools and look in the console
|
||||
for a message like
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
Template parse errors:
|
||||
Can't bind to 'ngModel' since it isn't a known property of 'input'.
|
||||
</code-example>
|
||||
|
||||
Although `ngModel` is a valid Angular directive, it isn't available by default.
|
||||
|
||||
It belongs to the optional `FormsModule` and you must _opt-in_ to using it.
|
||||
|
||||
## _AppModule_
|
||||
|
||||
Angular needs to know how the pieces of your application fit together
|
||||
and what other files and libraries the app requires.
|
||||
This information is called _metadata_.
|
||||
|
||||
Some of the metadata is in the `@Component` decorators that you added to your component classes.
|
||||
Other critical metadata is in [`@NgModule`](guide/ngmodules) decorators.
|
||||
|
||||
The most important `@NgModule` decorator annotates the top-level **AppModule** class.
|
||||
|
||||
The Angular CLI generated an `AppModule` class in `src/app/app.module.ts` when it created the project.
|
||||
This is where you _opt-in_ to the `FormsModule`.
|
||||
|
||||
### Import _FormsModule_
|
||||
|
||||
Open `AppModule` (`app.module.ts`) and import the `FormsModule` symbol from the `@angular/forms` library.
|
||||
|
||||
<code-example path="toh-pt1/src/app/app.module.ts" header="app.module.ts (FormsModule symbol import)"
|
||||
region="formsmodule-js-import">
|
||||
</code-example>
|
||||
|
||||
Then add `FormsModule` to the `@NgModule` metadata's `imports` array, which contains a list of external modules that the app needs.
|
||||
|
||||
<code-example path="toh-pt1/src/app/app.module.ts" header="app.module.ts (@NgModule imports)"
|
||||
region="ng-imports">
|
||||
</code-example>
|
||||
|
||||
When the browser refreshes, the app should work again. You can edit the hero's name and see the changes reflected immediately in the `<h2>` above the textbox.
|
||||
|
||||
### Declare `HeroesComponent`
|
||||
|
||||
Every component must be declared in _exactly one_ [NgModule](guide/ngmodules).
|
||||
|
||||
_You_ didn't declare the `HeroesComponent`.
|
||||
So why did the application work?
|
||||
|
||||
It worked because the Angular CLI declared `HeroesComponent` in the `AppModule` when it generated that component.
|
||||
|
||||
Open `src/app/app.module.ts` and find `HeroesComponent` imported near the top.
|
||||
<code-example path="toh-pt1/src/app/app.module.ts" header="src/app/app.module.ts" region="heroes-import" >
|
||||
</code-example>
|
||||
|
||||
The `HeroesComponent` is declared in the `@NgModule.declarations` array.
|
||||
<code-example path="toh-pt1/src/app/app.module.ts" header="src/app/app.module.ts" region="declarations">
|
||||
</code-example>
|
||||
|
||||
Note that `AppModule` declares both application components, `AppComponent` and `HeroesComponent`.
|
||||
|
||||
|
||||
## Final code review
|
||||
|
||||
Here are the code files discussed on this page.
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane header="src/app/heroes/heroes.component.ts" path="toh-pt1/src/app/heroes/heroes.component.ts">
|
||||
</code-pane>
|
||||
|
||||
<code-pane header="src/app/heroes/heroes.component.html" path="toh-pt1/src/app/heroes/heroes.component.html">
|
||||
</code-pane>
|
||||
|
||||
<code-pane header="src/app/app.module.ts"
|
||||
path="toh-pt1/src/app/app.module.ts">
|
||||
</code-pane>
|
||||
|
||||
<code-pane header="src/app/app.component.ts" path="toh-pt1/src/app/app.component.ts">
|
||||
</code-pane>
|
||||
|
||||
<code-pane header="src/app/app.component.html" path="toh-pt1/src/app/app.component.html">
|
||||
</code-pane>
|
||||
|
||||
<code-pane header="src/app/hero.ts"
|
||||
path="toh-pt1/src/app/hero.ts">
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
## Summary
|
||||
|
||||
* You used the CLI to create a second `HeroesComponent`.
|
||||
* You displayed the `HeroesComponent` by adding it to the `AppComponent` shell.
|
||||
* You applied the `UppercasePipe` to format the name.
|
||||
* You used two-way data binding with the `ngModel` directive.
|
||||
* You learned about the `AppModule`.
|
||||
* You imported the `FormsModule` in the `AppModule` so that Angular would recognize and apply the `ngModel` directive.
|
||||
* You learned the importance of declaring components in the `AppModule`
|
||||
and appreciated that the CLI declared it for you.
|
@ -1,213 +1,213 @@
|
||||
# The hero editor
|
||||
# El editor de Héroe
|
||||
|
||||
The application now has a basic title.
|
||||
Next you will create a new component to display hero information
|
||||
and place that component in the application shell.
|
||||
Se ha agregado un título básico a la aplicación.
|
||||
Luego crea un nuevo componente para mostrar la información del héroe,
|
||||
Coloca el componente en el (app shell) de la aplicación.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For the sample app that this page describes, see the <live-example></live-example>.
|
||||
Para ver la aplicación de ejemplo que describe esta página, consulta el <live-example></live-example>.
|
||||
|
||||
</div>
|
||||
|
||||
## Create the heroes component
|
||||
## Crear un componente de héroes
|
||||
|
||||
Using the Angular CLI, generate a new component named `heroes`.
|
||||
Usa la CLI angular para generar un nuevo componente llamado `heroes`.
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
ng generate component heroes
|
||||
</code-example>
|
||||
|
||||
The CLI creates a new folder, `src/app/heroes/`, and generates
|
||||
the three files of the `HeroesComponent` along with a test file.
|
||||
CLI crea una nueva carpeta llamada `src/app/heroes/`, y
|
||||
genera tres archivos sobre `HeroesComponent` junto un archivo de prueba.
|
||||
|
||||
The `HeroesComponent` class file is as follows:
|
||||
El archivo de la clase `HeroesComponent` es el siguiente.
|
||||
|
||||
<code-example path="toh-pt1/src/app/heroes/heroes.component.ts" region="v1" header="app/heroes/heroes.component.ts (initial version)"></code-example>
|
||||
|
||||
You always import the `Component` symbol from the Angular core library
|
||||
and annotate the component class with `@Component`.
|
||||
Siempre Importa el símbolo `Component` de la biblioteca pricipal de Angular, y realiza la anotación a la clase del component con `@Component`.
|
||||
|
||||
`@Component` is a decorator function that specifies the Angular metadata for the component.
|
||||
`@Component` es una decoradoro que especifica metadatos Angular para un
|
||||
componente.
|
||||
|
||||
The CLI generated three metadata properties:
|
||||
La CLI generó 3 propiedades de metadatos:
|
||||
|
||||
1. `selector`— the component's CSS element selector
|
||||
1. `templateUrl`— the location of the component's template file.
|
||||
1. `styleUrls`— the location of the component's private CSS styles.
|
||||
1. `selector`— El selector de elementos CSS para el componente
|
||||
1. `templateUrl`— La ubicación del archivo plantilla para el componente
|
||||
1. `styleUrls`— La ubicación de los estilos CSS privados del componente.
|
||||
|
||||
{@a selector}
|
||||
|
||||
The [CSS element selector](https://developer.mozilla.org/en-US/docs/Web/CSS/Type_selectors),
|
||||
`'app-heroes'`, matches the name of the HTML element that identifies this component within a parent component's template.
|
||||
El [Selector de elementos CSS](https://developer.mozilla.org/en-US/docs/Web/CSS/Type_selectors)
|
||||
`'app-heroes'`, coincide con el nombre del elemento HTML que identifica este componente en el componente padre Plantillas.
|
||||
|
||||
The `ngOnInit()` is a [lifecycle hook](guide/lifecycle-hooks#oninit).
|
||||
Angular calls `ngOnInit()` shortly after creating a component.
|
||||
It's a good place to put initialization logic.
|
||||
El `ngOnInit()` es un [gancho de ciclo de vida](guide/lifecycle-hooks#oninit) ("lifecycle hook") . Angular llama a `ngOnInit()` inmediatamente después de crear el componente.
|
||||
Adecuado para poner la lógica de inicialización.
|
||||
|
||||
Always `export` the component class so you can `import` it elsewhere ... like in the `AppModule`.
|
||||
Siempre `exporta` la clase de componente, por lo que siempre puede `importarla` en otro lugar, como un `AppModule`.
|
||||
|
||||
### Add a `hero` property
|
||||
### Agrega la propiedad `hero`
|
||||
|
||||
Add a `hero` property to the `HeroesComponent` for a hero named "Windstorm."
|
||||
Agrega una propiedad `hero` al `HeroesComponent` para un héroe llamado "Windstorm".
|
||||
|
||||
<code-example path="toh-pt1/src/app/heroes/heroes.component.ts" region="add-hero" header="heroes.component.ts (hero property)"></code-example>
|
||||
|
||||
### Show the hero
|
||||
### Mostrar el héroe
|
||||
|
||||
Open the `heroes.component.html` template file.
|
||||
Delete the default text generated by the Angular CLI and
|
||||
replace it with a data binding to the new `hero` property.
|
||||
Abre el archivo de plantilla `heroes.component.html`.
|
||||
Elimina el texto predeterminado generado por CLI angular,
|
||||
Reemplaza con un enlace de datos a la nueva propiedad `hero`.
|
||||
|
||||
<code-example path="toh-pt1/src/app/heroes/heroes.component.1.html" header="heroes.component.html" region="show-hero-1"></code-example>
|
||||
|
||||
## Show the `HeroesComponent` view
|
||||
## Mostrar la vista `HeroesComponent`
|
||||
|
||||
To display the `HeroesComponent`, you must add it to the template of the shell `AppComponent`.
|
||||
Para ver el `HeroesComponent`, debe agregarlo a las Plantillas en el `AppComponent` del shell de tu aplicación.
|
||||
|
||||
Remember that `app-heroes` is the [element selector](#selector) for the `HeroesComponent`.
|
||||
So add an `<app-heroes>` element to the `AppComponent` template file, just below the title.
|
||||
Recuerda que `app-heroes` es el [selector de elemento](#selector) del `HeroesComponent`.
|
||||
Entonces, en el archivo Plantillas de `AppComponent`, agrega el elemento `<app-heroes>` directamente debajo del título.
|
||||
|
||||
<code-example path="toh-pt1/src/app/app.component.html" header="src/app/app.component.html"></code-example>
|
||||
|
||||
Assuming that the CLI `ng serve` command is still running,
|
||||
the browser should refresh and display both the application title and the hero name.
|
||||
Si el comando CLI `ng serve` todavía se está ejecutando,
|
||||
El navegador se actualiza para mostrar el título de la aplicación y el nombre del héroe.
|
||||
|
||||
## Create a Hero interface
|
||||
## Crear interfaz de héroe
|
||||
|
||||
A real hero is more than a name.
|
||||
Un héroe es más que un nombre.
|
||||
|
||||
Create a `Hero` interface in its own file in the `src/app` folder.
|
||||
Give it `id` and `name` properties.
|
||||
Crea una interfaz `Hero` en su propio archivo en la carpeta `src/app`.
|
||||
Dale una propiedad `id` y una propiedad `name`.
|
||||
|
||||
<code-example path="toh-pt1/src/app/hero.ts" header="src/app/hero.ts"></code-example>
|
||||
|
||||
|
||||
Return to the `HeroesComponent` class and import the `Hero` interface.
|
||||
Regresa a la clase `HeroesComponent` e importe la interfaz `Hero`.
|
||||
|
||||
Refactor the component's `hero` property to be of type `Hero`.
|
||||
Initialize it with an `id` of `1` and the name `Windstorm`.
|
||||
Refactoriza la propiedad de héroe del componente para que sea del tipo 'Héroe'.
|
||||
Inicialízalo con un `id` de `1` y un nombre de `Windstorm`.
|
||||
|
||||
The revised `HeroesComponent` class file should look like this:
|
||||
El archivo de clase revisado `HeroesComponent` se ve así:
|
||||
|
||||
<code-example path="toh-pt1/src/app/heroes/heroes.component.ts" header="src/app/heroes/heroes.component.ts"></code-example>
|
||||
|
||||
The page no longer displays properly because you changed the hero from a string to an object.
|
||||
Cambió el héroe de texto a un objeto, lo que provocó que la página se mostrara incorrectamente.
|
||||
|
||||
## Show the hero object
|
||||
## Mostrar objeto de héroe
|
||||
|
||||
Update the binding in the template to announce the hero's name
|
||||
and show both `id` and `name` in a details layout like this:
|
||||
Actualiza los enlaces de Plantillas para anunciar el nombre del héroe,
|
||||
Muestra tanto el `id` como el `name` con un diseño detallado como este:
|
||||
|
||||
<code-example path="toh-pt1/src/app/heroes/heroes.component.1.html" region="show-hero-2" header="heroes.component.html (HeroesComponent's template)"></code-example>
|
||||
|
||||
The browser refreshes and displays the hero's information.
|
||||
El navegador se actualiza para mostrar la información del héroe.
|
||||
|
||||
## Format with the _UppercasePipe_
|
||||
## Formatea con _UppercasePipe_
|
||||
|
||||
Modify the `hero.name` binding like this.
|
||||
Modifica el enlace para `hero.name` de esta manera:
|
||||
<code-example path="toh-pt1/src/app/heroes/heroes.component.html" header="src/app/heroes/heroes.component.html" region="pipe">
|
||||
</code-example>
|
||||
|
||||
The browser refreshes and now the hero's name is displayed in capital letters.
|
||||
El navegador se actualizará para mostrar el nombre del héroe en mayúsculas.
|
||||
|
||||
The word `uppercase` in the interpolation binding,
|
||||
right after the pipe operator ( | ),
|
||||
activates the built-in `UppercasePipe`.
|
||||
En el enlace de interpolación, la palabra `mayúscula` inmediatamente después del operador pipe (|) es
|
||||
Inicie el 'UppercasePipe' incorporado.
|
||||
|
||||
[Pipes](guide/pipes) are a good way to format strings, currency amounts, dates and other display data.
|
||||
Angular ships with several built-in pipes and you can create your own.
|
||||
[pipe](guide/pipes) ("pipe") Es adecuado para formatear cadenas, importes monetarios, fechas y otros datos de visualización.
|
||||
Angular viene con múltiples pipes incorporadas, y puede crear las suyas propias.
|
||||
|
||||
## Edit the hero
|
||||
## Editar el héroe
|
||||
|
||||
Users should be able to edit the hero name in an `<input>` textbox.
|
||||
El usuario debe poder editar el nombre del héroe en el cuadro de texto `<input>`.
|
||||
|
||||
The textbox should both _display_ the hero's `name` property
|
||||
and _update_ that property as the user types.
|
||||
That means data flows from the component class _out to the screen_ and
|
||||
from the screen _back to the class_.
|
||||
En el cuadro de texto, la propiedad `name` del héroe se muestra _,
|
||||
La propiedad se actualiza según los tipos de usuario.
|
||||
Esto es de la clase de componente a _screen_,
|
||||
Y significa el flujo de datos desde la pantalla a la clase de componente.
|
||||
|
||||
To automate that data flow, setup a two-way data binding between the `<input>` form element and the `hero.name` property.
|
||||
Para automatizar ese flujo de datos, configure un enlace de datos bidireccional entre el elemento de formulario `<input>` y la propiedad `hero.name`.
|
||||
|
||||
### Two-way binding
|
||||
### Enlace de datos bidireccional
|
||||
|
||||
Refactor the details area in the `HeroesComponent` template so it looks like this:
|
||||
Refactorizando el área de detalle de las Plantas `HeroesComponent` se ve así:
|
||||
|
||||
<code-example path="toh-pt1/src/app/heroes/heroes.component.1.html" region="name-input" header="src/app/heroes/heroes.component.html (HeroesComponent's template)"></code-example>
|
||||
|
||||
**[(ngModel)]** is Angular's two-way data binding syntax.
|
||||
**[(ngModel)]** Es la sintaxis de enlace de datos bidireccional de Angular.
|
||||
|
||||
Here it binds the `hero.name` property to the HTML textbox so that data can flow _in both directions:_ from the `hero.name` property to the textbox, and from the textbox back to the `hero.name`.
|
||||
Esto vinculará la propiedad `hero.name` al cuadro de texto HTML, por lo que
|
||||
Puede pasar datos _en ambas direcciones_ desde la propiedad `hero.name` al cuadro de texto y desde el cuadro de texto a la propiedad `hero.name`.
|
||||
|
||||
### The missing _FormsModule_
|
||||
### _FormsModule_ No encontrado
|
||||
|
||||
Notice that the app stopped working when you added `[(ngModel)]`.
|
||||
Observa que la aplicación dejó de funcionar cuando agregué el `[(ngModel)]`.
|
||||
|
||||
To see the error, open the browser development tools and look in the console
|
||||
for a message like
|
||||
Para ver el error, abre las herramientas de desarrollo de su navegador,
|
||||
Busca mensajes como el siguiente en la consola,
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
Template parse errors:
|
||||
Can't bind to 'ngModel' since it isn't a known property of 'input'.
|
||||
Errores de análisis de plantilla:
|
||||
No se puede vincular a 'nGModelo' ya que no es una propiedad conocida de 'entrada'.
|
||||
</code-example>
|
||||
|
||||
Although `ngModel` is a valid Angular directive, it isn't available by default.
|
||||
`ngModel` Es una directiva angular válida pero no está disponible por defecto.
|
||||
|
||||
It belongs to the optional `FormsModule` and you must _opt-in_ to using it.
|
||||
Pertenece al `FormsModule` opcional y debe optar por ese módulo para usarlo.
|
||||
|
||||
## _AppModule_
|
||||
|
||||
Angular needs to know how the pieces of your application fit together
|
||||
and what other files and libraries the app requires.
|
||||
This information is called _metadata_.
|
||||
En Angular, cómo encajan las partes de la aplicación,
|
||||
Necesita saber qué otros archivos y bibliotecas necesita su aplicación.
|
||||
Esta información se llama _metadata_.
|
||||
|
||||
Some of the metadata is in the `@Component` decorators that you added to your component classes.
|
||||
Other critical metadata is in [`@NgModule`](guide/ngmodules) decorators.
|
||||
Algunos de los metadatos se encuentran en el decorador `@Component` que agregó a su clase de componentes.
|
||||
Otros metadatos importantes son[`@NgModule`](guide/ngmodules)Está en el decorador.
|
||||
|
||||
The most important `@NgModule` decorator annotates the top-level **AppModule** class.
|
||||
El decorador más importante `@NgModule` anota la clase **AppModule** de nivel superior.
|
||||
|
||||
The Angular CLI generated an `AppModule` class in `src/app/app.module.ts` when it created the project.
|
||||
This is where you _opt-in_ to the `FormsModule`.
|
||||
Angular CLI creó la clase `AppModule` en `src/app/app.module.ts` al crear el proyecto.
|
||||
Ahora opta por el `FormsModule`.
|
||||
|
||||
### Import _FormsModule_
|
||||
### Importar _FormsModule_
|
||||
|
||||
Open `AppModule` (`app.module.ts`) and import the `FormsModule` symbol from the `@angular/forms` library.
|
||||
Abre `AppModule` (`app.module.ts`) e importe el símbolo `FormsModule` desde la biblioteca `@angular/forms`.
|
||||
|
||||
<code-example path="toh-pt1/src/app/app.module.ts" header="app.module.ts (FormsModule symbol import)"
|
||||
<code-example path="toh-pt1/src/app/app.module.ts" header="app.module.ts (@NgModule imports)"
|
||||
region="formsmodule-js-import">
|
||||
</code-example>
|
||||
|
||||
Then add `FormsModule` to the `@NgModule` metadata's `imports` array, which contains a list of external modules that the app needs.
|
||||
A continuación, agregue el `FormsModule` a el arreglo `imports` de los metadatos `@ NgModule`.
|
||||
Esta matriz contiene una lista de módulos externos que requiere su aplicación.
|
||||
|
||||
<code-example path="toh-pt1/src/app/app.module.ts" header="app.module.ts (@NgModule imports)"
|
||||
<code-example path="toh-pt1/src/app/app.module.ts" header="app.module.ts ( @NgModule imports)"
|
||||
region="ng-imports">
|
||||
</code-example>
|
||||
|
||||
When the browser refreshes, the app should work again. You can edit the hero's name and see the changes reflected immediately in the `<h2>` above the textbox.
|
||||
La aplicación debería funcionar nuevamente cuando se actualice el navegador. Puedes editar el nombre del héroe y ver los cambios reflejados inmediatamente en el `<h2>` arriba del cuadro de texto.
|
||||
|
||||
### Declare `HeroesComponent`
|
||||
### Declarar `HeroesComponent`
|
||||
|
||||
Every component must be declared in _exactly one_ [NgModule](guide/ngmodules).
|
||||
Todos los componentes deben declararse con _exactamente uno_ [NgModule](guide/ngmodules).
|
||||
|
||||
_You_ didn't declare the `HeroesComponent`.
|
||||
So why did the application work?
|
||||
_No has declarado_ HeroesComponent`.
|
||||
Entonces, ¿por qué funcionó la aplicación?
|
||||
|
||||
It worked because the Angular CLI declared `HeroesComponent` in the `AppModule` when it generated that component.
|
||||
La aplicación funcionó porque Angular CLI declaró el componente en el `AppModule` cuando generó el `HeroesComponent`.
|
||||
|
||||
Abra `src/app/app.module.ts` y encuentre el `HeroesComponent` importado cerca de la parte superior.
|
||||
|
||||
Open `src/app/app.module.ts` and find `HeroesComponent` imported near the top.
|
||||
<code-example path="toh-pt1/src/app/app.module.ts" header="src/app/app.module.ts" region="heroes-import" >
|
||||
</code-example>
|
||||
|
||||
The `HeroesComponent` is declared in the `@NgModule.declarations` array.
|
||||
`HeroesComponent` se declara en la matriz`@NgModule.declarations`.
|
||||
<code-example path="toh-pt1/src/app/app.module.ts" header="src/app/app.module.ts" region="declarations">
|
||||
</code-example>
|
||||
|
||||
Note that `AppModule` declares both application components, `AppComponent` and `HeroesComponent`.
|
||||
`AppModule` declara los componentes de aplicación `AppComponent` y `HeroesComponent`.
|
||||
|
||||
## Revisión del código final
|
||||
|
||||
## Final code review
|
||||
|
||||
Here are the code files discussed on this page.
|
||||
Los archivos de código descritos en esta página son:
|
||||
|
||||
<code-tabs>
|
||||
|
||||
@ -217,7 +217,7 @@ Here are the code files discussed on this page.
|
||||
<code-pane header="src/app/heroes/heroes.component.html" path="toh-pt1/src/app/heroes/heroes.component.html">
|
||||
</code-pane>
|
||||
|
||||
<code-pane header="src/app/app.module.ts"
|
||||
<code-pane header="src/app/app.module.ts"
|
||||
path="toh-pt1/src/app/app.module.ts">
|
||||
</code-pane>
|
||||
|
||||
@ -232,14 +232,12 @@ Here are the code files discussed on this page.
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
## Resumen
|
||||
|
||||
## Summary
|
||||
|
||||
* You used the CLI to create a second `HeroesComponent`.
|
||||
* You displayed the `HeroesComponent` by adding it to the `AppComponent` shell.
|
||||
* You applied the `UppercasePipe` to format the name.
|
||||
* You used two-way data binding with the `ngModel` directive.
|
||||
* You learned about the `AppModule`.
|
||||
* You imported the `FormsModule` in the `AppModule` so that Angular would recognize and apply the `ngModel` directive.
|
||||
* You learned the importance of declaring components in the `AppModule`
|
||||
and appreciated that the CLI declared it for you.
|
||||
* Creo un segundo `HeroesComponent` usando el CLI.
|
||||
* Agregó `HeroesComponent` al shell de `AppComponent` y lo mostró.
|
||||
* Aplico 'UppercasePipe' para formatear el nombre.
|
||||
* Utilizo el enlace de datos bidireccional en la directiva `ngModel`.
|
||||
* Aprendío sobre `AppModule`.
|
||||
* Importó `FormsModule` en `AppModule` para reconocer y aplicar la directiva Angular `ngModel`.
|
||||
* Aprendío la importancia de declarar un componente en un `AppModule` y me di cuenta de que la CLI está haciendo esa declaración por usted.
|
||||
|
173
aio/content/tutorial/toh-pt3.en.md
Normal file
173
aio/content/tutorial/toh-pt3.en.md
Normal file
@ -0,0 +1,173 @@
|
||||
# Create a feature component
|
||||
|
||||
At the moment, the `HeroesComponent` displays both the list of heroes and the selected hero's details.
|
||||
|
||||
Keeping all features in one component as the application grows will not be maintainable.
|
||||
You'll want to split up large components into smaller sub-components, each focused on a specific task or workflow.
|
||||
|
||||
In this page, you'll take the first step in that direction by moving the hero details into a separate, reusable `HeroDetailComponent`.
|
||||
|
||||
The `HeroesComponent` will only present the list of heroes.
|
||||
The `HeroDetailComponent` will present details of a selected hero.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For the sample app that this page describes, see the <live-example></live-example>.
|
||||
|
||||
</div>
|
||||
|
||||
## Make the `HeroDetailComponent`
|
||||
|
||||
Use the Angular CLI to generate a new component named `hero-detail`.
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
ng generate component hero-detail
|
||||
</code-example>
|
||||
|
||||
The command scaffolds the following:
|
||||
|
||||
* Creates a directory `src/app/hero-detail`.
|
||||
|
||||
Inside that directory four files are generated:
|
||||
|
||||
* A CSS file for the component styles.
|
||||
* An HTML file for the component template.
|
||||
* A TypeScript file with a component class named `HeroDetailComponent`.
|
||||
* A test file for the `HeroDetailComponent` class.
|
||||
|
||||
The command also adds the `HeroDetailComponent` as a declaration in the `@NgModule` decorator of the `src/app/app.module.ts` file.
|
||||
|
||||
|
||||
### Write the template
|
||||
|
||||
Cut the HTML for the hero detail from the bottom of the `HeroesComponent` template and paste it over the generated boilerplate in the `HeroDetailComponent` template.
|
||||
|
||||
The pasted HTML refers to a `selectedHero`.
|
||||
The new `HeroDetailComponent` can present _any_ hero, not just a selected hero.
|
||||
So replace "selectedHero" with "hero" everywhere in the template.
|
||||
|
||||
When you're done, the `HeroDetailComponent` template should look like this:
|
||||
|
||||
<code-example path="toh-pt3/src/app/hero-detail/hero-detail.component.html" header="src/app/hero-detail/hero-detail.component.html"></code-example>
|
||||
|
||||
### Add the `@Input()` hero property
|
||||
|
||||
The `HeroDetailComponent` template binds to the component's `hero` property
|
||||
which is of type `Hero`.
|
||||
|
||||
Open the `HeroDetailComponent` class file and import the `Hero` symbol.
|
||||
|
||||
<code-example path="toh-pt3/src/app/hero-detail/hero-detail.component.ts"
|
||||
region="import-hero" header="src/app/hero-detail/hero-detail.component.ts (import Hero)">
|
||||
</code-example>
|
||||
|
||||
The `hero` property
|
||||
[must be an _Input_ property](guide/inputs-outputs "Input and Output properties"),
|
||||
annotated with the `@Input()` decorator,
|
||||
because the _external_ `HeroesComponent` [will bind to it](#heroes-component-template) like this.
|
||||
|
||||
<code-example path="toh-pt3/src/app/heroes/heroes.component.html" region="hero-detail-binding">
|
||||
</code-example>
|
||||
|
||||
Amend the `@angular/core` import statement to include the `Input` symbol.
|
||||
|
||||
<code-example path="toh-pt3/src/app/hero-detail/hero-detail.component.ts" region="import-input" header="src/app/hero-detail/hero-detail.component.ts (import Input)"></code-example>
|
||||
|
||||
Add a `hero` property, preceded by the `@Input()` decorator.
|
||||
|
||||
<code-example path="toh-pt3/src/app/hero-detail/hero-detail.component.ts" header="src/app/hero-detail/hero-detail.component.ts" region="input-hero"></code-example>
|
||||
|
||||
That's the only change you should make to the `HeroDetailComponent` class.
|
||||
There are no more properties. There's no presentation logic.
|
||||
This component simply receives a hero object through its `hero` property and displays it.
|
||||
|
||||
## Show the `HeroDetailComponent`
|
||||
|
||||
The `HeroesComponent` is still a master/detail view.
|
||||
|
||||
It used to display the hero details on its own, before you cut that portion of the template. Now it will delegate to the `HeroDetailComponent`.
|
||||
|
||||
The two components will have a parent/child relationship.
|
||||
The parent `HeroesComponent` will control the child `HeroDetailComponent`
|
||||
by sending it a new hero to display whenever
|
||||
the user selects a hero from the list.
|
||||
|
||||
You won't change the `HeroesComponent` _class_ but you will change its _template_.
|
||||
|
||||
{@a heroes-component-template}
|
||||
|
||||
### Update the `HeroesComponent` template
|
||||
|
||||
The `HeroDetailComponent` selector is `'app-hero-detail'`.
|
||||
Add an `<app-hero-detail>` element near the bottom of the `HeroesComponent` template, where the hero detail view used to be.
|
||||
|
||||
Bind the `HeroesComponent.selectedHero` to the element's `hero` property like this.
|
||||
|
||||
<code-example path="toh-pt3/src/app/heroes/heroes.component.html" region="hero-detail-binding" header="heroes.component.html (HeroDetail binding)">
|
||||
|
||||
</code-example>
|
||||
|
||||
`[hero]="selectedHero"` is an Angular [property binding](guide/property-binding).
|
||||
|
||||
It's a _one way_ data binding from
|
||||
the `selectedHero` property of the `HeroesComponent` to the `hero` property of the target element, which maps to the `hero` property of the `HeroDetailComponent`.
|
||||
|
||||
Now when the user clicks a hero in the list, the `selectedHero` changes.
|
||||
When the `selectedHero` changes, the _property binding_ updates `hero`
|
||||
and the `HeroDetailComponent` displays the new hero.
|
||||
|
||||
The revised `HeroesComponent` template should look like this:
|
||||
|
||||
<code-example path="toh-pt3/src/app/heroes/heroes.component.html"
|
||||
header="heroes.component.html"></code-example>
|
||||
|
||||
The browser refreshes and the app starts working again as it did before.
|
||||
|
||||
## What changed?
|
||||
|
||||
As [before](tutorial/toh-pt2), whenever a user clicks on a hero name,
|
||||
the hero detail appears below the hero list.
|
||||
Now the `HeroDetailComponent` is presenting those details instead of the `HeroesComponent`.
|
||||
|
||||
Refactoring the original `HeroesComponent` into two components yields benefits, both now and in the future:
|
||||
|
||||
1. You simplified the `HeroesComponent` by reducing its responsibilities.
|
||||
|
||||
1. You can evolve the `HeroDetailComponent` into a rich hero editor
|
||||
without touching the parent `HeroesComponent`.
|
||||
|
||||
1. You can evolve the `HeroesComponent` without touching the hero detail view.
|
||||
|
||||
1. You can re-use the `HeroDetailComponent` in the template of some future component.
|
||||
|
||||
## Final code review
|
||||
|
||||
Here are the code files discussed on this page.
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane header="src/app/hero-detail/hero-detail.component.ts" path="toh-pt3/src/app/hero-detail/hero-detail.component.ts">
|
||||
</code-pane>
|
||||
|
||||
<code-pane header="src/app/hero-detail/hero-detail.component.html" path="toh-pt3/src/app/hero-detail/hero-detail.component.html">
|
||||
</code-pane>
|
||||
|
||||
<code-pane header="src/app/heroes/heroes.component.html" path="toh-pt3/src/app/heroes/heroes.component.html">
|
||||
</code-pane>
|
||||
|
||||
<code-pane header="src/app/app.module.ts" path="toh-pt3/src/app/app.module.ts">
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
## Summary
|
||||
|
||||
* You created a separate, reusable `HeroDetailComponent`.
|
||||
|
||||
|
||||
* You used a [property binding](guide/property-binding) to give the parent `HeroesComponent` control over the child `HeroDetailComponent`.
|
||||
|
||||
|
||||
* You used the [`@Input` decorator](guide/inputs-outputs)
|
||||
to make the `hero` property available for binding
|
||||
by the external `HeroesComponent`.
|
@ -1,148 +1,140 @@
|
||||
# Create a feature component
|
||||
# Crear un componente de características
|
||||
|
||||
At the moment, the `HeroesComponent` displays both the list of heroes and the selected hero's details.
|
||||
Por el momento, el `HeroesComponent` muestra tanto la lista de héroes como los detalles de los héroes seleccionados.
|
||||
|
||||
Keeping all features in one component as the application grows will not be maintainable.
|
||||
You'll want to split up large components into smaller sub-components, each focused on a specific task or workflow.
|
||||
Mantener toda la funcionalidad en un componente se vuelve menos sostenible a medida que la aplicación crece.
|
||||
Deberá dividir un componente grande en subcomponentes más pequeños que se centren en una tarea o flujo de trabajo en particular.
|
||||
|
||||
In this page, you'll take the first step in that direction by moving the hero details into a separate, reusable `HeroDetailComponent`.
|
||||
Esta página da el primer paso en ese camino moviendo los detalles del héroe a otro `HeroDetailComponent` reutilizable.
|
||||
|
||||
The `HeroesComponent` will only present the list of heroes.
|
||||
The `HeroDetailComponent` will present details of a selected hero.
|
||||
`HeroesComponent` solo muestra una lista de héroes.
|
||||
`HeroDetailComponent` muestra los detalles del héroe seleccionado.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For the sample app that this page describes, see the <live-example></live-example>.
|
||||
Para ver la aplicación de ejemplo que describe esta página, consulte el <live-example></live-example>.
|
||||
|
||||
</div>
|
||||
|
||||
## Make the `HeroDetailComponent`
|
||||
## Crear `HeroDetailComponent`
|
||||
|
||||
Use the Angular CLI to generate a new component named `hero-detail`.
|
||||
Usa el CLI de Angular para generar un nuevo componente llamado `hero-detail`.
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
ng generate component hero-detail
|
||||
</code-example>
|
||||
|
||||
The command scaffolds the following:
|
||||
Este comando generará una plantilla para el archivo `HeroDetailComponent` y declarará este componente en el `AppModule`.
|
||||
Este comando produce la siguiente plantilla:
|
||||
|
||||
* Creates a directory `src/app/hero-detail`.
|
||||
* Crear el directorio `src/app/hero-detail`
|
||||
|
||||
Inside that directory four files are generated:
|
||||
Genera cuatro archivos en este directorio:
|
||||
|
||||
* A CSS file for the component styles.
|
||||
* An HTML file for the component template.
|
||||
* A TypeScript file with a component class named `HeroDetailComponent`.
|
||||
* A test file for the `HeroDetailComponent` class.
|
||||
* Archivo CSS para estilo de componente
|
||||
* Archivo HTML para la plantilla el componente
|
||||
* Archivo TypeScript de la clase de componente denominada `HeroDetailComponent`
|
||||
* Archivo de prueba de la clase `HeroDetailComponent`
|
||||
|
||||
The command also adds the `HeroDetailComponent` as a declaration in the `@NgModule` decorator of the `src/app/app.module.ts` file.
|
||||
Este comando también agrega `HeroDetailComponent` como `declaraciones` en el decorador `@ NgModule` del archivo `src/app/app.module.ts`.
|
||||
|
||||
### Escribir plantilla
|
||||
|
||||
### Write the template
|
||||
Corta el HTML de detalles del héroe desde la parte inferior de la plantilla `HeroesComponent` y pégalo en la plantilla generada en las plantilla `HeroDetailComponent`.
|
||||
|
||||
Cut the HTML for the hero detail from the bottom of the `HeroesComponent` template and paste it over the generated boilerplate in the `HeroDetailComponent` template.
|
||||
Las referencias HTML pegadas `selectedHero`.
|
||||
El nuevo `HeroDetailComponent` puede mostrar _cualquier_héroe, no solo el héroe seleccionado.
|
||||
Por lo tanto, reemplaza todos los "selectedHero" en la plantilla con "hero".
|
||||
|
||||
The pasted HTML refers to a `selectedHero`.
|
||||
The new `HeroDetailComponent` can present _any_ hero, not just a selected hero.
|
||||
So replace "selectedHero" with "hero" everywhere in the template.
|
||||
|
||||
When you're done, the `HeroDetailComponent` template should look like this:
|
||||
Cuando termines, las plantilla `HeroDetailComponent` deberían verse así:
|
||||
|
||||
<code-example path="toh-pt3/src/app/hero-detail/hero-detail.component.html" header="src/app/hero-detail/hero-detail.component.html"></code-example>
|
||||
|
||||
### Add the `@Input()` hero property
|
||||
### Añadir la propiedad `@Input()` al héroe
|
||||
|
||||
The `HeroDetailComponent` template binds to the component's `hero` property
|
||||
which is of type `Hero`.
|
||||
Las plantillas `HeroDetailComponent` están vinculadas a la propiedad `hero` de un componente que es del tipo `Hero`.
|
||||
|
||||
Open the `HeroDetailComponent` class file and import the `Hero` symbol.
|
||||
Abre el archivo de clase `HeroDetailComponent` e importe el símbolo `Hero`.
|
||||
|
||||
<code-example path="toh-pt3/src/app/hero-detail/hero-detail.component.ts"
|
||||
<code-example path="toh-pt3/src/app/hero-detail/hero-detail.component.ts"
|
||||
region="import-hero" header="src/app/hero-detail/hero-detail.component.ts (import Hero)">
|
||||
</code-example>
|
||||
|
||||
The `hero` property
|
||||
[must be an _Input_ property](guide/inputs-outputs "Input and Output properties"),
|
||||
annotated with the `@Input()` decorator,
|
||||
because the _external_ `HeroesComponent` [will bind to it](#heroes-component-template) like this.
|
||||
La propiedad `hero` debe ser una [_propiedad de entrada_](guide/inputs-outputs "Input and Output properties") -->, anotada con el decorador `@Input()` porque el `HeroesComponent` _externo_ [se vinculará de esta manera.](#heroes-component-template)
|
||||
|
||||
<code-example path="toh-pt3/src/app/heroes/heroes.component.html" region="hero-detail-binding">
|
||||
</code-example>
|
||||
|
||||
Amend the `@angular/core` import statement to include the `Input` symbol.
|
||||
Modifique la declaración de importación `@angular/core` para incluir el símbolo `Input`.
|
||||
|
||||
<code-example path="toh-pt3/src/app/hero-detail/hero-detail.component.ts" region="import-input" header="src/app/hero-detail/hero-detail.component.ts (import Input)"></code-example>
|
||||
|
||||
Add a `hero` property, preceded by the `@Input()` decorator.
|
||||
Agrega la propiedad `hero` antepuesta por el decorador `@Input()`.
|
||||
|
||||
<code-example path="toh-pt3/src/app/hero-detail/hero-detail.component.ts" header="src/app/hero-detail/hero-detail.component.ts" region="input-hero"></code-example>
|
||||
|
||||
That's the only change you should make to the `HeroDetailComponent` class.
|
||||
There are no more properties. There's no presentation logic.
|
||||
This component simply receives a hero object through its `hero` property and displays it.
|
||||
Este es el único cambio que debe realizar en la clase `HeroDetailComponent`.
|
||||
No se requieren más propiedades o lógica de visualización.
|
||||
Este componente solo toma un objeto héroe a través de la propiedad `hero` y lo muestra.
|
||||
|
||||
## Show the `HeroDetailComponent`
|
||||
## Mostrar `HeroDetailComponent`
|
||||
|
||||
The `HeroesComponent` is still a master/detail view.
|
||||
El `HeroesComponent` todavía está en la vista maestra/detalle.
|
||||
|
||||
It used to display the hero details on its own, before you cut that portion of the template. Now it will delegate to the `HeroDetailComponent`.
|
||||
Hasta que eliminé los detalles del héroe de Plantillas, lo estaba mostrando en este componente. Ahora deleguemos a `HeroDetailComponent`.
|
||||
|
||||
The two components will have a parent/child relationship.
|
||||
The parent `HeroesComponent` will control the child `HeroDetailComponent`
|
||||
by sending it a new hero to display whenever
|
||||
the user selects a hero from the list.
|
||||
Los dos componentes tienen una relación padre-hijo.
|
||||
Para mostrar un nuevo héroe cada vez que el usuario selecciona un héroe de la lista,
|
||||
El padre `HeroesComponent` controla al hijo `HeroDetailComponent` enviándolo.
|
||||
|
||||
You won't change the `HeroesComponent` _class_ but you will change its _template_.
|
||||
No cambiarás la _clase_ de `HeroesComponent` pero cambiarás su _template_.
|
||||
|
||||
{@a heroes-component-template}
|
||||
|
||||
### Update the `HeroesComponent` template
|
||||
### Actualizar las plantillas `HeroesComponent`
|
||||
|
||||
The `HeroDetailComponent` selector is `'app-hero-detail'`.
|
||||
Add an `<app-hero-detail>` element near the bottom of the `HeroesComponent` template, where the hero detail view used to be.
|
||||
El selector para `HeroDetailComponent` es `'app-hero-detail'`.
|
||||
|
||||
Bind the `HeroesComponent.selectedHero` to the element's `hero` property like this.
|
||||
Agrega un elemento `<app-hero-detail>` a la parte inferior de las plantillas `HeroesComponent` donde la vista detallada de héroe existió una vez.
|
||||
|
||||
Vincula `HeroesComponent.selectedHero` a la propiedad `hero` de este elemento de la siguiente manera:
|
||||
|
||||
<code-example path="toh-pt3/src/app/heroes/heroes.component.html" region="hero-detail-binding" header="heroes.component.html (HeroDetail binding)">
|
||||
|
||||
</code-example>
|
||||
|
||||
`[hero]="selectedHero"` is an Angular [property binding](guide/property-binding).
|
||||
`[hero]="selectedHero"` es el [enlace de propiedad](guide/property-binding) de Angular.
|
||||
|
||||
It's a _one way_ data binding from
|
||||
the `selectedHero` property of the `HeroesComponent` to the `hero` property of the target element, which maps to the `hero` property of the `HeroDetailComponent`.
|
||||
Este es un enlace de datos unidireccional de la propiedad `selectedHero` `HeroesComponent` a la propiedad `hero` del elemento objetivo.
|
||||
Aquí se asigna la propiedad `hero` de `HeroDetailComponent`.
|
||||
|
||||
Now when the user clicks a hero in the list, the `selectedHero` changes.
|
||||
When the `selectedHero` changes, the _property binding_ updates `hero`
|
||||
and the `HeroDetailComponent` displays the new hero.
|
||||
Cuando el usuario hace clic en un héroe en la lista, el `selectedHero` cambia.
|
||||
Cuando `selectedHero` cambia,el _enlace de propiedad_ actualiza `hero` y
|
||||
`HeroDetailComponent` muestra el nuevo héroe.
|
||||
|
||||
The revised `HeroesComponent` template should look like this:
|
||||
La plantilla modificada de `HeroesComponent` se ve así:
|
||||
|
||||
<code-example path="toh-pt3/src/app/heroes/heroes.component.html"
|
||||
header="heroes.component.html"></code-example>
|
||||
|
||||
The browser refreshes and the app starts working again as it did before.
|
||||
Una vez que se actualiza el navegador, la aplicación comenzará a funcionar nuevamente como antes.
|
||||
|
||||
## What changed?
|
||||
## ¿Que ha cambiado?
|
||||
|
||||
As [before](tutorial/toh-pt2), whenever a user clicks on a hero name,
|
||||
the hero detail appears below the hero list.
|
||||
Now the `HeroDetailComponent` is presenting those details instead of the `HeroesComponent`.
|
||||
[Como antes](tutorial/toh-pt2), cada vez que un usuario hace clic en el nombre de un héroe, el detalle del héroe aparece debajo de la lista de héroes. Ahora HeroDetailComponent presenta esos detalles en lugar de HeroesComponent.
|
||||
|
||||
Refactoring the original `HeroesComponent` into two components yields benefits, both now and in the future:
|
||||
Refactorizar el `HeroesComponent` original en dos componentes te beneficiará ahora y en el futuro.
|
||||
|
||||
1. You simplified the `HeroesComponent` by reducing its responsibilities.
|
||||
1. Simplificado `HeroesComponent` al reducir su responsabilidad.
|
||||
|
||||
1. You can evolve the `HeroDetailComponent` into a rich hero editor
|
||||
without touching the parent `HeroesComponent`.
|
||||
1. Puedes convertir un `HeroDetailComponent` en un editor enriquecido de héroes sin tocar el padre `HeroesComponent` principal.
|
||||
|
||||
1. You can evolve the `HeroesComponent` without touching the hero detail view.
|
||||
1. Puedes evolucionar `HeroesComponent` sin tocar la vista de detalles del héroe.
|
||||
|
||||
1. You can re-use the `HeroDetailComponent` in the template of some future component.
|
||||
1. Puedes reutilizar `HeroDetailComponent` en futuros componentes de Plantillas.
|
||||
|
||||
## Final code review
|
||||
## Revisión final del código
|
||||
|
||||
Here are the code files discussed on this page.
|
||||
Los archivos de código descritos en esta página son:
|
||||
|
||||
<code-tabs>
|
||||
|
||||
@ -160,14 +152,10 @@ Here are the code files discussed on this page.
|
||||
|
||||
</code-tabs>
|
||||
|
||||
## Summary
|
||||
## Resumen
|
||||
|
||||
* You created a separate, reusable `HeroDetailComponent`.
|
||||
* Creaste un `HeroDetailComponent` independiente y reutilizable.
|
||||
|
||||
* Usaste el [enlace de propiedad](guide/property-binding) para que el padre `HeroesComponent` pueda controlar al hijo `HeroDetailComponent`.
|
||||
|
||||
* You used a [property binding](guide/property-binding) to give the parent `HeroesComponent` control over the child `HeroDetailComponent`.
|
||||
|
||||
|
||||
* You used the [`@Input` decorator](guide/inputs-outputs)
|
||||
to make the `hero` property available for binding
|
||||
by the external `HeroesComponent`.
|
||||
* Usaste el [`decorador @Input`](guide/inputs-outputs) para hacer que la propiedad del héroe esté disponible para ser vinculada por el componente `HeroesComponent` externamente.
|
||||
|
446
aio/content/tutorial/toh-pt4.en.md
Normal file
446
aio/content/tutorial/toh-pt4.en.md
Normal file
@ -0,0 +1,446 @@
|
||||
# Add services
|
||||
|
||||
The Tour of Heroes `HeroesComponent` is currently getting and displaying fake data.
|
||||
|
||||
After the refactoring in this tutorial, `HeroesComponent` will be lean and focused on supporting the view.
|
||||
It will also be easier to unit-test with a mock service.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For the sample app that this page describes, see the <live-example></live-example>.
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
## Why services
|
||||
|
||||
Components shouldn't fetch or save data directly and they certainly shouldn't knowingly present fake data.
|
||||
They should focus on presenting data and delegate data access to a service.
|
||||
|
||||
In this tutorial, you'll create a `HeroService` that all application classes can use to get heroes.
|
||||
Instead of creating that service with the [`new` keyword](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new),
|
||||
you'll rely on Angular [*dependency injection*](guide/dependency-injection)
|
||||
to inject it into the `HeroesComponent` constructor.
|
||||
|
||||
Services are a great way to share information among classes that _don't know each other_.
|
||||
You'll create a `MessageService` and inject it in two places.
|
||||
|
||||
1. Inject in HeroService, which uses the service to send a message.
|
||||
2. Inject in MessagesComponent, which displays that message, and also displays the ID
|
||||
when the user clicks a hero.
|
||||
|
||||
|
||||
## Create the `HeroService`
|
||||
|
||||
Using the Angular CLI, create a service called `hero`.
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
ng generate service hero
|
||||
</code-example>
|
||||
|
||||
The command generates a skeleton `HeroService` class in `src/app/hero.service.ts` as follows:
|
||||
|
||||
<code-example path="toh-pt4/src/app/hero.service.1.ts" region="new"
|
||||
header="src/app/hero.service.ts (new service)"></code-example>
|
||||
|
||||
|
||||
### `@Injectable()` services
|
||||
|
||||
Notice that the new service imports the Angular `Injectable` symbol and annotates
|
||||
the class with the `@Injectable()` decorator. This marks the class as one that participates in the _dependency injection system_. The `HeroService` class is going to provide an injectable service, and it can also have its own injected dependencies.
|
||||
It doesn't have any dependencies yet, but [it will soon](#inject-message-service).
|
||||
|
||||
The `@Injectable()` decorator accepts a metadata object for the service, the same way the `@Component()` decorator did for your component classes.
|
||||
|
||||
### Get hero data
|
||||
|
||||
The `HeroService` could get hero data from anywhere—a web service, local storage, or a mock data source.
|
||||
|
||||
Removing data access from components means you can change your mind about the implementation anytime, without touching any components.
|
||||
They don't know how the service works.
|
||||
|
||||
The implementation in _this_ tutorial will continue to deliver _mock heroes_.
|
||||
|
||||
Import the `Hero` and `HEROES`.
|
||||
|
||||
<code-example path="toh-pt4/src/app/hero.service.ts" header="src/app/hero.service.ts" region="import-heroes">
|
||||
</code-example>
|
||||
|
||||
Add a `getHeroes` method to return the _mock heroes_.
|
||||
|
||||
<code-example path="toh-pt4/src/app/hero.service.1.ts" header="src/app/hero.service.ts" region="getHeroes">
|
||||
</code-example>
|
||||
|
||||
{@a provide}
|
||||
## Provide the `HeroService`
|
||||
|
||||
You must make the `HeroService` available to the dependency injection system
|
||||
before Angular can _inject_ it into the `HeroesComponent` by registering a _provider_. A provider is something that can create or deliver a service; in this case, it instantiates the `HeroService` class to provide the service.
|
||||
|
||||
To make sure that the `HeroService` can provide this service, register it
|
||||
with the _injector_, which is the object that is responsible for choosing
|
||||
and injecting the provider where the app requires it.
|
||||
|
||||
By default, the Angular CLI command `ng generate service` registers a provider with the _root injector_ for your service by including provider metadata, that is `providedIn: 'root'` in the `@Injectable()` decorator.
|
||||
|
||||
```
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
```
|
||||
|
||||
When you provide the service at the root level, Angular creates a single, shared instance of `HeroService` and injects into any class that asks for it.
|
||||
Registering the provider in the `@Injectable` metadata also allows Angular to optimize an app by removing the service if it turns out not to be used after all.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
To learn more about providers, see the [Providers section](guide/providers).
|
||||
To learn more about injectors, see the [Dependency Injection guide](guide/dependency-injection).
|
||||
|
||||
</div>
|
||||
|
||||
The `HeroService` is now ready to plug into the `HeroesComponent`.
|
||||
|
||||
<div class="alert is-important">
|
||||
|
||||
This is an interim code sample that will allow you to provide and use the `HeroService`. At this point, the code will differ from the `HeroService` in the ["final code review"](#final-code-review).
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
## Update `HeroesComponent`
|
||||
|
||||
Open the `HeroesComponent` class file.
|
||||
|
||||
Delete the `HEROES` import, because you won't need that anymore.
|
||||
Import the `HeroService` instead.
|
||||
|
||||
<code-example path="toh-pt4/src/app/heroes/heroes.component.ts" header="src/app/heroes/heroes.component.ts (import HeroService)" region="hero-service-import">
|
||||
</code-example>
|
||||
|
||||
Replace the definition of the `heroes` property with a simple declaration.
|
||||
|
||||
<code-example path="toh-pt4/src/app/heroes/heroes.component.ts" header="src/app/heroes/heroes.component.ts" region="heroes">
|
||||
</code-example>
|
||||
|
||||
{@a inject}
|
||||
|
||||
### Inject the `HeroService`
|
||||
|
||||
Add a private `heroService` parameter of type `HeroService` to the constructor.
|
||||
|
||||
<code-example path="toh-pt4/src/app/heroes/heroes.component.1.ts" header="src/app/heroes/heroes.component.ts" region="ctor">
|
||||
</code-example>
|
||||
|
||||
The parameter simultaneously defines a private `heroService` property and identifies it as a `HeroService` injection site.
|
||||
|
||||
When Angular creates a `HeroesComponent`, the [Dependency Injection](guide/dependency-injection) system
|
||||
sets the `heroService` parameter to the singleton instance of `HeroService`.
|
||||
|
||||
### Add `getHeroes()`
|
||||
|
||||
Create a method to retrieve the heroes from the service.
|
||||
|
||||
<code-example path="toh-pt4/src/app/heroes/heroes.component.1.ts" header="src/app/heroes/heroes.component.ts" region="getHeroes">
|
||||
</code-example>
|
||||
|
||||
{@a oninit}
|
||||
|
||||
### Call it in `ngOnInit()`
|
||||
|
||||
While you could call `getHeroes()` in the constructor, that's not the best practice.
|
||||
|
||||
Reserve the constructor for simple initialization such as wiring constructor parameters to properties.
|
||||
The constructor shouldn't _do anything_.
|
||||
It certainly shouldn't call a function that makes HTTP requests to a remote server as a _real_ data service would.
|
||||
|
||||
Instead, call `getHeroes()` inside the [*ngOnInit lifecycle hook*](guide/lifecycle-hooks) and
|
||||
let Angular call `ngOnInit()` at an appropriate time _after_ constructing a `HeroesComponent` instance.
|
||||
|
||||
<code-example path="toh-pt4/src/app/heroes/heroes.component.ts" header="src/app/heroes/heroes.component.ts" region="ng-on-init">
|
||||
</code-example>
|
||||
|
||||
### See it run
|
||||
|
||||
After the browser refreshes, the app should run as before,
|
||||
showing a list of heroes and a hero detail view when you click on a hero name.
|
||||
|
||||
## Observable data
|
||||
|
||||
The `HeroService.getHeroes()` method has a _synchronous signature_,
|
||||
which implies that the `HeroService` can fetch heroes synchronously.
|
||||
The `HeroesComponent` consumes the `getHeroes()` result
|
||||
as if heroes could be fetched synchronously.
|
||||
|
||||
<code-example path="toh-pt4/src/app/heroes/heroes.component.1.ts" header="src/app/heroes/heroes.component.ts" region="get-heroes">
|
||||
</code-example>
|
||||
|
||||
This will not work in a real app.
|
||||
You're getting away with it now because the service currently returns _mock heroes_.
|
||||
But soon the app will fetch heroes from a remote server,
|
||||
which is an inherently _asynchronous_ operation.
|
||||
|
||||
The `HeroService` must wait for the server to respond,
|
||||
`getHeroes()` cannot return immediately with hero data,
|
||||
and the browser will not block while the service waits.
|
||||
|
||||
`HeroService.getHeroes()` must have an _asynchronous signature_ of some kind.
|
||||
|
||||
In this tutorial, `HeroService.getHeroes()` will return an `Observable`
|
||||
because it will eventually use the Angular `HttpClient.get` method to fetch the heroes
|
||||
and [`HttpClient.get()` returns an `Observable`](guide/http).
|
||||
|
||||
### Observable `HeroService`
|
||||
|
||||
`Observable` is one of the key classes in the [RxJS library](http://reactivex.io/rxjs/).
|
||||
|
||||
In a [later tutorial on HTTP](tutorial/toh-pt6), you'll learn that Angular's `HttpClient` methods return RxJS `Observable`s.
|
||||
In this tutorial, you'll simulate getting data from the server with the RxJS `of()` function.
|
||||
|
||||
Open the `HeroService` file and import the `Observable` and `of` symbols from RxJS.
|
||||
|
||||
<code-example path="toh-pt4/src/app/hero.service.ts" header="src/app/hero.service.ts (Observable imports)" region="import-observable">
|
||||
</code-example>
|
||||
|
||||
Replace the `getHeroes()` method with the following:
|
||||
|
||||
<code-example path="toh-pt4/src/app/hero.service.ts" header="src/app/hero.service.ts" region="getHeroes-1"></code-example>
|
||||
|
||||
`of(HEROES)` returns an `Observable<Hero[]>` that emits _a single value_, the array of mock heroes.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
In the [HTTP tutorial](tutorial/toh-pt6), you'll call `HttpClient.get<Hero[]>()` which also returns an `Observable<Hero[]>` that emits _a single value_, an array of heroes from the body of the HTTP response.
|
||||
|
||||
</div>
|
||||
|
||||
### Subscribe in `HeroesComponent`
|
||||
|
||||
The `HeroService.getHeroes` method used to return a `Hero[]`.
|
||||
Now it returns an `Observable<Hero[]>`.
|
||||
|
||||
You'll have to adjust to that difference in `HeroesComponent`.
|
||||
|
||||
Find the `getHeroes` method and replace it with the following code
|
||||
(shown side-by-side with the previous version for comparison)
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane header="heroes.component.ts (Observable)"
|
||||
path="toh-pt4/src/app/heroes/heroes.component.ts" region="getHeroes">
|
||||
</code-pane>
|
||||
|
||||
<code-pane header="heroes.component.ts (Original)"
|
||||
path="toh-pt4/src/app/heroes/heroes.component.1.ts" region="getHeroes">
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
`Observable.subscribe()` is the critical difference.
|
||||
|
||||
The previous version assigns an array of heroes to the component's `heroes` property.
|
||||
The assignment occurs _synchronously_, as if the server could return heroes instantly
|
||||
or the browser could freeze the UI while it waited for the server's response.
|
||||
|
||||
That _won't work_ when the `HeroService` is actually making requests of a remote server.
|
||||
|
||||
The new version waits for the `Observable` to emit the array of heroes—which
|
||||
could happen now or several minutes from now.
|
||||
The `subscribe()` method passes the emitted array to the callback,
|
||||
which sets the component's `heroes` property.
|
||||
|
||||
This asynchronous approach _will work_ when
|
||||
the `HeroService` requests heroes from the server.
|
||||
|
||||
## Show messages
|
||||
|
||||
This section guides you through the following:
|
||||
|
||||
* adding a `MessagesComponent` that displays app messages at the bottom of the screen
|
||||
* creating an injectable, app-wide `MessageService` for sending messages to be displayed
|
||||
* injecting `MessageService` into the `HeroService`
|
||||
* displaying a message when `HeroService` fetches heroes successfully
|
||||
|
||||
### Create `MessagesComponent`
|
||||
|
||||
Use the CLI to create the `MessagesComponent`.
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
ng generate component messages
|
||||
</code-example>
|
||||
|
||||
The CLI creates the component files in the `src/app/messages` folder and declares the `MessagesComponent` in `AppModule`.
|
||||
|
||||
Modify the `AppComponent` template to display the generated `MessagesComponent`.
|
||||
|
||||
<code-example
|
||||
header = "src/app/app.component.html"
|
||||
path="toh-pt4/src/app/app.component.html">
|
||||
</code-example>
|
||||
|
||||
You should see the default paragraph from `MessagesComponent` at the bottom of the page.
|
||||
|
||||
### Create the `MessageService`
|
||||
|
||||
Use the CLI to create the `MessageService` in `src/app`.
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
ng generate service message
|
||||
</code-example>
|
||||
|
||||
Open `MessageService` and replace its contents with the following.
|
||||
|
||||
<code-example header = "src/app/message.service.ts" path="toh-pt4/src/app/message.service.ts">
|
||||
</code-example>
|
||||
|
||||
The service exposes its cache of `messages` and two methods: one to `add()` a message to the cache and another to `clear()` the cache.
|
||||
|
||||
{@a inject-message-service}
|
||||
### Inject it into the `HeroService`
|
||||
|
||||
In `HeroService`, import the `MessageService`.
|
||||
|
||||
<code-example
|
||||
header = "src/app/hero.service.ts (import MessageService)"
|
||||
path="toh-pt4/src/app/hero.service.ts" region="import-message-service">
|
||||
</code-example>
|
||||
|
||||
Modify the constructor with a parameter that declares a private `messageService` property.
|
||||
Angular will inject the singleton `MessageService` into that property
|
||||
when it creates the `HeroService`.
|
||||
|
||||
<code-example
|
||||
path="toh-pt4/src/app/hero.service.ts" header="src/app/hero.service.ts" region="ctor">
|
||||
</code-example>
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
This is a typical "*service-in-service*" scenario:
|
||||
you inject the `MessageService` into the `HeroService` which is injected into the `HeroesComponent`.
|
||||
|
||||
</div>
|
||||
|
||||
### Send a message from `HeroService`
|
||||
|
||||
Modify the `getHeroes()` method to send a message when the heroes are fetched.
|
||||
|
||||
<code-example path="toh-pt4/src/app/hero.service.ts" header="src/app/hero.service.ts" region="getHeroes">
|
||||
</code-example>
|
||||
|
||||
### Display the message from `HeroService`
|
||||
|
||||
The `MessagesComponent` should display all messages,
|
||||
including the message sent by the `HeroService` when it fetches heroes.
|
||||
|
||||
Open `MessagesComponent` and import the `MessageService`.
|
||||
|
||||
<code-example header="src/app/messages/messages.component.ts (import MessageService)" path="toh-pt4/src/app/messages/messages.component.ts" region="import-message-service">
|
||||
</code-example>
|
||||
|
||||
Modify the constructor with a parameter that declares a **public** `messageService` property.
|
||||
Angular will inject the singleton `MessageService` into that property
|
||||
when it creates the `MessagesComponent`.
|
||||
|
||||
<code-example path="toh-pt4/src/app/messages/messages.component.ts" header="src/app/messages/messages.component.ts" region="ctor">
|
||||
</code-example>
|
||||
|
||||
The `messageService` property **must be public** because you're going to bind to it in the template.
|
||||
|
||||
<div class="alert is-important">
|
||||
|
||||
Angular only binds to _public_ component properties.
|
||||
|
||||
</div>
|
||||
|
||||
### Bind to the `MessageService`
|
||||
|
||||
Replace the CLI-generated `MessagesComponent` template with the following.
|
||||
|
||||
<code-example
|
||||
header = "src/app/messages/messages.component.html"
|
||||
path="toh-pt4/src/app/messages/messages.component.html">
|
||||
</code-example>
|
||||
|
||||
This template binds directly to the component's `messageService`.
|
||||
|
||||
* The `*ngIf` only displays the messages area if there are messages to show.
|
||||
|
||||
|
||||
* An `*ngFor` presents the list of messages in repeated `<div>` elements.
|
||||
|
||||
|
||||
* An Angular [event binding](guide/event-binding) binds the button's click event
|
||||
to `MessageService.clear()`.
|
||||
|
||||
The messages will look better when you add the private CSS styles to `messages.component.css`
|
||||
as listed in one of the ["final code review"](#final-code-review) tabs below.
|
||||
|
||||
## Add additional messages to hero service
|
||||
|
||||
The following example shows how to send and display a message each time the user clicks on
|
||||
a hero, showing a history of the user's selections. This will be helpful when you get to the
|
||||
next section on [Routing](tutorial/toh-pt5).
|
||||
|
||||
<code-example header="src/app/heroes/heroes.component.ts"
|
||||
path="toh-pt4/src/app/heroes/heroes.component.ts">
|
||||
</code-example>
|
||||
|
||||
The browser refreshes and the page displays the list of heroes.
|
||||
Refresh the browser to see the list of heroes, and scroll to the bottom to see the
|
||||
messages from the HeroService. Each time you click a hero, a new message appears to record
|
||||
the selection. Use the "clear" button to clear the message history.
|
||||
|
||||
{@a final-code-review}
|
||||
|
||||
## Final code review
|
||||
|
||||
Here are the code files discussed on this page.
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane header="src/app/hero.service.ts"
|
||||
path="toh-pt4/src/app/hero.service.ts">
|
||||
</code-pane>
|
||||
|
||||
<code-pane header="src/app/message.service.ts"
|
||||
path="toh-pt4/src/app/message.service.ts">
|
||||
</code-pane>
|
||||
|
||||
<code-pane header="src/app/heroes/heroes.component.ts"
|
||||
path="toh-pt4/src/app/heroes/heroes.component.ts">
|
||||
</code-pane>
|
||||
|
||||
<code-pane header="src/app/messages/messages.component.ts"
|
||||
path="toh-pt4/src/app/messages/messages.component.ts">
|
||||
</code-pane>
|
||||
|
||||
<code-pane header="src/app/messages/messages.component.html"
|
||||
path="toh-pt4/src/app/messages/messages.component.html">
|
||||
</code-pane>
|
||||
|
||||
<code-pane header="src/app/messages/messages.component.css"
|
||||
path="toh-pt4/src/app/messages/messages.component.css">
|
||||
</code-pane>
|
||||
|
||||
<code-pane header="src/app/app.module.ts"
|
||||
path="toh-pt4/src/app/app.module.ts">
|
||||
</code-pane>
|
||||
|
||||
<code-pane header="src/app/app.component.html"
|
||||
path="toh-pt4/src/app/app.component.html">
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
## Summary
|
||||
|
||||
* You refactored data access to the `HeroService` class.
|
||||
* You registered the `HeroService` as the _provider_ of its service at the root level so that it can be injected anywhere in the app.
|
||||
* You used [Angular Dependency Injection](guide/dependency-injection) to inject it into a component.
|
||||
* You gave the `HeroService` _get data_ method an asynchronous signature.
|
||||
* You discovered `Observable` and the RxJS _Observable_ library.
|
||||
* You used RxJS `of()` to return an observable of mock heroes (`Observable<Hero[]>`).
|
||||
* The component's `ngOnInit` lifecycle hook calls the `HeroService` method, not the constructor.
|
||||
* You created a `MessageService` for loosely-coupled communication between classes.
|
||||
* The `HeroService` injected into a component is created with another injected service,
|
||||
`MessageService`.
|
@ -1,87 +1,88 @@
|
||||
# Add services
|
||||
# Agregar servicios
|
||||
|
||||
The Tour of Heroes `HeroesComponent` is currently getting and displaying fake data.
|
||||
El `HeroesComponent` de Tour de los Heroes actualmente está obteniendo y mostrando datos simulados.
|
||||
|
||||
After the refactoring in this tutorial, `HeroesComponent` will be lean and focused on supporting the view.
|
||||
It will also be easier to unit-test with a mock service.
|
||||
Después de la refactorización en este tutorial, `HeroesComponent` será sencillo y se centrará en apoyar la vista.
|
||||
También será más fácil realizar pruebas unitarias con un servicio simulado.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For the sample app that this page describes, see the <live-example></live-example>.
|
||||
Para ver la aplicación de ejemplo que describe esta página, consulte el <live-example></live-example>.
|
||||
|
||||
</div>
|
||||
|
||||
## Por qué servicios
|
||||
|
||||
## Why services
|
||||
Los componentes no deberían buscar ni guardar datos directamente y, desde luego, no deberían presentar a sabiendas datos simulados.
|
||||
Deben centrarse en presentar datos y delegar el acceso a los datos a un servicio.
|
||||
|
||||
Components shouldn't fetch or save data directly and they certainly shouldn't knowingly present fake data.
|
||||
They should focus on presenting data and delegate data access to a service.
|
||||
En este tutorial, crearás un `HeroService` que todas las clases de aplicación pueden usar para obtener héroes.
|
||||
En lugar de crear ese servicio con la [palabra clave `new`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new),
|
||||
confiará en la [*inyección de dependencia*](guide/dependency-injection) de Angular
|
||||
para inyectarlo en el constructor `HeroesComponent`.
|
||||
|
||||
In this tutorial, you'll create a `HeroService` that all application classes can use to get heroes.
|
||||
Instead of creating that service with the [`new` keyword](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new),
|
||||
you'll rely on Angular [*dependency injection*](guide/dependency-injection)
|
||||
to inject it into the `HeroesComponent` constructor.
|
||||
Los servicios son una excelente manera de compartir información entre clases que no se _conocen entre sí_.
|
||||
Creará un `MessageService` y lo inyectará en dos lugares.
|
||||
|
||||
Services are a great way to share information among classes that _don't know each other_.
|
||||
You'll create a `MessageService` and inject it in two places.
|
||||
|
||||
1. Inject in HeroService, which uses the service to send a message.
|
||||
2. Inject in MessagesComponent, which displays that message, and also displays the ID
|
||||
when the user clicks a hero.
|
||||
1. Inyecte en HeroService, que utiliza el servicio para enviar un mensaje.
|
||||
2. Inyecte en MessagesComponent, que muestra ese mensaje, y también muestra la ID
|
||||
cuando el usuario hace clic en un héroe.
|
||||
|
||||
|
||||
## Create the `HeroService`
|
||||
## Crear el `HeroService`
|
||||
|
||||
Using the Angular CLI, create a service called `hero`.
|
||||
Usando la CLI Angular, cree un servicio llamado `hero`.
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
ng generate service hero
|
||||
</code-example>
|
||||
|
||||
The command generates a skeleton `HeroService` class in `src/app/hero.service.ts` as follows:
|
||||
Este comando generará un archivo base `HeroService` en `src/app/hero.service.ts` de la siguiente manera:
|
||||
|
||||
<code-example path="toh-pt4/src/app/hero.service.1.ts" region="new"
|
||||
header="src/app/hero.service.ts (new service)"></code-example>
|
||||
|
||||
|
||||
### `@Injectable()` services
|
||||
### Servicio `@Injectable()`
|
||||
|
||||
Notice that the new service imports the Angular `Injectable` symbol and annotates
|
||||
the class with the `@Injectable()` decorator. This marks the class as one that participates in the _dependency injection system_. The `HeroService` class is going to provide an injectable service, and it can also have its own injected dependencies.
|
||||
It doesn't have any dependencies yet, but [it will soon](#inject-message-service).
|
||||
Observe que el símbolo Inyectable de Angular se importa en el archivo generado, anotando la clase como decorador `@Injectable()`.
|
||||
Esto marca a la clase como participante en el sistema de inyección de dependencia. La clase `HeroService` proporcionará servicios inyectables y puede tener dependencias.
|
||||
Aún no hay dependencias, [estará pronto](#inject-message-service).
|
||||
|
||||
The `@Injectable()` decorator accepts a metadata object for the service, the same way the `@Component()` decorator did for your component classes.
|
||||
El decorador `@Injectable()` acepta el objeto de metadatos de un servicio de la misma manera que el decorador `@Component()` para las clases de componentes.
|
||||
|
||||
### Get hero data
|
||||
### Obtener datos del héroe
|
||||
|
||||
The `HeroService` could get hero data from anywhere—a web service, local storage, or a mock data source.
|
||||
|
||||
Removing data access from components means you can change your mind about the implementation anytime, without touching any components.
|
||||
They don't know how the service works.
|
||||
El `HeroService` podría obtener datos de héroes desde cualquier lugar— un servicio web, almacenamiento local o una fuente de datos simulada.
|
||||
|
||||
The implementation in _this_ tutorial will continue to deliver _mock heroes_.
|
||||
|
||||
Eliminar el acceso a datos de los componentes significa que puede cambiar de opinión acerca de la implementación en cualquier momento, sin tocar ningún componente.
|
||||
No saben cómo funciona el servicio.
|
||||
|
||||
Import the `Hero` and `HEROES`.
|
||||
La implementación en este tutorial continuará entregando _héroes simulados_.
|
||||
|
||||
Importar `Hero` and `HEROES`.
|
||||
|
||||
<code-example path="toh-pt4/src/app/hero.service.ts" header="src/app/hero.service.ts" region="import-heroes">
|
||||
</code-example>
|
||||
|
||||
Add a `getHeroes` method to return the _mock heroes_.
|
||||
Agregue el método `getHeroes` y devuelva los _héroes simulados_.
|
||||
|
||||
<code-example path="toh-pt4/src/app/hero.service.1.ts" header="src/app/hero.service.ts" region="getHeroes">
|
||||
</code-example>
|
||||
|
||||
{@a provide}
|
||||
## Provide the `HeroService`
|
||||
## Proporcionar el `HeroService`
|
||||
|
||||
You must make the `HeroService` available to the dependency injection system
|
||||
before Angular can _inject_ it into the `HeroesComponent` by registering a _provider_. A provider is something that can create or deliver a service; in this case, it instantiates the `HeroService` class to provide the service.
|
||||
Debe poner el `HeroService` a disposición del sistema de inyección de dependencias.
|
||||
antes de que Angular pueda inyectarlo en el 'Componente de héroes' al registrar un proveedor. Un proveedor es algo que puede crear o prestar un servicio; en este caso, crea una instancia de la clase `HeroService` para proporcionar el servicio.
|
||||
|
||||
To make sure that the `HeroService` can provide this service, register it
|
||||
with the _injector_, which is the object that is responsible for choosing
|
||||
and injecting the provider where the app requires it.
|
||||
Para asegurarse de que el `HeroService` pueda proporcionar este servicio, regístrelo
|
||||
con el _inyector_, que es el objeto responsable de elegir
|
||||
e inyectando el proveedor donde la aplicación lo requiere.
|
||||
|
||||
By default, the Angular CLI command `ng generate service` registers a provider with the _root injector_ for your service by including provider metadata, that is `providedIn: 'root'` in the `@Injectable()` decorator.
|
||||
Por defecto, el comando Angular CLI `ng generate service` registra a un proveedor con el inyector raíz para su servicio al incluir los metadatos del proveedor, que se proporcionan en el decorador `@Injectable() `.
|
||||
|
||||
```
|
||||
@Injectable({
|
||||
@ -89,320 +90,323 @@ By default, the Angular CLI command `ng generate service` registers a provider w
|
||||
})
|
||||
```
|
||||
|
||||
When you provide the service at the root level, Angular creates a single, shared instance of `HeroService` and injects into any class that asks for it.
|
||||
Registering the provider in the `@Injectable` metadata also allows Angular to optimize an app by removing the service if it turns out not to be used after all.
|
||||
Cuando proporciona el servicio en el nivel raíz, Angular crea una única instancia compartida de `HeroService` e inyecta en cualquier clase que lo solicite.
|
||||
El registro del proveedor en los metadatos `@Injectable` también le permite a Angular optimizar una aplicación eliminando el servicio si resulta que no se usará después de todo.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
To learn more about providers, see the [Providers section](guide/providers).
|
||||
To learn more about injectors, see the [Dependency Injection guide](guide/dependency-injection).
|
||||
Para obtener más información sobre los proveedores, consulte la [Sección de proveedores](guide/providers).
|
||||
Para obtener más información sobre los inyectores, consulte la [Guía de inyección de dependencia](guide/dependency-injection).
|
||||
|
||||
</div>
|
||||
|
||||
The `HeroService` is now ready to plug into the `HeroesComponent`.
|
||||
El `HeroService` ahora está listo para conectarse al `HeroesComponent`.
|
||||
|
||||
<div class="alert is-important">
|
||||
|
||||
This is an interim code sample that will allow you to provide and use the `HeroService`. At this point, the code will differ from the `HeroService` in the ["final code review"](#final-code-review).
|
||||
Este es un ejemplo de código provisional que le permitirá proporcionar y usar el `HeroService`. En este punto, el código diferirá del `HeroService` en la [" revisión final del código "](#final-code-review).
|
||||
|
||||
</div>
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
## Update `HeroesComponent`
|
||||
Si desea obtener más información sobre _proveedores_, consulte [Proveedores](guide/providers).
|
||||
|
||||
Open the `HeroesComponent` class file.
|
||||
</div>
|
||||
|
||||
Delete the `HEROES` import, because you won't need that anymore.
|
||||
Import the `HeroService` instead.
|
||||
## Actualizar `HeroesComponent`
|
||||
|
||||
Abra el archivo de clase `HeroesComponent`.
|
||||
|
||||
Elimine la importación `HEROES`, porque ya no la necesitará.
|
||||
Importa el `HeroService` en su lugar.
|
||||
|
||||
<code-example path="toh-pt4/src/app/heroes/heroes.component.ts" header="src/app/heroes/heroes.component.ts (import HeroService)" region="hero-service-import">
|
||||
</code-example>
|
||||
|
||||
Replace the definition of the `heroes` property with a simple declaration.
|
||||
Reemplace la definición de la propiedad `heroes` con una simple declaración.
|
||||
|
||||
<code-example path="toh-pt4/src/app/heroes/heroes.component.ts" header="src/app/heroes/heroes.component.ts" region="heroes">
|
||||
</code-example>
|
||||
|
||||
{@a inject}
|
||||
|
||||
### Inject the `HeroService`
|
||||
### Inyectar el `HeroService`
|
||||
|
||||
Add a private `heroService` parameter of type `HeroService` to the constructor.
|
||||
Agregue un parámetro privado `heroService` de tipo `HeroService` al constructor.
|
||||
|
||||
<code-example path="toh-pt4/src/app/heroes/heroes.component.1.ts" header="src/app/heroes/heroes.component.ts" region="ctor">
|
||||
</code-example>
|
||||
|
||||
The parameter simultaneously defines a private `heroService` property and identifies it as a `HeroService` injection site.
|
||||
El parámetro define simultáneamente una propiedad privada `heroService` y la identifica como un sitio de inyección `HeroService`.
|
||||
|
||||
When Angular creates a `HeroesComponent`, the [Dependency Injection](guide/dependency-injection) system
|
||||
sets the `heroService` parameter to the singleton instance of `HeroService`.
|
||||
Cuando Angular crea un `HeroesComponent`, el sistema [Inyección de dependencia](guide/dependency-injection) establece el parámetro `heroService` en la instancia única de `HeroService`.
|
||||
|
||||
### Add `getHeroes()`
|
||||
### Añadir `getHeroes()`
|
||||
|
||||
Create a method to retrieve the heroes from the service.
|
||||
Crea un método para recuperar a los héroes del servicio
|
||||
|
||||
<code-example path="toh-pt4/src/app/heroes/heroes.component.1.ts" header="src/app/heroes/heroes.component.ts" region="getHeroes">
|
||||
</code-example>
|
||||
|
||||
{@a oninit}
|
||||
|
||||
### Call it in `ngOnInit()`
|
||||
### Llamarlo en `ngOnInit()`
|
||||
|
||||
While you could call `getHeroes()` in the constructor, that's not the best practice.
|
||||
Si bien podría llamar a `getHeroes()` en el constructor, esa no es la mejor práctica.
|
||||
|
||||
Reserve the constructor for simple initialization such as wiring constructor parameters to properties.
|
||||
The constructor shouldn't _do anything_.
|
||||
It certainly shouldn't call a function that makes HTTP requests to a remote server as a _real_ data service would.
|
||||
Reserve el constructor para una inicialización simple, como conectar los parámetros del constructor a las propiedades.
|
||||
El constructor no debe _hacer nada_.
|
||||
Ciertamente no debería llamar a una función que realiza solicitudes HTTP a un servidor remoto como lo haría un servicio de datos _real_.
|
||||
|
||||
Instead, call `getHeroes()` inside the [*ngOnInit lifecycle hook*](guide/lifecycle-hooks) and
|
||||
let Angular call `ngOnInit()` at an appropriate time _after_ constructing a `HeroesComponent` instance.
|
||||
En su lugar, llame a `getHeroes()` dentro del [*ngOnInit lifecycle hook*](guide/lifecycle-hooks) (gancho del ciclo de vida) y
|
||||
deje que Angular llame a `ngOnInit()` en el momento apropiado _después_ de construir una instancia de `HeroesComponent`.
|
||||
|
||||
<code-example path="toh-pt4/src/app/heroes/heroes.component.ts" header="src/app/heroes/heroes.component.ts" region="ng-on-init">
|
||||
</code-example>
|
||||
|
||||
### See it run
|
||||
### Verlo correr
|
||||
|
||||
After the browser refreshes, the app should run as before,
|
||||
showing a list of heroes and a hero detail view when you click on a hero name.
|
||||
Después de que el navegador se actualice, la aplicación debería ejecutarse como antes,
|
||||
mostrando una lista de héroes y una vista detallada de héroe cuando haces clic en el nombre de un héroe.
|
||||
|
||||
## Observable data
|
||||
## Datos observables
|
||||
|
||||
The `HeroService.getHeroes()` method has a _synchronous signature_,
|
||||
which implies that the `HeroService` can fetch heroes synchronously.
|
||||
The `HeroesComponent` consumes the `getHeroes()` result
|
||||
as if heroes could be fetched synchronously.
|
||||
El método `HeroService.getHeroes()` tiene una firma sincrónica,
|
||||
lo que implica que el `HeroService` puede buscar héroes sincrónicamente.
|
||||
El `HeroesComponent` consume el resultado `getHeroes()`
|
||||
como si los héroes pudieran ser recuperados sincrónicamente.
|
||||
|
||||
<code-example path="toh-pt4/src/app/heroes/heroes.component.1.ts" header="src/app/heroes/heroes.component.ts" region="get-heroes">
|
||||
</code-example>
|
||||
|
||||
This will not work in a real app.
|
||||
You're getting away with it now because the service currently returns _mock heroes_.
|
||||
But soon the app will fetch heroes from a remote server,
|
||||
which is an inherently _asynchronous_ operation.
|
||||
Esto no funcionará en una aplicación real.
|
||||
Ahora te saldrás con la tuya porque el servicio actualmente devuelve _héroes simulados_.
|
||||
Pero pronto la aplicación buscará héroes de un servidor remoto,
|
||||
que es una operación inherentemente _asincrónica_.
|
||||
|
||||
The `HeroService` must wait for the server to respond,
|
||||
`getHeroes()` cannot return immediately with hero data,
|
||||
and the browser will not block while the service waits.
|
||||
El `HeroService` debe esperar a que el servidor responda,
|
||||
`getHeroes()` no puede regresar inmediatamente con los datos del héroe,
|
||||
y el navegador no se bloqueará mientras el servicio espere.
|
||||
|
||||
`HeroService.getHeroes()` must have an _asynchronous signature_ of some kind.
|
||||
`HeroService.getHeroes()` debe tener una firma asíncrona de algún tipo.
|
||||
|
||||
In this tutorial, `HeroService.getHeroes()` will return an `Observable`
|
||||
because it will eventually use the Angular `HttpClient.get` method to fetch the heroes
|
||||
and [`HttpClient.get()` returns an `Observable`](guide/http).
|
||||
En este tutorial, `HeroService.getHeroes()` devolverá un `Observable`
|
||||
porque eventualmente usará el método angular `HttpClient.get` para buscar a los héroes y [`HttpClient.get()` devuelve un `Observable`](guide/http).
|
||||
|
||||
### Observable `HeroService`
|
||||
|
||||
`Observable` is one of the key classes in the [RxJS library](http://reactivex.io/rxjs/).
|
||||
`Observable` es una de las clases clave en la [biblioteca RxJS] (http://reactivex.io/rxjs/).
|
||||
|
||||
In a [later tutorial on HTTP](tutorial/toh-pt6), you'll learn that Angular's `HttpClient` methods return RxJS `Observable`s.
|
||||
In this tutorial, you'll simulate getting data from the server with the RxJS `of()` function.
|
||||
En un [tutorial posterior sobre HTTP](tutorial/toh-pt6), aprenderá que los métodos `HttpClient` de Angular devuelven RxJS `Observable`s.
|
||||
En este tutorial, simulará obtener datos del servidor con la función RxJS `of()`.
|
||||
|
||||
Open the `HeroService` file and import the `Observable` and `of` symbols from RxJS.
|
||||
Abra el archivo `HeroService` e importe los símbolos `Observable` y `of` de RxJS.
|
||||
|
||||
<code-example path="toh-pt4/src/app/hero.service.ts" header="src/app/hero.service.ts (Observable imports)" region="import-observable">
|
||||
</code-example>
|
||||
|
||||
Replace the `getHeroes()` method with the following:
|
||||
Reemplace el método `getHeroes()` con lo siguiente:
|
||||
|
||||
<code-example path="toh-pt4/src/app/hero.service.ts" header="src/app/hero.service.ts" region="getHeroes-1"></code-example>
|
||||
|
||||
`of(HEROES)` returns an `Observable<Hero[]>` that emits _a single value_, the array of mock heroes.
|
||||
`of (HEROES)` devuelve un `Observable <Hero[]>` que emite _un valor único_, el conjunto de héroes simulados.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
<div class="l-sub-section">
|
||||
|
||||
In the [HTTP tutorial](tutorial/toh-pt6), you'll call `HttpClient.get<Hero[]>()` which also returns an `Observable<Hero[]>` that emits _a single value_, an array of heroes from the body of the HTTP response.
|
||||
En el [tutorial HTTP](tutorial/toh-pt6), llamará a `HttpClient.get <Hero[]>()` que también devuelve un `Observable <Hero[]>` que emite _un valor único_, una matriz de héroes del cuerpo de la respuesta HTTP.
|
||||
|
||||
</div>
|
||||
|
||||
### Subscribe in `HeroesComponent`
|
||||
### Suscríbirse en `HeroesComponent`
|
||||
|
||||
The `HeroService.getHeroes` method used to return a `Hero[]`.
|
||||
Now it returns an `Observable<Hero[]>`.
|
||||
El método `HeroService.getHeroes` utilizado para devolver un `Hero[]`.
|
||||
Ahora devuelve un `Observable <Hero[]>`.
|
||||
|
||||
You'll have to adjust to that difference in `HeroesComponent`.
|
||||
Tendrás que ajustarte a esa diferencia en `HeroesComponent`.
|
||||
|
||||
Find the `getHeroes` method and replace it with the following code
|
||||
(shown side-by-side with the previous version for comparison)
|
||||
Encuentre el método `getHeroes` y reemplácelo con el siguiente código
|
||||
(Al lado de la versión anterior para comparar)
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane header="heroes.component.ts (Observable)"
|
||||
<code-pane header="heroes.component.ts (Observable)"
|
||||
path="toh-pt4/src/app/heroes/heroes.component.ts" region="getHeroes">
|
||||
</code-pane>
|
||||
|
||||
<code-pane header="heroes.component.ts (Original)"
|
||||
<code-pane header="heroes.component.ts (Original)"
|
||||
path="toh-pt4/src/app/heroes/heroes.component.1.ts" region="getHeroes">
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
`Observable.subscribe()` is the critical difference.
|
||||
`Observable.subscribe()` es la diferencia crítica.
|
||||
|
||||
The previous version assigns an array of heroes to the component's `heroes` property.
|
||||
The assignment occurs _synchronously_, as if the server could return heroes instantly
|
||||
or the browser could freeze the UI while it waited for the server's response.
|
||||
La versión anterior asigna una variedad de héroes a la propiedad 'heroes' del componente.
|
||||
La asignación ocurre _sincrónicamente_, como si el servidor pudiera devolver héroes al instante
|
||||
o el navegador podría congelar la interfaz de usuario mientras esperaba la respuesta del servidor.
|
||||
|
||||
That _won't work_ when the `HeroService` is actually making requests of a remote server.
|
||||
Eso _no funcionará_ cuando el `HeroService` realmente está haciendo solicitudes a un servidor remoto.
|
||||
|
||||
The new version waits for the `Observable` to emit the array of heroes—which
|
||||
could happen now or several minutes from now.
|
||||
The `subscribe()` method passes the emitted array to the callback,
|
||||
which sets the component's `heroes` property.
|
||||
La nueva versión espera a que el 'Observable' emita una serie de héroes,—
|
||||
que podría suceder ahora o varios minutos a partir de ahora.
|
||||
El método `subscribe()` pasa el arreglo emitida a la devolución de llamada,
|
||||
que establece la propiedad 'heroes' del componente.
|
||||
|
||||
This asynchronous approach _will work_ when
|
||||
the `HeroService` requests heroes from the server.
|
||||
Este enfoque asincrónico funcionará cuando
|
||||
el `HeroService` solicite héroes del servidor.
|
||||
|
||||
## Show messages
|
||||
## Mostrar mensajes
|
||||
|
||||
This section guides you through the following:
|
||||
Esta sección lo guía a través de lo siguiente:
|
||||
|
||||
* adding a `MessagesComponent` that displays app messages at the bottom of the screen
|
||||
* creating an injectable, app-wide `MessageService` for sending messages to be displayed
|
||||
* injecting `MessageService` into the `HeroService`
|
||||
* displaying a message when `HeroService` fetches heroes successfully
|
||||
* agregando un `MessagesComponent` que muestra los mensajes de la aplicación en la parte inferior de la pantalla
|
||||
* crear un `MessageService` inyectable para toda la aplicación para enviar mensajes que se mostrarán
|
||||
* inyectando `MessageService` en el `HeroService`
|
||||
* mostrando un mensaje cuando `HeroService` busca héroes con éxito
|
||||
|
||||
### Create `MessagesComponent`
|
||||
|
||||
Use the CLI to create the `MessagesComponent`.
|
||||
### Crear `MessagesComponent`
|
||||
|
||||
Use la CLI para crear el `MessagesComponent`.
|
||||
<code-example language="sh" class="code-shell">
|
||||
ng generate component messages
|
||||
</code-example>
|
||||
|
||||
The CLI creates the component files in the `src/app/messages` folder and declares the `MessagesComponent` in `AppModule`.
|
||||
|
||||
Modify the `AppComponent` template to display the generated `MessagesComponent`.
|
||||
La CLI crea los archivos componentes en la carpeta `src/app/messages` y declara el `MessagesComponent` en `AppModule`.
|
||||
|
||||
Modifique la plantilla `AppComponent` para mostrar el `MessagesComponent` generado.
|
||||
|
||||
<code-example
|
||||
header = "src/app/app.component.html"
|
||||
path="toh-pt4/src/app/app.component.html">
|
||||
</code-example>
|
||||
|
||||
You should see the default paragraph from `MessagesComponent` at the bottom of the page.
|
||||
Debería ver el párrafo predeterminado de `MessagesComponent` en la parte inferior de la página.
|
||||
|
||||
### Create the `MessageService`
|
||||
### Crear el `MessageService`
|
||||
|
||||
Use the CLI to create the `MessageService` in `src/app`.
|
||||
Use la CLI para crear el `MessageService` en `src/app`.
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
ng generate service message
|
||||
</code-example>
|
||||
|
||||
Open `MessageService` and replace its contents with the following.
|
||||
Abra `MessageService` y reemplace su contenido con lo siguiente.
|
||||
|
||||
<code-example header = "src/app/message.service.ts" path="toh-pt4/src/app/message.service.ts">
|
||||
</code-example>
|
||||
|
||||
The service exposes its cache of `messages` and two methods: one to `add()` a message to the cache and another to `clear()` the cache.
|
||||
El servicio expone su caché de `mensajes` y dos métodos: uno para `agregar()` un mensaje al caché y otro para `borrar()` el caché.
|
||||
|
||||
{@a inject-message-service}
|
||||
### Inject it into the `HeroService`
|
||||
### Inyectar en el `HeroService`
|
||||
|
||||
En `HeroService`, importe el `MessageService`.
|
||||
|
||||
In `HeroService`, import the `MessageService`.
|
||||
|
||||
<code-example
|
||||
header = "src/app/hero.service.ts (import MessageService)"
|
||||
path="toh-pt4/src/app/hero.service.ts" region="import-message-service">
|
||||
</code-example>
|
||||
|
||||
Modify the constructor with a parameter that declares a private `messageService` property.
|
||||
Angular will inject the singleton `MessageService` into that property
|
||||
when it creates the `HeroService`.
|
||||
Modifique el constructor con un parámetro que declare una propiedad privada `messageService`.
|
||||
Angular inyectará el singleton `MessageService` en esa propiedad
|
||||
cuando crea el `HeroService`.
|
||||
|
||||
<code-example
|
||||
path="toh-pt4/src/app/hero.service.ts" header="src/app/hero.service.ts" region="ctor">
|
||||
</code-example>
|
||||
|
||||
<div class="alert is-helpful">
|
||||
<div class="l-sub-section">
|
||||
|
||||
This is a typical "*service-in-service*" scenario:
|
||||
you inject the `MessageService` into the `HeroService` which is injected into the `HeroesComponent`.
|
||||
Este es un escenario típico de "*servicio en servicio*":
|
||||
inyecta el `MessageService` en el `HeroService` que se inyecta en el `HeroesComponent`.
|
||||
|
||||
</div>
|
||||
|
||||
### Send a message from `HeroService`
|
||||
### Enviar un mensaje desde `HeroService`
|
||||
|
||||
Modify the `getHeroes()` method to send a message when the heroes are fetched.
|
||||
Modifique el método `getHeroes()` para enviar un mensaje cuando se busquen los héroes.
|
||||
|
||||
<code-example path="toh-pt4/src/app/hero.service.ts" header="src/app/hero.service.ts" region="getHeroes">
|
||||
</code-example>
|
||||
|
||||
### Display the message from `HeroService`
|
||||
### Mostrar el mensaje de `HeroService`
|
||||
|
||||
The `MessagesComponent` should display all messages,
|
||||
including the message sent by the `HeroService` when it fetches heroes.
|
||||
El `MessagesComponent` debería mostrar todos los mensajes,
|
||||
incluido el mensaje enviado por el `HeroService` cuando busca héroes.
|
||||
|
||||
Open `MessagesComponent` and import the `MessageService`.
|
||||
Abra `MessagesComponent` e importe el `MessageService`
|
||||
|
||||
<code-example header="src/app/messages/messages.component.ts (import MessageService)" path="toh-pt4/src/app/messages/messages.component.ts" region="import-message-service">
|
||||
</code-example>
|
||||
|
||||
Modify the constructor with a parameter that declares a **public** `messageService` property.
|
||||
Angular will inject the singleton `MessageService` into that property
|
||||
when it creates the `MessagesComponent`.
|
||||
Modifique el constructor con un parámetro que declare una propiedad `messageService` **publica**.
|
||||
Angular inyectará el único `MessageService` en esa propiedad
|
||||
cuando crea el `MessagesComponent`.
|
||||
|
||||
<code-example path="toh-pt4/src/app/messages/messages.component.ts" header="src/app/messages/messages.component.ts" region="ctor">
|
||||
</code-example>
|
||||
|
||||
The `messageService` property **must be public** because you're going to bind to it in the template.
|
||||
La propiedad `messageService` **debe ser pública** porque la vinculará en la plantilla.
|
||||
|
||||
<div class="alert is-important">
|
||||
|
||||
Angular only binds to _public_ component properties.
|
||||
Angular solo se une a las propiedades _publicas_ del componente .
|
||||
|
||||
</div>
|
||||
|
||||
### Bind to the `MessageService`
|
||||
|
||||
Replace the CLI-generated `MessagesComponent` template with the following.
|
||||
### Enlazar al `MessageService`
|
||||
|
||||
Reemplace la plantilla `MessagesComponent` generada por CLI con lo siguiente.
|
||||
|
||||
<code-example
|
||||
header = "src/app/messages/messages.component.html"
|
||||
path="toh-pt4/src/app/messages/messages.component.html">
|
||||
</code-example>
|
||||
|
||||
This template binds directly to the component's `messageService`.
|
||||
Esta plantilla se une directamente al componente `messageService` del componente.
|
||||
|
||||
* The `*ngIf` only displays the messages area if there are messages to show.
|
||||
* `*NgIf` solo muestra el área de mensajes si hay mensajes para mostrar.
|
||||
|
||||
|
||||
* An `*ngFor` presents the list of messages in repeated `<div>` elements.
|
||||
* Un `*ngFor` presenta la lista de mensajes en elementos repetidos` <div> `.
|
||||
|
||||
|
||||
* An Angular [event binding](guide/event-binding) binds the button's click event
|
||||
to `MessageService.clear()`.
|
||||
* Un [enlace de evento](guide/template-syntax) en angular une el evento de clic del botón
|
||||
a `MessageService.clear ()`.
|
||||
|
||||
The messages will look better when you add the private CSS styles to `messages.component.css`
|
||||
as listed in one of the ["final code review"](#final-code-review) tabs below.
|
||||
Los mensajes se verán mejor cuando agregue los estilos CSS privados a `messages.component.css`
|
||||
como se indica en una de las pestañas ["revisión de código final"](#final-code-review) a continuación.
|
||||
|
||||
## Add additional messages to hero service
|
||||
## Agregar mensajes adicionales al servicio de héroe
|
||||
|
||||
The following example shows how to send and display a message each time the user clicks on
|
||||
a hero, showing a history of the user's selections. This will be helpful when you get to the
|
||||
next section on [Routing](tutorial/toh-pt5).
|
||||
El siguiente ejemplo muestra cómo enviar y mostrar un mensaje cada vez que el usuario hace clic en
|
||||
un héroe, que muestra un historial de las selecciones del usuario. Esto será útil cuando llegues a
|
||||
siguiente sección sobre [Enrutamiento](tutorial/toh-pt5).
|
||||
|
||||
<code-example header="src/app/heroes/heroes.component.ts"
|
||||
path="toh-pt4/src/app/heroes/heroes.component.ts">
|
||||
</code-example>
|
||||
|
||||
The browser refreshes and the page displays the list of heroes.
|
||||
Refresh the browser to see the list of heroes, and scroll to the bottom to see the
|
||||
messages from the HeroService. Each time you click a hero, a new message appears to record
|
||||
the selection. Use the "clear" button to clear the message history.
|
||||
El navegador se actualizará y la página mostrará la lista de héroes.
|
||||
Actualiza el navegador para ver la lista de héroes y desplázate hacia abajo para ver
|
||||
mensajes del HeroService. Cada vez que haces clic en un héroe, aparece un nuevo mensaje para grabar
|
||||
la selección. Use el botón "borrar" para borrar el historial de mensajes.
|
||||
|
||||
{@a final-code-review}
|
||||
|
||||
## Final code review
|
||||
## Revisión final del código
|
||||
|
||||
Here are the code files discussed on this page.
|
||||
Aquí están los archivos de código discutidos en esta página.
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane header="src/app/hero.service.ts"
|
||||
<code-pane header="src/app/hero.service.ts"
|
||||
path="toh-pt4/src/app/hero.service.ts">
|
||||
</code-pane>
|
||||
|
||||
<code-pane header="src/app/message.service.ts"
|
||||
<code-pane header="src/app/message.service.ts"
|
||||
path="toh-pt4/src/app/message.service.ts">
|
||||
</code-pane>
|
||||
|
||||
@ -432,15 +436,16 @@ Here are the code files discussed on this page.
|
||||
|
||||
</code-tabs>
|
||||
|
||||
## Summary
|
||||
## Resumen
|
||||
|
||||
* You refactored data access to the `HeroService` class.
|
||||
* You registered the `HeroService` as the _provider_ of its service at the root level so that it can be injected anywhere in the app.
|
||||
* You used [Angular Dependency Injection](guide/dependency-injection) to inject it into a component.
|
||||
* You gave the `HeroService` _get data_ method an asynchronous signature.
|
||||
* You discovered `Observable` and the RxJS _Observable_ library.
|
||||
* You used RxJS `of()` to return an observable of mock heroes (`Observable<Hero[]>`).
|
||||
* The component's `ngOnInit` lifecycle hook calls the `HeroService` method, not the constructor.
|
||||
* You created a `MessageService` for loosely-coupled communication between classes.
|
||||
* The `HeroService` injected into a component is created with another injected service,
|
||||
`MessageService`.
|
||||
* Refactorizó el acceso a datos a la clase `HeroService`.
|
||||
* Registro el `HeroService` como el _proveedor_ de su servicio en el nivel raíz para que pueda inyectarse en cualquier lugar de la aplicación.
|
||||
* Usó la [Inyección de dependencia angular](guide/dependency-injection) para inyectarlo en un componente.
|
||||
* Le dio al `HeroService` el método _get data_ una firma asincrónica.
|
||||
* Descubrio `Observable` y la biblioteca RxJS _Observable_.
|
||||
* Usó RxJS `of ()` para devolver un observable de héroes simulados (`Observable <Hero []>`).
|
||||
* El lifecycle hook (gancho del ciclo de vida) `ngOnInit` del componente llama al método `HeroService`, no al constructor.
|
||||
* Creó un `MessageService` para una comunicación débilmente acoplada entre clases.
|
||||
* El `HeroService` inyectado en un componente se crea con otro servicio inyectado,
|
||||
`MessageService`.
|
||||
|
573
aio/content/tutorial/toh-pt5.en.md
Normal file
573
aio/content/tutorial/toh-pt5.en.md
Normal file
@ -0,0 +1,573 @@
|
||||
# Add in-app navigation with routing
|
||||
|
||||
There are new requirements for the Tour of Heroes app:
|
||||
|
||||
* Add a *Dashboard* view.
|
||||
* Add the ability to navigate between the *Heroes* and *Dashboard* views.
|
||||
* When users click a hero name in either view, navigate to a detail view of the selected hero.
|
||||
* When users click a *deep link* in an email, open the detail view for a particular hero.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For the sample app that this page describes, see the <live-example></live-example>.
|
||||
|
||||
</div>
|
||||
|
||||
When you’re done, users will be able to navigate the app like this:
|
||||
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/toh/nav-diagram.png' alt="View navigations">
|
||||
</div>
|
||||
|
||||
## Add the `AppRoutingModule`
|
||||
|
||||
In Angular, the best practice is to load and configure the router in a separate, top-level module
|
||||
that is dedicated to routing and imported by the root `AppModule`.
|
||||
|
||||
By convention, the module class name is `AppRoutingModule` and it belongs in the `app-routing.module.ts` in the `src/app` folder.
|
||||
|
||||
Use the CLI to generate it.
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
ng generate module app-routing --flat --module=app
|
||||
</code-example>
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
`--flat` puts the file in `src/app` instead of its own folder.<br>
|
||||
`--module=app` tells the CLI to register it in the `imports` array of the `AppModule`.
|
||||
</div>
|
||||
|
||||
The generated file looks like this:
|
||||
|
||||
<code-example path="toh-pt5/src/app/app-routing.module.0.ts" header="src/app/app-routing.module.ts (generated)">
|
||||
</code-example>
|
||||
|
||||
Replace it with the following:
|
||||
|
||||
<code-example path="toh-pt5/src/app/app-routing.module.1.ts" header="src/app/app-routing.module.ts (updated)">
|
||||
</code-example>
|
||||
|
||||
First, `AppRoutingModule` imports `RouterModule` and `Routes` so the app can have routing functionality. The next import, `HeroesComponent`, will give the Router somewhere to go once you configure the routes.
|
||||
|
||||
Notice that the `CommonModule` references and `declarations` array are unnecessary, so are no
|
||||
longer part of `AppRoutingModule`. The following sections explain the rest of the `AppRoutingModule` in more detail.
|
||||
|
||||
|
||||
### Routes
|
||||
|
||||
The next part of the file is where you configure your routes.
|
||||
*Routes* tell the Router which view to display when a user clicks a link or
|
||||
pastes a URL into the browser address bar.
|
||||
|
||||
Since `AppRoutingModule` already imports `HeroesComponent`, you can use it in the `routes` array:
|
||||
|
||||
<code-example path="toh-pt5/src/app/app-routing.module.ts" header="src/app/app-routing.module.ts"
|
||||
region="heroes-route">
|
||||
</code-example>
|
||||
|
||||
A typical Angular `Route` has two properties:
|
||||
|
||||
* `path`: a string that matches the URL in the browser address bar.
|
||||
* `component`: the component that the router should create when navigating to this route.
|
||||
|
||||
This tells the router to match that URL to `path: 'heroes'`
|
||||
and display the `HeroesComponent` when the URL is something like `localhost:4200/heroes`.
|
||||
|
||||
### `RouterModule.forRoot()`
|
||||
|
||||
The `@NgModule` metadata initializes the router and starts it listening for browser location changes.
|
||||
|
||||
The following line adds the `RouterModule` to the `AppRoutingModule` `imports` array and
|
||||
configures it with the `routes` in one step by calling
|
||||
`RouterModule.forRoot()`:
|
||||
|
||||
<code-example path="toh-pt5/src/app/app-routing.module.ts" header="src/app/app-routing.module.ts" region="ngmodule-imports">
|
||||
</code-example>
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
The method is called `forRoot()` because you configure the router at the application's root level.
|
||||
The `forRoot()` method supplies the service providers and directives needed for routing,
|
||||
and performs the initial navigation based on the current browser URL.
|
||||
|
||||
</div>
|
||||
|
||||
Next, `AppRoutingModule` exports `RouterModule` so it will be available throughout the app.
|
||||
|
||||
<code-example path="toh-pt5/src/app/app-routing.module.ts" header="src/app/app-routing.module.ts (exports array)" region="export-routermodule">
|
||||
</code-example>
|
||||
|
||||
## Add `RouterOutlet`
|
||||
|
||||
Open the `AppComponent` template and replace the `<app-heroes>` element with a `<router-outlet>` element.
|
||||
|
||||
<code-example path="toh-pt5/src/app/app.component.html" region="outlet" header="src/app/app.component.html (router-outlet)">
|
||||
</code-example>
|
||||
|
||||
The `AppComponent` template no longer needs `<app-heroes>` because the app will only display the `HeroesComponent` when the user navigates to it.
|
||||
|
||||
The `<router-outlet>` tells the router where to display routed views.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
The `RouterOutlet` is one of the router directives that became available to the `AppComponent`
|
||||
because `AppModule` imports `AppRoutingModule` which exported `RouterModule`. The `ng generate` command you ran at the start of this tutorial added this import because of the `--module=app` flag. If you manually created `app-routing.module.ts` or used a tool other than the CLI to do so, you'll need to import `AppRoutingModule` into `app.module.ts` and add it to the `imports` array of the `NgModule`.
|
||||
|
||||
</div>
|
||||
|
||||
#### Try it
|
||||
|
||||
You should still be running with this CLI command.
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
ng serve
|
||||
</code-example>
|
||||
|
||||
The browser should refresh and display the app title but not the list of heroes.
|
||||
|
||||
Look at the browser's address bar.
|
||||
The URL ends in `/`.
|
||||
The route path to `HeroesComponent` is `/heroes`.
|
||||
|
||||
Append `/heroes` to the URL in the browser address bar.
|
||||
You should see the familiar heroes master/detail view.
|
||||
|
||||
{@a routerlink}
|
||||
|
||||
## Add a navigation link (`routerLink`)
|
||||
|
||||
Ideally, users should be able to click a link to navigate rather
|
||||
than pasting a route URL into the address bar.
|
||||
|
||||
Add a `<nav>` element and, within that, an anchor element that, when clicked,
|
||||
triggers navigation to the `HeroesComponent`.
|
||||
The revised `AppComponent` template looks like this:
|
||||
|
||||
<code-example path="toh-pt5/src/app/app.component.html" region="heroes" header="src/app/app.component.html (heroes RouterLink)">
|
||||
</code-example>
|
||||
|
||||
A [`routerLink` attribute](#routerlink) is set to `"/heroes"`,
|
||||
the string that the router matches to the route to `HeroesComponent`.
|
||||
The `routerLink` is the selector for the [`RouterLink` directive](/api/router/RouterLink)
|
||||
that turns user clicks into router navigations.
|
||||
It's another of the public directives in the `RouterModule`.
|
||||
|
||||
The browser refreshes and displays the app title and heroes link,
|
||||
but not the heroes list.
|
||||
|
||||
Click the link.
|
||||
The address bar updates to `/heroes` and the list of heroes appears.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
Make this and future navigation links look better by adding private CSS styles to `app.component.css`
|
||||
as listed in the [final code review](#appcomponent) below.
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
## Add a dashboard view
|
||||
|
||||
Routing makes more sense when there are multiple views.
|
||||
So far there's only the heroes view.
|
||||
|
||||
Add a `DashboardComponent` using the CLI:
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
ng generate component dashboard
|
||||
</code-example>
|
||||
|
||||
The CLI generates the files for the `DashboardComponent` and declares it in `AppModule`.
|
||||
|
||||
Replace the default file content in these three files as follows:
|
||||
|
||||
<code-tabs>
|
||||
<code-pane
|
||||
header="src/app/dashboard/dashboard.component.html" path="toh-pt5/src/app/dashboard/dashboard.component.1.html">
|
||||
</code-pane>
|
||||
|
||||
<code-pane
|
||||
header="src/app/dashboard/dashboard.component.ts" path="toh-pt5/src/app/dashboard/dashboard.component.ts">
|
||||
</code-pane>
|
||||
|
||||
<code-pane
|
||||
header="src/app/dashboard/dashboard.component.css" path="toh-pt5/src/app/dashboard/dashboard.component.css">
|
||||
</code-pane>
|
||||
</code-tabs>
|
||||
|
||||
The _template_ presents a grid of hero name links.
|
||||
|
||||
* The `*ngFor` repeater creates as many links as are in the component's `heroes` array.
|
||||
* The links are styled as colored blocks by the `dashboard.component.css`.
|
||||
* The links don't go anywhere yet but [they will shortly](#hero-details).
|
||||
|
||||
The _class_ is similar to the `HeroesComponent` class.
|
||||
* It defines a `heroes` array property.
|
||||
* The constructor expects Angular to inject the `HeroService` into a private `heroService` property.
|
||||
* The `ngOnInit()` lifecycle hook calls `getHeroes()`.
|
||||
|
||||
This `getHeroes()` returns the sliced list of heroes at positions 1 and 5, returning only four of the Top Heroes (2nd, 3rd, 4th, and 5th).
|
||||
|
||||
<code-example path="toh-pt5/src/app/dashboard/dashboard.component.ts" header="src/app/dashboard/dashboard.component.ts" region="getHeroes">
|
||||
</code-example>
|
||||
|
||||
### Add the dashboard route
|
||||
|
||||
To navigate to the dashboard, the router needs an appropriate route.
|
||||
|
||||
Import the `DashboardComponent` in the `AppRoutingModule`.
|
||||
|
||||
<code-example path="toh-pt5/src/app/app-routing.module.ts" region="import-dashboard" header="src/app/app-routing.module.ts (import DashboardComponent)">
|
||||
</code-example>
|
||||
|
||||
Add a route to the `AppRoutingModule.routes` array that matches a path to the `DashboardComponent`.
|
||||
|
||||
<code-example path="toh-pt5/src/app/app-routing.module.ts" header="src/app/app-routing.module.ts" region="dashboard-route">
|
||||
</code-example>
|
||||
|
||||
### Add a default route
|
||||
|
||||
When the app starts, the browser's address bar points to the web site's root.
|
||||
That doesn't match any existing route so the router doesn't navigate anywhere.
|
||||
The space below the `<router-outlet>` is blank.
|
||||
|
||||
To make the app navigate to the dashboard automatically, add the following
|
||||
route to the `AppRoutingModule.Routes` array.
|
||||
|
||||
<code-example path="toh-pt5/src/app/app-routing.module.ts" header="src/app/app-routing.module.ts" region="redirect-route">
|
||||
</code-example>
|
||||
|
||||
This route redirects a URL that fully matches the empty path to the route whose path is `'/dashboard'`.
|
||||
|
||||
After the browser refreshes, the router loads the `DashboardComponent`
|
||||
and the browser address bar shows the `/dashboard` URL.
|
||||
|
||||
### Add dashboard link to the shell
|
||||
|
||||
The user should be able to navigate back and forth between the
|
||||
`DashboardComponent` and the `HeroesComponent` by clicking links in the
|
||||
navigation area near the top of the page.
|
||||
|
||||
Add a dashboard navigation link to the `AppComponent` shell template, just above the *Heroes* link.
|
||||
|
||||
<code-example path="toh-pt5/src/app/app.component.html" header="src/app/app.component.html">
|
||||
</code-example>
|
||||
|
||||
After the browser refreshes you can navigate freely between the two views by clicking the links.
|
||||
|
||||
{@a hero-details}
|
||||
## Navigating to hero details
|
||||
|
||||
The `HeroDetailsComponent` displays details of a selected hero.
|
||||
At the moment the `HeroDetailsComponent` is only visible at the bottom of the `HeroesComponent`
|
||||
|
||||
The user should be able to get to these details in three ways.
|
||||
|
||||
1. By clicking a hero in the dashboard.
|
||||
1. By clicking a hero in the heroes list.
|
||||
1. By pasting a "deep link" URL into the browser address bar that identifies the hero to display.
|
||||
|
||||
In this section, you'll enable navigation to the `HeroDetailsComponent`
|
||||
and liberate it from the `HeroesComponent`.
|
||||
|
||||
### Delete _hero details_ from `HeroesComponent`
|
||||
|
||||
When the user clicks a hero item in the `HeroesComponent`,
|
||||
the app should navigate to the `HeroDetailComponent`,
|
||||
replacing the heroes list view with the hero detail view.
|
||||
The heroes list view should no longer show hero details as it does now.
|
||||
|
||||
Open the `HeroesComponent` template (`heroes/heroes.component.html`) and
|
||||
delete the `<app-hero-detail>` element from the bottom.
|
||||
|
||||
Clicking a hero item now does nothing.
|
||||
You'll [fix that shortly](#heroes-component-links) after you enable routing to the `HeroDetailComponent`.
|
||||
|
||||
### Add a _hero detail_ route
|
||||
|
||||
A URL like `~/detail/11` would be a good URL for navigating to the *Hero Detail* view of the hero whose `id` is `11`.
|
||||
|
||||
Open `AppRoutingModule` and import `HeroDetailComponent`.
|
||||
|
||||
<code-example path="toh-pt5/src/app/app-routing.module.ts" region="import-herodetail" header="src/app/app-routing.module.ts (import HeroDetailComponent)">
|
||||
</code-example>
|
||||
|
||||
Then add a _parameterized_ route to the `AppRoutingModule.routes` array that matches the path pattern to the _hero detail_ view.
|
||||
|
||||
<code-example path="toh-pt5/src/app/app-routing.module.ts" header="src/app/app-routing.module.ts" region="detail-route">
|
||||
</code-example>
|
||||
|
||||
The colon (:) in the `path` indicates that `:id` is a placeholder for a specific hero `id`.
|
||||
|
||||
At this point, all application routes are in place.
|
||||
|
||||
<code-example path="toh-pt5/src/app/app-routing.module.ts" region="routes" header="src/app/app-routing.module.ts (all routes)">
|
||||
</code-example>
|
||||
|
||||
### `DashboardComponent` hero links
|
||||
|
||||
The `DashboardComponent` hero links do nothing at the moment.
|
||||
|
||||
Now that the router has a route to `HeroDetailComponent`,
|
||||
fix the dashboard hero links to navigate via the _parameterized_ dashboard route.
|
||||
|
||||
<code-example
|
||||
path="toh-pt5/src/app/dashboard/dashboard.component.html"
|
||||
region="click"
|
||||
header="src/app/dashboard/dashboard.component.html (hero links)">
|
||||
</code-example>
|
||||
|
||||
You're using Angular [interpolation binding](guide/interpolation) within the `*ngFor` repeater
|
||||
to insert the current iteration's `hero.id` into each
|
||||
[`routerLink`](#routerlink).
|
||||
|
||||
{@a heroes-component-links}
|
||||
### `HeroesComponent` hero links
|
||||
|
||||
The hero items in the `HeroesComponent` are `<li>` elements whose click events
|
||||
are bound to the component's `onSelect()` method.
|
||||
|
||||
<code-example path="toh-pt4/src/app/heroes/heroes.component.html" region="list" header="src/app/heroes/heroes.component.html (list with onSelect)">
|
||||
</code-example>
|
||||
|
||||
Strip the `<li>` back to just its `*ngFor`,
|
||||
wrap the badge and name in an anchor element (`<a>`),
|
||||
and add a `routerLink` attribute to the anchor that
|
||||
is the same as in the dashboard template
|
||||
|
||||
<code-example path="toh-pt5/src/app/heroes/heroes.component.html" region="list" header="src/app/heroes/heroes.component.html (list with links)">
|
||||
</code-example>
|
||||
|
||||
You'll have to fix the private stylesheet (`heroes.component.css`) to make
|
||||
the list look as it did before.
|
||||
Revised styles are in the [final code review](#heroescomponent) at the bottom of this guide.
|
||||
|
||||
#### Remove dead code (optional)
|
||||
|
||||
While the `HeroesComponent` class still works,
|
||||
the `onSelect()` method and `selectedHero` property are no longer used.
|
||||
|
||||
It's nice to tidy up and you'll be grateful to yourself later.
|
||||
Here's the class after pruning away the dead code.
|
||||
|
||||
<code-example path="toh-pt5/src/app/heroes/heroes.component.ts" region="class" header="src/app/heroes/heroes.component.ts (cleaned up)">
|
||||
</code-example>
|
||||
|
||||
## Routable `HeroDetailComponent`
|
||||
|
||||
Previously, the parent `HeroesComponent` set the `HeroDetailComponent.hero`
|
||||
property and the `HeroDetailComponent` displayed the hero.
|
||||
|
||||
`HeroesComponent` doesn't do that anymore.
|
||||
Now the router creates the `HeroDetailComponent` in response to a URL such as `~/detail/11`.
|
||||
|
||||
The `HeroDetailComponent` needs a new way to obtain the hero-to-display.
|
||||
This section explains the following:
|
||||
|
||||
* Get the route that created it
|
||||
* Extract the `id` from the route
|
||||
* Acquire the hero with that `id` from the server via the `HeroService`
|
||||
|
||||
Add the following imports:
|
||||
|
||||
<code-example path="toh-pt5/src/app/hero-detail/hero-detail.component.ts" region="added-imports" header="src/app/hero-detail/hero-detail.component.ts">
|
||||
</code-example>
|
||||
|
||||
{@a hero-detail-ctor}
|
||||
|
||||
Inject the `ActivatedRoute`, `HeroService`, and `Location` services
|
||||
into the constructor, saving their values in private fields:
|
||||
|
||||
<code-example path="toh-pt5/src/app/hero-detail/hero-detail.component.ts" header="src/app/hero-detail/hero-detail.component.ts" region="ctor">
|
||||
</code-example>
|
||||
|
||||
The [`ActivatedRoute`](api/router/ActivatedRoute) holds information about the route to this instance of the `HeroDetailComponent`.
|
||||
This component is interested in the route's parameters extracted from the URL.
|
||||
The "id" parameter is the `id` of the hero to display.
|
||||
|
||||
The [`HeroService`](tutorial/toh-pt4) gets hero data from the remote server
|
||||
and this component will use it to get the hero-to-display.
|
||||
|
||||
The [`location`](api/common/Location) is an Angular service for interacting with the browser.
|
||||
You'll use it [later](#goback) to navigate back to the view that navigated here.
|
||||
|
||||
### Extract the `id` route parameter
|
||||
|
||||
In the `ngOnInit()` [lifecycle hook](guide/lifecycle-hooks#oninit)
|
||||
call `getHero()` and define it as follows.
|
||||
|
||||
<code-example path="toh-pt5/src/app/hero-detail/hero-detail.component.ts" header="src/app/hero-detail/hero-detail.component.ts" region="ngOnInit">
|
||||
</code-example>
|
||||
|
||||
The `route.snapshot` is a static image of the route information shortly after the component was created.
|
||||
|
||||
The `paramMap` is a dictionary of route parameter values extracted from the URL.
|
||||
The `"id"` key returns the `id` of the hero to fetch.
|
||||
|
||||
Route parameters are always strings.
|
||||
The JavaScript (+) operator converts the string to a number,
|
||||
which is what a hero `id` should be.
|
||||
|
||||
The browser refreshes and the app crashes with a compiler error.
|
||||
`HeroService` doesn't have a `getHero()` method.
|
||||
Add it now.
|
||||
|
||||
### Add `HeroService.getHero()`
|
||||
|
||||
Open `HeroService` and add the following `getHero()` method with the `id` after the `getHeroes()` method:
|
||||
|
||||
<code-example path="toh-pt5/src/app/hero.service.ts" region="getHero" header="src/app/hero.service.ts (getHero)">
|
||||
</code-example>
|
||||
|
||||
<div class="alert is-important">
|
||||
|
||||
Note the backticks ( ` ) that define a JavaScript
|
||||
[_template literal_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) for embedding the `id`.
|
||||
</div>
|
||||
|
||||
Like [`getHeroes()`](tutorial/toh-pt4#observable-heroservice),
|
||||
`getHero()` has an asynchronous signature.
|
||||
It returns a _mock hero_ as an `Observable`, using the RxJS `of()` function.
|
||||
|
||||
You'll be able to re-implement `getHero()` as a real `Http` request
|
||||
without having to change the `HeroDetailComponent` that calls it.
|
||||
|
||||
#### Try it
|
||||
|
||||
The browser refreshes and the app is working again.
|
||||
You can click a hero in the dashboard or in the heroes list and navigate to that hero's detail view.
|
||||
|
||||
If you paste `localhost:4200/detail/11` in the browser address bar,
|
||||
the router navigates to the detail view for the hero with `id: 11`, "Dr Nice".
|
||||
|
||||
{@a goback}
|
||||
|
||||
### Find the way back
|
||||
|
||||
By clicking the browser's back button,
|
||||
you can go back to the hero list or dashboard view,
|
||||
depending upon which sent you to the detail view.
|
||||
|
||||
It would be nice to have a button on the `HeroDetail` view that can do that.
|
||||
|
||||
Add a *go back* button to the bottom of the component template and bind it
|
||||
to the component's `goBack()` method.
|
||||
|
||||
<code-example path="toh-pt5/src/app/hero-detail/hero-detail.component.html" region="back-button" header="src/app/hero-detail/hero-detail.component.html (back button)">
|
||||
</code-example>
|
||||
|
||||
Add a `goBack()` _method_ to the component class that navigates backward one step
|
||||
in the browser's history stack
|
||||
using the `Location` service that you [injected previously](#hero-detail-ctor).
|
||||
|
||||
<code-example path="toh-pt5/src/app/hero-detail/hero-detail.component.ts" region="goBack" header="src/app/hero-detail/hero-detail.component.ts (goBack)">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
Refresh the browser and start clicking.
|
||||
Users can navigate around the app, from the dashboard to hero details and back,
|
||||
from heroes list to the mini detail to the hero details and back to the heroes again.
|
||||
|
||||
## Final code review
|
||||
|
||||
Here are the code files discussed on this page.
|
||||
|
||||
{@a approutingmodule}
|
||||
{@a appmodule}
|
||||
#### `AppRoutingModule`, `AppModule`, and `HeroService`
|
||||
|
||||
<code-tabs>
|
||||
<code-pane
|
||||
header="src/app/app-routing.module.ts"
|
||||
path="toh-pt5/src/app/app-routing.module.ts">
|
||||
</code-pane>
|
||||
<code-pane
|
||||
header="src/app/app.module.ts"
|
||||
path="toh-pt5/src/app/app.module.ts">
|
||||
</code-pane>
|
||||
<code-pane
|
||||
header="src/app/hero.service.ts"
|
||||
path="toh-pt5/src/app/hero.service.ts">
|
||||
</code-pane>
|
||||
</code-tabs>
|
||||
|
||||
{@a appcomponent}
|
||||
#### `AppComponent`
|
||||
|
||||
<code-tabs>
|
||||
<code-pane
|
||||
header="src/app/app.component.html"
|
||||
path="toh-pt5/src/app/app.component.html">
|
||||
</code-pane>
|
||||
|
||||
<code-pane
|
||||
header="src/app/app.component.css"
|
||||
path="toh-pt5/src/app/app.component.css">
|
||||
</code-pane>
|
||||
</code-tabs>
|
||||
|
||||
{@a dashboardcomponent}
|
||||
#### `DashboardComponent`
|
||||
|
||||
<code-tabs>
|
||||
<code-pane
|
||||
header="src/app/dashboard/dashboard.component.html" path="toh-pt5/src/app/dashboard/dashboard.component.html">
|
||||
</code-pane>
|
||||
|
||||
<code-pane
|
||||
header="src/app/dashboard/dashboard.component.ts" path="toh-pt5/src/app/dashboard/dashboard.component.ts">
|
||||
</code-pane>
|
||||
|
||||
<code-pane
|
||||
header="src/app/dashboard/dashboard.component.css" path="toh-pt5/src/app/dashboard/dashboard.component.css">
|
||||
</code-pane>
|
||||
</code-tabs>
|
||||
|
||||
{@a heroescomponent}
|
||||
#### `HeroesComponent`
|
||||
|
||||
<code-tabs>
|
||||
<code-pane
|
||||
header="src/app/heroes/heroes.component.html" path="toh-pt5/src/app/heroes/heroes.component.html">
|
||||
</code-pane>
|
||||
|
||||
<code-pane
|
||||
header="src/app/heroes/heroes.component.ts"
|
||||
path="toh-pt5/src/app/heroes/heroes.component.ts">
|
||||
</code-pane>
|
||||
|
||||
<code-pane
|
||||
header="src/app/heroes/heroes.component.css"
|
||||
path="toh-pt5/src/app/heroes/heroes.component.css">
|
||||
</code-pane>
|
||||
</code-tabs>
|
||||
|
||||
{@a herodetailcomponent}
|
||||
#### `HeroDetailComponent`
|
||||
|
||||
<code-tabs>
|
||||
<code-pane
|
||||
header="src/app/hero-detail/hero-detail.component.html" path="toh-pt5/src/app/hero-detail/hero-detail.component.html">
|
||||
</code-pane>
|
||||
|
||||
<code-pane
|
||||
header="src/app/hero-detail/hero-detail.component.ts" path="toh-pt5/src/app/hero-detail/hero-detail.component.ts">
|
||||
</code-pane>
|
||||
|
||||
<code-pane
|
||||
header="src/app/hero-detail/hero-detail.component.css" path="toh-pt5/src/app/hero-detail/hero-detail.component.css">
|
||||
</code-pane>
|
||||
</code-tabs>
|
||||
|
||||
## Summary
|
||||
|
||||
* You added the Angular router to navigate among different components.
|
||||
* You turned the `AppComponent` into a navigation shell with `<a>` links and a `<router-outlet>`.
|
||||
* You configured the router in an `AppRoutingModule`
|
||||
* You defined simple routes, a redirect route, and a parameterized route.
|
||||
* You used the `routerLink` directive in anchor elements.
|
||||
* You refactored a tightly-coupled master/detail view into a routed detail view.
|
||||
* You used router link parameters to navigate to the detail view of a user-selected hero.
|
||||
* You shared the `HeroService` among multiple components.
|
@ -1,32 +1,32 @@
|
||||
# Add in-app navigation with routing
|
||||
# Agregar navegación en la aplicación con enrutamiento
|
||||
|
||||
There are new requirements for the Tour of Heroes app:
|
||||
Hay nuevos requisitos para la aplicación Tour of Heroes:
|
||||
|
||||
* Add a *Dashboard* view.
|
||||
* Add the ability to navigate between the *Heroes* and *Dashboard* views.
|
||||
* When users click a hero name in either view, navigate to a detail view of the selected hero.
|
||||
* When users click a *deep link* in an email, open the detail view for a particular hero.
|
||||
* Agregar una vista de *Panel de control*.
|
||||
* Agregue la capacidad de navegar entre las vistas *Heroes* y *Dashboard*.
|
||||
* Cuando los usuarios hacen clic en el nombre de un héroe en cualquiera de las vistas, navega a una vista detallada del héroe seleccionado.
|
||||
* Cuando los usuarios hacen clic en un *enlace profundo* en un correo electrónico, abre la vista detallada de un héroe en particular.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For the sample app that this page describes, see the <live-example></live-example>.
|
||||
Para ver la aplicación de ejemplo que describe esta página, consulte el<live-example></live-example>.
|
||||
|
||||
</div>
|
||||
|
||||
When you’re done, users will be able to navigate the app like this:
|
||||
Cuando haya terminado, los usuarios podrán navegar por la aplicación de esta manera:
|
||||
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/toh/nav-diagram.png' alt="View navigations">
|
||||
</div>
|
||||
|
||||
## Add the `AppRoutingModule`
|
||||
## Agregar el `AppRoutingModule`
|
||||
|
||||
In Angular, the best practice is to load and configure the router in a separate, top-level module
|
||||
that is dedicated to routing and imported by the root `AppModule`.
|
||||
En Angular, la mejor práctica es cargar y configurar el enrutador en un módulo de nivel superior separado
|
||||
que está dedicado al enrutamiento e importado por la raíz `AppModule`.
|
||||
|
||||
By convention, the module class name is `AppRoutingModule` and it belongs in the `app-routing.module.ts` in the `src/app` folder.
|
||||
Por convención, el nombre de la clase del módulo es `AppRoutingModule` y pertenece a `app-routing.module.ts` en la carpeta `src/app`.
|
||||
|
||||
Use the CLI to generate it.
|
||||
Utiliza el CLI para generarlo.
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
ng generate module app-routing --flat --module=app
|
||||
@ -34,52 +34,51 @@ Use the CLI to generate it.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
`--flat` puts the file in `src/app` instead of its own folder.<br>
|
||||
`--module=app` tells the CLI to register it in the `imports` array of the `AppModule`.
|
||||
`--flat` coloca el archivo en `src/app` en lugar de en su propia carpeta. <br>
|
||||
`--module=app` le dice a la CLI que lo registre en la matriz de `importaciones` del `AppModule`.
|
||||
</div>
|
||||
|
||||
The generated file looks like this:
|
||||
El archivo generado se ve así:
|
||||
|
||||
<code-example path="toh-pt5/src/app/app-routing.module.0.ts" header="src/app/app-routing.module.ts (generated)">
|
||||
</code-example>
|
||||
|
||||
Replace it with the following:
|
||||
Reemplácelo con lo siguiente:
|
||||
|
||||
<code-example path="toh-pt5/src/app/app-routing.module.1.ts" header="src/app/app-routing.module.ts (updated)">
|
||||
</code-example>
|
||||
|
||||
First, `AppRoutingModule` imports `RouterModule` and `Routes` so the app can have routing functionality. The next import, `HeroesComponent`, will give the Router somewhere to go once you configure the routes.
|
||||
Primero, `AppRoutingModule` importa `RouterModule` y `Routes` para que la aplicación pueda tener funcionalidad de enrutamiento. La siguiente importación, `HeroesComponent`, le dará al enrutador un lugar adonde ir una vez que configure las rutas.
|
||||
|
||||
Notice that the `CommonModule` references and `declarations` array are unnecessary, so are no
|
||||
longer part of `AppRoutingModule`. The following sections explain the rest of the `AppRoutingModule` in more detail.
|
||||
Ten en cuenta que las referencias de CommonModule y la matriz de declaraciones son innecesarias, por lo que no
|
||||
parte más larga de `AppRoutingModule`. Las siguientes secciones explican el resto del `AppRoutingModule` con más detalle.
|
||||
|
||||
### Rutas
|
||||
|
||||
### Routes
|
||||
La siguiente parte del archivo es donde configura sus rutas.
|
||||
*Rutas* le indican al enrutador qué vista mostrar cuando un usuario hace clic en un enlace o
|
||||
pega una URL en la barra de direcciones del navegador.
|
||||
|
||||
The next part of the file is where you configure your routes.
|
||||
*Routes* tell the Router which view to display when a user clicks a link or
|
||||
pastes a URL into the browser address bar.
|
||||
|
||||
Since `AppRoutingModule` already imports `HeroesComponent`, you can use it in the `routes` array:
|
||||
Como `AppRoutingModule` ya importa `HeroesComponent`, puedes usarlo en la matriz de `rutas`:
|
||||
|
||||
<code-example path="toh-pt5/src/app/app-routing.module.ts" header="src/app/app-routing.module.ts"
|
||||
region="heroes-route">
|
||||
</code-example>
|
||||
|
||||
A typical Angular `Route` has two properties:
|
||||
Una `Ruta` típica de Angular tiene dos propiedades:
|
||||
|
||||
* `path`: a string that matches the URL in the browser address bar.
|
||||
* `component`: the component that the router should create when navigating to this route.
|
||||
* `path`: una cadena que coincide con la URL en la barra de direcciones del navegador.
|
||||
* `componet`: el componente que el enrutador debe crear al navegar a esta ruta.
|
||||
|
||||
This tells the router to match that URL to `path: 'heroes'`
|
||||
and display the `HeroesComponent` when the URL is something like `localhost:4200/heroes`.
|
||||
Esto le dice al enrutador que haga coincidir esa URL con `path: 'héroes'`
|
||||
y mostrar el `HeroesComponent` cuando la URL sea algo como `localhost:4200/heroes`.
|
||||
|
||||
### `RouterModule.forRoot()`
|
||||
|
||||
The `@NgModule` metadata initializes the router and starts it listening for browser location changes.
|
||||
Los metadatos `@NgModule` inicializan el enrutador y lo hacen escuchar los cambios de ubicación del navegador.
|
||||
|
||||
The following line adds the `RouterModule` to the `AppRoutingModule` `imports` array and
|
||||
configures it with the `routes` in one step by calling
|
||||
La siguiente línea agrega el `RouterModule` a la matriz `AppRoutingModule` `importa` y
|
||||
lo configura con las `rutas` en un solo paso llamando
|
||||
`RouterModule.forRoot()`:
|
||||
|
||||
<code-example path="toh-pt5/src/app/app-routing.module.ts" header="src/app/app-routing.module.ts" region="ngmodule-imports">
|
||||
@ -87,100 +86,99 @@ configures it with the `routes` in one step by calling
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
The method is called `forRoot()` because you configure the router at the application's root level.
|
||||
The `forRoot()` method supplies the service providers and directives needed for routing,
|
||||
and performs the initial navigation based on the current browser URL.
|
||||
El método se llama `forRoot()` porque configura el enrutador en el nivel raíz de la aplicación.
|
||||
El método `forRoot()` proporciona los proveedores de servicios y las directivas necesarias para el enrutamiento,
|
||||
y realiza la navegación inicial basada en la URL del navegador actual.
|
||||
|
||||
</div>
|
||||
|
||||
Next, `AppRoutingModule` exports `RouterModule` so it will be available throughout the app.
|
||||
A continuación, `AppRoutingModule` exporta `RouterModule` para que esté disponible en toda la aplicación.
|
||||
|
||||
<code-example path="toh-pt5/src/app/app-routing.module.ts" header="src/app/app-routing.module.ts (exports array)" region="export-routermodule">
|
||||
</code-example>
|
||||
|
||||
## Add `RouterOutlet`
|
||||
## Agregar `RouterOutlet`
|
||||
|
||||
Open the `AppComponent` template and replace the `<app-heroes>` element with a `<router-outlet>` element.
|
||||
Abre la plantilla `AppComponent` y reemplaza el elemento `<app-heroes>` con un elemento `<router-outlet>`.
|
||||
|
||||
<code-example path="toh-pt5/src/app/app.component.html" region="outlet" header="src/app/app.component.html (router-outlet)">
|
||||
</code-example>
|
||||
|
||||
The `AppComponent` template no longer needs `<app-heroes>` because the app will only display the `HeroesComponent` when the user navigates to it.
|
||||
La plantilla `AppComponent` ya no necesita `<app-heroes>` porque la aplicación solo mostrará el `HeroesComponent` cuando el usuario navegue hacia él.
|
||||
|
||||
The `<router-outlet>` tells the router where to display routed views.
|
||||
El `<router-outlet>` le dice al enrutador dónde mostrar las vistas enrutadas.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
The `RouterOutlet` is one of the router directives that became available to the `AppComponent`
|
||||
because `AppModule` imports `AppRoutingModule` which exported `RouterModule`. The `ng generate` command you ran at the start of this tutorial added this import because of the `--module=app` flag. If you manually created `app-routing.module.ts` or used a tool other than the CLI to do so, you'll need to import `AppRoutingModule` into `app.module.ts` and add it to the `imports` array of the `NgModule`.
|
||||
El `RouterOutlet` es una de las directivas del enrutador que estuvo disponible para el `AppComponent`
|
||||
porque `AppModule` importa `AppRoutingModule` que exportó `RouterModule`. El comando `ng generate` que ejecutó al comienzo de este tutorial agregó esta importación debido a la marca `--module=app`. Si creó manualmente `app-routing.module.ts` o usó una herramienta que no sea la CLI para hacerlo, deberá importar `AppRoutingModule` a `app.module.ts` y agregarlo a las `importaciones` matriz del `NgModule`.
|
||||
|
||||
</div>
|
||||
|
||||
#### Try it
|
||||
#### Pruébalo
|
||||
|
||||
You should still be running with this CLI command.
|
||||
Debería seguir ejecutando este comando CLI.
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
ng serve
|
||||
</code-example>
|
||||
|
||||
The browser should refresh and display the app title but not the list of heroes.
|
||||
El navegador debería actualizar y mostrar el título de la aplicación, pero no la lista de héroes.
|
||||
|
||||
Look at the browser's address bar.
|
||||
The URL ends in `/`.
|
||||
The route path to `HeroesComponent` is `/heroes`.
|
||||
Mira la barra de direcciones del navegador.
|
||||
La URL termina en `/`.
|
||||
La ruta de acceso a `HeroesComponent` es `/heroes`.
|
||||
|
||||
Append `/heroes` to the URL in the browser address bar.
|
||||
You should see the familiar heroes master/detail view.
|
||||
Agrega `/heroes` a la URL en la barra de direcciones del navegador.
|
||||
Debería ver la vista maestra / detallada de héroes familiares.
|
||||
|
||||
{@a routerlink}
|
||||
|
||||
## Add a navigation link (`routerLink`)
|
||||
## Agregar un enlace de navegación (`routerLink`)
|
||||
|
||||
Ideally, users should be able to click a link to navigate rather
|
||||
than pasting a route URL into the address bar.
|
||||
Idealmente, los usuarios deberían poder hacer clic en un enlace para navegar en lugar de
|
||||
que pegar una URL de ruta en la barra de direcciones.
|
||||
|
||||
Add a `<nav>` element and, within that, an anchor element that, when clicked,
|
||||
triggers navigation to the `HeroesComponent`.
|
||||
The revised `AppComponent` template looks like this:
|
||||
Agrega un elemento `<nav>` y, dentro de él, un elemento de ancla que, al hacer clic,
|
||||
activa la navegación al `HeroesComponent`.
|
||||
La plantilla `AppComponent` revisada se ve así:
|
||||
|
||||
<code-example path="toh-pt5/src/app/app.component.html" region="heroes" header="src/app/app.component.html (heroes RouterLink)">
|
||||
</code-example>
|
||||
|
||||
A [`routerLink` attribute](#routerlink) is set to `"/heroes"`,
|
||||
the string that the router matches to the route to `HeroesComponent`.
|
||||
The `routerLink` is the selector for the [`RouterLink` directive](/api/router/RouterLink)
|
||||
that turns user clicks into router navigations.
|
||||
It's another of the public directives in the `RouterModule`.
|
||||
Un [atributo `routerLink`](#routerlink) se establece en `"/heroes"`,
|
||||
la cadena que el enrutador coincide con la ruta a `HeroesComponent`.
|
||||
El `routerLink` es el selector para la [directiva `RouterLink`](/api/router/RouterLink)
|
||||
que convierte los clics del usuario en navegaciones del enrutador.
|
||||
Es otra de las directivas públicas del `RouterModule`.
|
||||
|
||||
The browser refreshes and displays the app title and heroes link,
|
||||
but not the heroes list.
|
||||
El navegador se actualiza y muestra el título de la aplicación y el enlace de héroes.
|
||||
pero no la lista de héroes.
|
||||
|
||||
Click the link.
|
||||
The address bar updates to `/heroes` and the list of heroes appears.
|
||||
Haz clic en el enlace.
|
||||
La barra de direcciones se actualiza a `/heroes` y aparece la lista de héroes.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
Make this and future navigation links look better by adding private CSS styles to `app.component.css`
|
||||
as listed in the [final code review](#appcomponent) below.
|
||||
Hace que este y los enlaces de navegación futuros se vean mejor agregando estilos CSS privados a `app.component.css`
|
||||
como se indica en la [revisión final del código](#appcomponent) a continuación.
|
||||
|
||||
</div>
|
||||
|
||||
## Agregar una vista de panel
|
||||
|
||||
## Add a dashboard view
|
||||
El enrutamiento tiene más sentido cuando hay varias vistas.
|
||||
Hasta ahora solo existe la vista de héroes.
|
||||
|
||||
Routing makes more sense when there are multiple views.
|
||||
So far there's only the heroes view.
|
||||
|
||||
Add a `DashboardComponent` using the CLI:
|
||||
Agrega un `DashboardComponent` usando la CLI:
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
ng generate component dashboard
|
||||
</code-example>
|
||||
|
||||
The CLI generates the files for the `DashboardComponent` and declares it in `AppModule`.
|
||||
La CLI genera los archivos para el `DashboardComponent` y lo declara en `AppModule`.
|
||||
|
||||
Replace the default file content in these three files as follows:
|
||||
Reemplaza el contenido del archivo predeterminado en estos tres archivos de la siguiente manera:
|
||||
|
||||
<code-tabs>
|
||||
<code-pane
|
||||
@ -196,121 +194,121 @@ Replace the default file content in these three files as follows:
|
||||
</code-pane>
|
||||
</code-tabs>
|
||||
|
||||
The _template_ presents a grid of hero name links.
|
||||
La _plantilla_ presenta una cuadrícula de enlaces de nombres de héroes.
|
||||
|
||||
* The `*ngFor` repeater creates as many links as are in the component's `heroes` array.
|
||||
* The links are styled as colored blocks by the `dashboard.component.css`.
|
||||
* The links don't go anywhere yet but [they will shortly](#hero-details).
|
||||
* El repetidor `* ngFor` crea tantos enlaces como hay en en el arreglo `heroes` del componente.
|
||||
* Los enlaces están diseñados como bloques de colores por el `dashboard.component.css`.
|
||||
* Los enlaces no van a ninguna parte todavía, pero [lo harán en breve](#hero-details).
|
||||
|
||||
The _class_ is similar to the `HeroesComponent` class.
|
||||
* It defines a `heroes` array property.
|
||||
* The constructor expects Angular to inject the `HeroService` into a private `heroService` property.
|
||||
* The `ngOnInit()` lifecycle hook calls `getHeroes()`.
|
||||
La _clase_ es similar a la clase `HeroesComponent`.
|
||||
* Define una propiedad de matriz de héroes.
|
||||
* El constructor espera que Angular inyecte el `HeroService` en una propiedad privada de `heroService`.
|
||||
* El gancho del ciclo de vida `ngOnInit()` llama a `getHeroes()`.
|
||||
|
||||
This `getHeroes()` returns the sliced list of heroes at positions 1 and 5, returning only four of the Top Heroes (2nd, 3rd, 4th, and 5th).
|
||||
Este `getHeroes()` devuelve la lista dividida de héroes en las posiciones 1 y 5, devolviendo solo cuatro de los mejores héroes (segundo, tercero, cuarto y quinto).
|
||||
|
||||
<code-example path="toh-pt5/src/app/dashboard/dashboard.component.ts" header="src/app/dashboard/dashboard.component.ts" region="getHeroes">
|
||||
</code-example>
|
||||
|
||||
### Add the dashboard route
|
||||
### Agregar la ruta del tablero(dashboard)
|
||||
|
||||
To navigate to the dashboard, the router needs an appropriate route.
|
||||
Para navegar hasta el tablero, el enrutador necesita una ruta adecuada.
|
||||
|
||||
Import the `DashboardComponent` in the `AppRoutingModule`.
|
||||
Importa el `DashboardComponent` en el `AppRoutingModule`.
|
||||
|
||||
<code-example path="toh-pt5/src/app/app-routing.module.ts" region="import-dashboard" header="src/app/app-routing.module.ts (import DashboardComponent)">
|
||||
</code-example>
|
||||
|
||||
Add a route to the `AppRoutingModule.routes` array that matches a path to the `DashboardComponent`.
|
||||
Agrega una ruta a la matriz `AppRoutingModule.routes` que coincida con una ruta al `DashboardComponent`.
|
||||
|
||||
<code-example path="toh-pt5/src/app/app-routing.module.ts" header="src/app/app-routing.module.ts" region="dashboard-route">
|
||||
</code-example>
|
||||
|
||||
### Add a default route
|
||||
### Agregar una ruta predeterminada
|
||||
|
||||
When the app starts, the browser's address bar points to the web site's root.
|
||||
That doesn't match any existing route so the router doesn't navigate anywhere.
|
||||
The space below the `<router-outlet>` is blank.
|
||||
Cuando se inicia la aplicación, la barra de direcciones del navegador apunta a la raíz del sitio web.
|
||||
Eso no coincide con ninguna ruta existente, por lo que el enrutador no navega a ninguna parte.
|
||||
El espacio debajo de `<router-outlet>` está en blanco.
|
||||
|
||||
To make the app navigate to the dashboard automatically, add the following
|
||||
route to the `AppRoutingModule.Routes` array.
|
||||
Para que la aplicación navegue al panel de control automáticamente, agreaga la siguiente
|
||||
ruta a la matriz `AppRoutingModule.Routes`.
|
||||
|
||||
<code-example path="toh-pt5/src/app/app-routing.module.ts" header="src/app/app-routing.module.ts" region="redirect-route">
|
||||
</code-example>
|
||||
|
||||
This route redirects a URL that fully matches the empty path to the route whose path is `'/dashboard'`.
|
||||
Esta ruta redirige una URL que coincide completamente con la ruta vacía a la ruta cuya ruta es `'/dashboard'`.
|
||||
|
||||
After the browser refreshes, the router loads the `DashboardComponent`
|
||||
and the browser address bar shows the `/dashboard` URL.
|
||||
Después de que el navegador se actualiza, el enrutador carga el `DashboardComponent`
|
||||
y la barra de direcciones del navegador muestra la URL `/dashboard`.
|
||||
|
||||
### Add dashboard link to the shell
|
||||
### Agregar enlace del tablero al caparazón
|
||||
|
||||
The user should be able to navigate back and forth between the
|
||||
`DashboardComponent` and the `HeroesComponent` by clicking links in the
|
||||
navigation area near the top of the page.
|
||||
El usuario debe poder navegar hacia adelante y hacia atrás entre
|
||||
`DashboardComponent` y `HeroesComponent` haciendo clic en los enlaces en el
|
||||
área de navegación cerca de la parte superior de la página.
|
||||
|
||||
Add a dashboard navigation link to the `AppComponent` shell template, just above the *Heroes* link.
|
||||
Agrega un enlace de navegación del panel de control a la plantilla de caparazón `AppComponent`, justo encima del enlace *Heroes*.
|
||||
|
||||
<code-example path="toh-pt5/src/app/app.component.html" header="src/app/app.component.html">
|
||||
</code-example>
|
||||
|
||||
After the browser refreshes you can navigate freely between the two views by clicking the links.
|
||||
Después de que se actualice el navegador, puedes navegar libremente entre las dos vistas haciendo clic en los enlaces.
|
||||
|
||||
{@a hero-details}
|
||||
## Navigating to hero details
|
||||
## Navegando a los detalles del héroe
|
||||
|
||||
The `HeroDetailsComponent` displays details of a selected hero.
|
||||
At the moment the `HeroDetailsComponent` is only visible at the bottom of the `HeroesComponent`
|
||||
El `HeroDetailsComponent` muestra los detalles de un héroe seleccionado.
|
||||
Por el momento, el `HeroDetailsComponent` solo es visible en la parte inferior del `HeroesComponent`
|
||||
|
||||
The user should be able to get to these details in three ways.
|
||||
El usuario debería poder acceder a estos detalles de tres formas.
|
||||
|
||||
1. By clicking a hero in the dashboard.
|
||||
1. By clicking a hero in the heroes list.
|
||||
1. By pasting a "deep link" URL into the browser address bar that identifies the hero to display.
|
||||
1. Haciendo clic en un héroe en el tablero.
|
||||
1. Haciendo clic en un héroe de la lista de héroes.
|
||||
1. Pegando una URL de "enlace profundo" en la barra de direcciones del navegador que identifica al héroe a mostrar.
|
||||
|
||||
In this section, you'll enable navigation to the `HeroDetailsComponent`
|
||||
and liberate it from the `HeroesComponent`.
|
||||
En esta sección, habilitará la navegación al `HeroDetailsComponent`
|
||||
y libérelo del `HeroesComponent`.
|
||||
|
||||
### Delete _hero details_ from `HeroesComponent`
|
||||
### Eliminar _detalles de héroe_ de `HeroesComponent`
|
||||
|
||||
When the user clicks a hero item in the `HeroesComponent`,
|
||||
the app should navigate to the `HeroDetailComponent`,
|
||||
replacing the heroes list view with the hero detail view.
|
||||
The heroes list view should no longer show hero details as it does now.
|
||||
Cuando el usuario hace clic en un elemento de héroe en el `HeroesComponent`,
|
||||
la aplicación debería navegar hasta el `HeroDetailComponent`,
|
||||
reemplazando la vista de lista de héroes con la vista de detalles de héroe.
|
||||
La vista de lista de héroes ya no debería mostrar los detalles de los héroes como lo hace ahora.
|
||||
|
||||
Open the `HeroesComponent` template (`heroes/heroes.component.html`) and
|
||||
delete the `<app-hero-detail>` element from the bottom.
|
||||
Abre la plantilla `HeroesComponent` (`heroes/heroes.component.html`) y
|
||||
elimine el elemento `<app-hero-detail>` de la parte inferior.
|
||||
|
||||
Clicking a hero item now does nothing.
|
||||
You'll [fix that shortly](#heroes-component-links) after you enable routing to the `HeroDetailComponent`.
|
||||
Hacer clic en un elemento de héroe ahora no hace nada.
|
||||
Lo [arreglará en breve](#heroes-component-links) después de habilitar el enrutamiento al `HeroDetailComponent`.
|
||||
|
||||
### Add a _hero detail_ route
|
||||
### Agregar una ruta _detalle del héroe_
|
||||
|
||||
A URL like `~/detail/11` would be a good URL for navigating to the *Hero Detail* view of the hero whose `id` is `11`.
|
||||
Una URL como `~/detail/11` sería una buena URL para navegar a la vista *Hero Detail* del héroe cuyo `id` es `11`.
|
||||
|
||||
Open `AppRoutingModule` and import `HeroDetailComponent`.
|
||||
Abre `AppRoutingModule` e importe `HeroDetailComponent`.
|
||||
|
||||
<code-example path="toh-pt5/src/app/app-routing.module.ts" region="import-herodetail" header="src/app/app-routing.module.ts (import HeroDetailComponent)">
|
||||
</code-example>
|
||||
|
||||
Then add a _parameterized_ route to the `AppRoutingModule.routes` array that matches the path pattern to the _hero detail_ view.
|
||||
Luego, agrega una ruta _parametrizada_ a la matriz `AppRoutingModule.routes` que coincida con el patrón de ruta de la vista _detalle del héroe_.
|
||||
|
||||
<code-example path="toh-pt5/src/app/app-routing.module.ts" header="src/app/app-routing.module.ts" region="detail-route">
|
||||
</code-example>
|
||||
|
||||
The colon (:) in the `path` indicates that `:id` is a placeholder for a specific hero `id`.
|
||||
Los dos puntos (:) en el `path` indican que `: id` es un marcador de posición para un `id` de héroe específico.
|
||||
|
||||
At this point, all application routes are in place.
|
||||
En este punto, todas las rutas de aplicación están en su lugar.
|
||||
|
||||
<code-example path="toh-pt5/src/app/app-routing.module.ts" region="routes" header="src/app/app-routing.module.ts (all routes)">
|
||||
</code-example>
|
||||
|
||||
### `DashboardComponent` hero links
|
||||
### Enlaces de héroe de `DashboardComponent`
|
||||
|
||||
The `DashboardComponent` hero links do nothing at the moment.
|
||||
Los enlaces de héroe `DashboardComponent` no hacen nada en este momento.
|
||||
|
||||
Now that the router has a route to `HeroDetailComponent`,
|
||||
fix the dashboard hero links to navigate via the _parameterized_ dashboard route.
|
||||
Ahora que el enrutador tiene una ruta a `HeroDetailComponent`,
|
||||
Corrige los enlaces del héroe del tablero para navegar a través de la ruta del tablero _parameterized_.
|
||||
|
||||
<code-example
|
||||
path="toh-pt5/src/app/dashboard/dashboard.component.html"
|
||||
@ -318,161 +316,161 @@ fix the dashboard hero links to navigate via the _parameterized_ dashboard route
|
||||
header="src/app/dashboard/dashboard.component.html (hero links)">
|
||||
</code-example>
|
||||
|
||||
You're using Angular [interpolation binding](guide/interpolation) within the `*ngFor` repeater
|
||||
to insert the current iteration's `hero.id` into each
|
||||
[`routerLink`](#routerlink).
|
||||
Estás usando el [enlace de interpolación](guide/interpolation) Angular dentro del repetidor `*ngFor`
|
||||
para insertar el `hero.id` de la iteración actual en cada
|
||||
[`enlace del enrutador`](#routerlink).
|
||||
|
||||
{@a heroes-component-links}
|
||||
### `HeroesComponent` hero links
|
||||
### Enlaces de héroe de `HeroesComponent`
|
||||
|
||||
The hero items in the `HeroesComponent` are `<li>` elements whose click events
|
||||
are bound to the component's `onSelect()` method.
|
||||
Los elementos de héroe en el `HeroesComponent` son elementos` <li> `cuyos eventos de clic
|
||||
están vinculados al método `onSelect()` del componente.
|
||||
|
||||
<code-example path="toh-pt4/src/app/heroes/heroes.component.html" region="list" header="src/app/heroes/heroes.component.html (list with onSelect)">
|
||||
</code-example>
|
||||
|
||||
Strip the `<li>` back to just its `*ngFor`,
|
||||
wrap the badge and name in an anchor element (`<a>`),
|
||||
and add a `routerLink` attribute to the anchor that
|
||||
is the same as in the dashboard template
|
||||
Quita el `<li>` de nuevo a su `* ngFor`,
|
||||
envuelve la insignia y el nombre en un elemento de anclaje (`<a>`),
|
||||
y agrega un atributo `routerLink` al ancla que
|
||||
es el mismo que en la plantilla del panel
|
||||
|
||||
<code-example path="toh-pt5/src/app/heroes/heroes.component.html" region="list" header="src/app/heroes/heroes.component.html (list with links)">
|
||||
</code-example>
|
||||
|
||||
You'll have to fix the private stylesheet (`heroes.component.css`) to make
|
||||
the list look as it did before.
|
||||
Revised styles are in the [final code review](#heroescomponent) at the bottom of this guide.
|
||||
Tendrás que arreglar la hoja de estilo privada (`heroes.component.css`) para hacer
|
||||
la lista tiene el mismo aspecto que antes.
|
||||
Los estilos revisados se encuentran en la [revisión final del código](#heroescomponent) al final de esta guía.
|
||||
|
||||
#### Remove dead code (optional)
|
||||
#### Eliminar código muerto (opcional)
|
||||
|
||||
While the `HeroesComponent` class still works,
|
||||
the `onSelect()` method and `selectedHero` property are no longer used.
|
||||
Si bien la clase `HeroesComponent` todavía funciona,
|
||||
el método `onSelect()` y la propiedad `selectedHero` ya no se utilizan.
|
||||
|
||||
It's nice to tidy up and you'll be grateful to yourself later.
|
||||
Here's the class after pruning away the dead code.
|
||||
Es agradable poner en orden y te lo agradecerás más tarde.
|
||||
Aquí está la clase después de podar el código muerto.
|
||||
|
||||
<code-example path="toh-pt5/src/app/heroes/heroes.component.ts" region="class" header="src/app/heroes/heroes.component.ts (cleaned up)">
|
||||
</code-example>
|
||||
|
||||
## Routable `HeroDetailComponent`
|
||||
## `HeroDetailComponent` enrutable
|
||||
|
||||
Previously, the parent `HeroesComponent` set the `HeroDetailComponent.hero`
|
||||
property and the `HeroDetailComponent` displayed the hero.
|
||||
Anteriormente, el padre `HeroesComponent` configuraba el `HeroDetailComponent.hero`
|
||||
propiedad y el `HeroDetailComponent` mostraba el héroe.
|
||||
|
||||
`HeroesComponent` doesn't do that anymore.
|
||||
Now the router creates the `HeroDetailComponent` in response to a URL such as `~/detail/11`.
|
||||
`HeroesComponent` ya no hace eso.
|
||||
Ahora el enrutador crea el `HeroDetailComponent` en respuesta a una URL como `~/detail/11`.
|
||||
|
||||
The `HeroDetailComponent` needs a new way to obtain the hero-to-display.
|
||||
This section explains the following:
|
||||
El `HeroDetailComponent` necesita una nueva forma de obtener el héroe a mostrar.
|
||||
Esta sección explica lo siguiente:
|
||||
|
||||
* Get the route that created it
|
||||
* Extract the `id` from the route
|
||||
* Acquire the hero with that `id` from the server via the `HeroService`
|
||||
* Obtén la ruta que lo creó
|
||||
* Extrae el `id` de la ruta
|
||||
* Adquirir el héroe con ese "id" del servidor a través de "HeroService"
|
||||
|
||||
Add the following imports:
|
||||
Agrega las siguientes importaciones:
|
||||
|
||||
<code-example path="toh-pt5/src/app/hero-detail/hero-detail.component.ts" region="added-imports" header="src/app/hero-detail/hero-detail.component.ts">
|
||||
</code-example>
|
||||
|
||||
{@a hero-detail-ctor}
|
||||
|
||||
Inject the `ActivatedRoute`, `HeroService`, and `Location` services
|
||||
into the constructor, saving their values in private fields:
|
||||
Inyecta los servicios `ActivatedRoute`, `HeroService` y `Location`
|
||||
en el constructor, guardando sus valores en campos privados:
|
||||
|
||||
<code-example path="toh-pt5/src/app/hero-detail/hero-detail.component.ts" header="src/app/hero-detail/hero-detail.component.ts" region="ctor">
|
||||
</code-example>
|
||||
|
||||
The [`ActivatedRoute`](api/router/ActivatedRoute) holds information about the route to this instance of the `HeroDetailComponent`.
|
||||
This component is interested in the route's parameters extracted from the URL.
|
||||
The "id" parameter is the `id` of the hero to display.
|
||||
El [`ActivatedRoute`](api/router/ActivatedRoute) contiene información sobre la ruta a esta instancia del `HeroDetailComponent`.
|
||||
Este componente está interesado en los parámetros de la ruta extraídos de la URL.
|
||||
El parámetro "id" es el `id` del héroe que se mostrará.
|
||||
|
||||
The [`HeroService`](tutorial/toh-pt4) gets hero data from the remote server
|
||||
and this component will use it to get the hero-to-display.
|
||||
El [`HeroService`](tutorial/toh-pt4) obtiene los datos del héroe del servidor remoto
|
||||
y este componente lo usará para mostrar el héroe.
|
||||
|
||||
The [`location`](api/common/Location) is an Angular service for interacting with the browser.
|
||||
You'll use it [later](#goback) to navigate back to the view that navigated here.
|
||||
La [`ubicación`](api/common/Location) es un servicio Angular para interactuar con el navegador.
|
||||
Lo usarás [más tarde](#goback) para volver a la vista que navegó aquí.
|
||||
|
||||
### Extract the `id` route parameter
|
||||
### Extrae el parámetro de ruta `id`
|
||||
|
||||
In the `ngOnInit()` [lifecycle hook](guide/lifecycle-hooks#oninit)
|
||||
call `getHero()` and define it as follows.
|
||||
En el `ngOnInit()` [gancho del ciclo de vida](guide/lifecycle-hooks#oninit)
|
||||
llama a `getHero()` y defínalo de la siguiente manera.
|
||||
|
||||
<code-example path="toh-pt5/src/app/hero-detail/hero-detail.component.ts" header="src/app/hero-detail/hero-detail.component.ts" region="ngOnInit">
|
||||
</code-example>
|
||||
|
||||
The `route.snapshot` is a static image of the route information shortly after the component was created.
|
||||
`Route.snapshot` es una imagen estática de la información de la ruta poco después de que se creó el componente.
|
||||
|
||||
The `paramMap` is a dictionary of route parameter values extracted from the URL.
|
||||
The `"id"` key returns the `id` of the hero to fetch.
|
||||
El `paramMap` es un diccionario de valores de parámetros de ruta extraídos de la URL.
|
||||
La clave `"id"` devuelve el `id` del héroe a buscar.
|
||||
|
||||
Route parameters are always strings.
|
||||
The JavaScript (+) operator converts the string to a number,
|
||||
which is what a hero `id` should be.
|
||||
Los parámetros de ruta son siempre cadenas.
|
||||
El operador JavaScript (+) convierte la cadena en un número,
|
||||
que es lo que debería ser un "id" de héroe.
|
||||
|
||||
The browser refreshes and the app crashes with a compiler error.
|
||||
`HeroService` doesn't have a `getHero()` method.
|
||||
Add it now.
|
||||
El navegador se actualiza y la aplicación se bloquea con un error del compilador.
|
||||
`HeroService` no tiene un método `getHero()`.
|
||||
Agréguelo ahora.
|
||||
|
||||
### Add `HeroService.getHero()`
|
||||
### Agregar `HeroService.getHero ()`
|
||||
|
||||
Open `HeroService` and add the following `getHero()` method with the `id` after the `getHeroes()` method:
|
||||
Abre `HeroService` y agrega el siguiente método `getHero()` con el `id` después del método `getHeroes ()`:
|
||||
|
||||
<code-example path="toh-pt5/src/app/hero.service.ts" region="getHero" header="src/app/hero.service.ts (getHero)">
|
||||
</code-example>
|
||||
|
||||
<div class="alert is-important">
|
||||
|
||||
Note the backticks ( ` ) that define a JavaScript
|
||||
[_template literal_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) for embedding the `id`.
|
||||
Ten en cuenta las comillas invertidas (`) que definen un JavaScript
|
||||
[_plantilla literal_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) para incrustar el `id`.
|
||||
|
||||
</div>
|
||||
|
||||
Like [`getHeroes()`](tutorial/toh-pt4#observable-heroservice),
|
||||
`getHero()` has an asynchronous signature.
|
||||
It returns a _mock hero_ as an `Observable`, using the RxJS `of()` function.
|
||||
Como [`getHeroes()`](tutorial/toh-pt4#observable-heroservice),
|
||||
`getHero()` tiene una firma asincrónica.
|
||||
Devuelve un _mock hero_ como un `Observable`, usando la función RxJS `of()`.
|
||||
|
||||
You'll be able to re-implement `getHero()` as a real `Http` request
|
||||
without having to change the `HeroDetailComponent` that calls it.
|
||||
Podrá volver a implementar `getHero()` como una solicitud real de `Http`
|
||||
sin tener que cambiar el `HeroDetailComponent` que lo llama.
|
||||
|
||||
#### Try it
|
||||
#### Pruébalo
|
||||
|
||||
The browser refreshes and the app is working again.
|
||||
You can click a hero in the dashboard or in the heroes list and navigate to that hero's detail view.
|
||||
El navegador se actualiza y la aplicación vuelve a funcionar.
|
||||
Puedes hacer clic en un héroe en el tablero o en la lista de héroes y navegar hasta la vista de detalles de ese héroe.
|
||||
|
||||
If you paste `localhost:4200/detail/11` in the browser address bar,
|
||||
the router navigates to the detail view for the hero with `id: 11`, "Dr Nice".
|
||||
Si pega `localhost:4200/detail/11` en la barra de direcciones del navegador,
|
||||
el enrutador navega a la vista detallada del héroe con `id: 11`," Dr Nice ".
|
||||
|
||||
{@a goback}
|
||||
|
||||
### Find the way back
|
||||
### Encuentra el camino de regreso
|
||||
|
||||
By clicking the browser's back button,
|
||||
you can go back to the hero list or dashboard view,
|
||||
depending upon which sent you to the detail view.
|
||||
Al hacer clic en el botón Atrás del navegador,
|
||||
puede volver a la lista de héroes o la vista del panel,
|
||||
dependiendo de cuál le envió a la vista detallada.
|
||||
|
||||
It would be nice to have a button on the `HeroDetail` view that can do that.
|
||||
Sería bueno tener un botón en la vista `HeroDetail` que pueda hacer eso.
|
||||
|
||||
Add a *go back* button to the bottom of the component template and bind it
|
||||
to the component's `goBack()` method.
|
||||
Agrega un botón *volver* en la parte inferior de la plantilla del componente y vincúlalo
|
||||
al método `goBack()` del componente.
|
||||
|
||||
<code-example path="toh-pt5/src/app/hero-detail/hero-detail.component.html" region="back-button" header="src/app/hero-detail/hero-detail.component.html (back button)">
|
||||
</code-example>
|
||||
|
||||
Add a `goBack()` _method_ to the component class that navigates backward one step
|
||||
in the browser's history stack
|
||||
using the `Location` service that you [injected previously](#hero-detail-ctor).
|
||||
Agrega un método `goBack()` a la clase de componente que navega hacia atrás un paso
|
||||
en la pila de historial del navegador
|
||||
usando el servicio `Location` que [inyectaste previamente](#hero-detail-ctor).
|
||||
|
||||
<code-example path="toh-pt5/src/app/hero-detail/hero-detail.component.ts" region="goBack" header="src/app/hero-detail/hero-detail.component.ts (goBack)">
|
||||
|
||||
</code-example>
|
||||
|
||||
Actualiza el navegador y comience a hacer clic.
|
||||
Los usuarios pueden navegar por la aplicación, desde el panel hasta los detalles del héroe y viceversa,
|
||||
de la lista de héroes al mini detalle a los detalles del héroe y de regreso a los héroes nuevamente.
|
||||
|
||||
Refresh the browser and start clicking.
|
||||
Users can navigate around the app, from the dashboard to hero details and back,
|
||||
from heroes list to the mini detail to the hero details and back to the heroes again.
|
||||
## Revisión final del código
|
||||
|
||||
## Final code review
|
||||
|
||||
Here are the code files discussed on this page.
|
||||
Aquí están los archivos de código discutidos en esta página.
|
||||
|
||||
{@a approutingmodule}
|
||||
{@a appmodule}
|
||||
@ -561,13 +559,13 @@ Here are the code files discussed on this page.
|
||||
</code-pane>
|
||||
</code-tabs>
|
||||
|
||||
## Summary
|
||||
## Resumen
|
||||
|
||||
* You added the Angular router to navigate among different components.
|
||||
* You turned the `AppComponent` into a navigation shell with `<a>` links and a `<router-outlet>`.
|
||||
* You configured the router in an `AppRoutingModule`
|
||||
* You defined simple routes, a redirect route, and a parameterized route.
|
||||
* You used the `routerLink` directive in anchor elements.
|
||||
* You refactored a tightly-coupled master/detail view into a routed detail view.
|
||||
* You used router link parameters to navigate to the detail view of a user-selected hero.
|
||||
* You shared the `HeroService` among multiple components.
|
||||
* Agregó el enrutador Angular para navegar entre diferentes componentes.
|
||||
* Convirtió el `AppComponent` en un caparazón de navegación con enlaces `<a>`y un `<router-outlet>`.
|
||||
* Configuró el enrutador en un `AppRoutingModule`
|
||||
* Definió rutas simples, una ruta de redireccionamiento y una ruta parametrizada.
|
||||
* Usó la directiva `routerLink` en elementos de anclaje.
|
||||
* Refactorizó una vista maestra/detallada estrechamente acoplada en una vista de detalle enrutada.
|
||||
* Usó parámetros de enlace del enrutador para navegar a la vista detallada de un héroe seleccionado por el usuario.
|
||||
* Compartió el "HeroService" entre varios componentes.
|
||||
|
621
aio/content/tutorial/toh-pt6.en.md
Normal file
621
aio/content/tutorial/toh-pt6.en.md
Normal file
@ -0,0 +1,621 @@
|
||||
# Get data from a server
|
||||
|
||||
In this tutorial, you'll add the following data persistence features with help from
|
||||
Angular's `HttpClient`.
|
||||
|
||||
* The `HeroService` gets hero data with HTTP requests.
|
||||
* Users can add, edit, and delete heroes and save these changes over HTTP.
|
||||
* Users can search for heroes by name.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For the sample app that this page describes, see the <live-example></live-example>.
|
||||
|
||||
</div>
|
||||
|
||||
## Enable HTTP services
|
||||
|
||||
`HttpClient` is Angular's mechanism for communicating with a remote server over HTTP.
|
||||
|
||||
Make `HttpClient` available everywhere in the app in two steps. First, add it to the root `AppModule` by importing it:
|
||||
|
||||
<code-example path="toh-pt6/src/app/app.module.ts" region="import-http-client" header="src/app/app.module.ts (HttpClientModule import)">
|
||||
</code-example>
|
||||
|
||||
Next, still in the `AppModule`, add `HttpClient` to the `imports` array:
|
||||
|
||||
<code-example path="toh-pt6/src/app/app.module.ts" region="import-httpclientmodule" header="src/app/app.module.ts (imports array excerpt)">
|
||||
</code-example>
|
||||
|
||||
|
||||
## Simulate a data server
|
||||
|
||||
This tutorial sample mimics communication with a remote data server by using the
|
||||
[In-memory Web API](https://github.com/angular/in-memory-web-api "In-memory Web API") module.
|
||||
|
||||
After installing the module, the app will make requests to and receive responses from the `HttpClient`
|
||||
without knowing that the *In-memory Web API* is intercepting those requests,
|
||||
applying them to an in-memory data store, and returning simulated responses.
|
||||
|
||||
By using the In-memory Web API, you won't have to set up a server to learn about `HttpClient`.
|
||||
|
||||
<div class="alert is-important">
|
||||
|
||||
**Important:** the In-memory Web API module has nothing to do with HTTP in Angular.
|
||||
|
||||
If you're just reading this tutorial to learn about `HttpClient`, you can [skip over](#import-heroes) this step.
|
||||
If you're coding along with this tutorial, stay here and add the In-memory Web API now.
|
||||
|
||||
</div>
|
||||
|
||||
Install the In-memory Web API package from npm with the following command:
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
npm install angular-in-memory-web-api --save
|
||||
</code-example>
|
||||
|
||||
In the `AppModule`, import the `HttpClientInMemoryWebApiModule` and the `InMemoryDataService` class,
|
||||
which you will create in a moment.
|
||||
|
||||
<code-example path="toh-pt6/src/app/app.module.ts" region="import-in-mem-stuff" header="src/app/app.module.ts (In-memory Web API imports)">
|
||||
</code-example>
|
||||
|
||||
After the `HttpClientModule`, add the `HttpClientInMemoryWebApiModule`
|
||||
to the `AppModule` `imports` array and configure it with the `InMemoryDataService`.
|
||||
|
||||
<code-example path="toh-pt6/src/app/app.module.ts" header="src/app/app.module.ts (imports array excerpt)" region="in-mem-web-api-imports">
|
||||
</code-example>
|
||||
|
||||
The `forRoot()` configuration method takes an `InMemoryDataService` class
|
||||
that primes the in-memory database.
|
||||
|
||||
Generate the class `src/app/in-memory-data.service.ts` with the following command:
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
ng generate service InMemoryData
|
||||
</code-example>
|
||||
|
||||
Replace the default contents of `in-memory-data.service.ts` with the following:
|
||||
|
||||
<code-example path="toh-pt6/src/app/in-memory-data.service.ts" region="init" header="src/app/in-memory-data.service.ts"></code-example>
|
||||
|
||||
The `in-memory-data.service.ts` file will take over the function of `mock-heroes.ts`.
|
||||
However, don't delete `mock-heroes.ts` yet, as you still need it for a few more steps of this tutorial.
|
||||
|
||||
When the server is ready, you'll detach the In-memory Web API, and the app's requests will go through to the server.
|
||||
|
||||
|
||||
{@a import-heroes}
|
||||
## Heroes and HTTP
|
||||
|
||||
In the `HeroService`, import `HttpClient` and `HttpHeaders`:
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" region="import-httpclient" header="src/app/hero.service.ts (import HTTP symbols)">
|
||||
</code-example>
|
||||
|
||||
Still in the `HeroService`, inject `HttpClient` into the constructor in a private property called `http`.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" header="src/app/hero.service.ts" region="ctor" >
|
||||
</code-example>
|
||||
|
||||
Notice that you keep injecting the `MessageService` but since you'll call it so frequently, wrap it in a private `log()` method:
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" header="src/app/hero.service.ts" region="log" >
|
||||
</code-example>
|
||||
|
||||
Define the `heroesUrl` of the form `:base/:collectionName` with the address of the heroes resource on the server.
|
||||
Here `base` is the resource to which requests are made,
|
||||
and `collectionName` is the heroes data object in the `in-memory-data-service.ts`.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" header="src/app/hero.service.ts" region="heroesUrl" >
|
||||
</code-example>
|
||||
|
||||
### Get heroes with `HttpClient`
|
||||
|
||||
The current `HeroService.getHeroes()`
|
||||
uses the RxJS `of()` function to return an array of mock heroes
|
||||
as an `Observable<Hero[]>`.
|
||||
|
||||
<code-example path="toh-pt4/src/app/hero.service.ts" region="getHeroes-1" header="src/app/hero.service.ts (getHeroes with RxJs 'of()')">
|
||||
</code-example>
|
||||
|
||||
Convert that method to use `HttpClient` as follows:
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" header="src/app/hero.service.ts" region="getHeroes-1">
|
||||
</code-example>
|
||||
|
||||
Refresh the browser. The hero data should successfully load from the
|
||||
mock server.
|
||||
|
||||
You've swapped `of()` for `http.get()` and the app keeps working without any other changes
|
||||
because both functions return an `Observable<Hero[]>`.
|
||||
|
||||
### `HttpClient` methods return one value
|
||||
|
||||
All `HttpClient` methods return an RxJS `Observable` of something.
|
||||
|
||||
HTTP is a request/response protocol.
|
||||
You make a request, it returns a single response.
|
||||
|
||||
In general, an observable _can_ return multiple values over time.
|
||||
An observable from `HttpClient` always emits a single value and then completes, never to emit again.
|
||||
|
||||
This particular `HttpClient.get()` call returns an `Observable<Hero[]>`; that is, "_an observable of hero arrays_". In practice, it will only return a single hero array.
|
||||
|
||||
### `HttpClient.get()` returns response data
|
||||
|
||||
`HttpClient.get()` returns the body of the response as an untyped JSON object by default.
|
||||
Applying the optional type specifier, `<Hero[]>` , adds TypeScript capabilities, which reduce errors during compile time.
|
||||
|
||||
The server's data API determines the shape of the JSON data.
|
||||
The _Tour of Heroes_ data API returns the hero data as an array.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
Other APIs may bury the data that you want within an object.
|
||||
You might have to dig that data out by processing the `Observable` result
|
||||
with the RxJS `map()` operator.
|
||||
|
||||
Although not discussed here, there's an example of `map()` in the `getHeroNo404()`
|
||||
method included in the sample source code.
|
||||
|
||||
</div>
|
||||
|
||||
### Error handling
|
||||
|
||||
Things go wrong, especially when you're getting data from a remote server.
|
||||
The `HeroService.getHeroes()` method should catch errors and do something appropriate.
|
||||
|
||||
To catch errors, you **"pipe" the observable** result from `http.get()` through an RxJS `catchError()` operator.
|
||||
|
||||
Import the `catchError` symbol from `rxjs/operators`, along with some other operators you'll need later.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" header="src/app/hero.service.ts" region="import-rxjs-operators">
|
||||
</code-example>
|
||||
|
||||
Now extend the observable result with the `pipe()` method and
|
||||
give it a `catchError()` operator.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" region="getHeroes-2" header="src/app/hero.service.ts">
|
||||
</code-example>
|
||||
|
||||
The `catchError()` operator intercepts an **`Observable` that failed**.
|
||||
It passes the error an error handler that can do what it wants with the error.
|
||||
|
||||
The following `handleError()` method reports the error and then returns an
|
||||
innocuous result so that the application keeps working.
|
||||
|
||||
#### `handleError`
|
||||
|
||||
The following `handleError()` will be shared by many `HeroService` methods
|
||||
so it's generalized to meet their different needs.
|
||||
|
||||
Instead of handling the error directly, it returns an error handler function to `catchError` that it
|
||||
has configured with both the name of the operation that failed and a safe return value.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" header="src/app/hero.service.ts" region="handleError">
|
||||
</code-example>
|
||||
|
||||
After reporting the error to the console, the handler constructs
|
||||
a user friendly message and returns a safe value to the app so the app can keep working.
|
||||
|
||||
Because each service method returns a different kind of `Observable` result,
|
||||
`handleError()` takes a type parameter so it can return the safe value as the type that the app expects.
|
||||
|
||||
### Tap into the Observable
|
||||
|
||||
The `HeroService` methods will **tap** into the flow of observable values
|
||||
and send a message, via the `log()` method, to the message area at the bottom of the page.
|
||||
|
||||
They'll do that with the RxJS `tap()` operator,
|
||||
which looks at the observable values, does something with those values,
|
||||
and passes them along.
|
||||
The `tap()` call back doesn't touch the values themselves.
|
||||
|
||||
Here is the final version of `getHeroes()` with the `tap()` that logs the operation.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" header="src/app/hero.service.ts" region="getHeroes" >
|
||||
</code-example>
|
||||
|
||||
### Get hero by id
|
||||
|
||||
Most web APIs support a _get by id_ request in the form `:baseURL/:id`.
|
||||
|
||||
Here, the _base URL_ is the `heroesURL` defined in the [Heroes and HTTP](tutorial/toh-pt6#import-heroes) section (`api/heroes`) and _id_ is
|
||||
the number of the hero that you want to retrieve. For example, `api/heroes/11`.
|
||||
|
||||
Update the `HeroService` `getHero()` method with the following to make that request:
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" region="getHero" header="src/app/hero.service.ts"></code-example>
|
||||
|
||||
There are three significant differences from `getHeroes()`:
|
||||
|
||||
* `getHero()` constructs a request URL with the desired hero's id.
|
||||
* The server should respond with a single hero rather than an array of heroes.
|
||||
* `getHero()` returns an `Observable<Hero>` ("_an observable of Hero objects_")
|
||||
rather than an observable of hero _arrays_ .
|
||||
|
||||
## Update heroes
|
||||
|
||||
Edit a hero's name in the hero detail view.
|
||||
As you type, the hero name updates the heading at the top of the page.
|
||||
But when you click the "go back button", the changes are lost.
|
||||
|
||||
If you want changes to persist, you must write them back to
|
||||
the server.
|
||||
|
||||
At the end of the hero detail template, add a save button with a `click` event
|
||||
binding that invokes a new component method named `save()`.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero-detail/hero-detail.component.html" region="save" header="src/app/hero-detail/hero-detail.component.html (save)"></code-example>
|
||||
|
||||
In the `HeroDetail` component class, add the following `save()` method, which persists hero name changes using the hero service
|
||||
`updateHero()` method and then navigates back to the previous view.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero-detail/hero-detail.component.ts" region="save" header="src/app/hero-detail/hero-detail.component.ts (save)"></code-example>
|
||||
|
||||
#### Add `HeroService.updateHero()`
|
||||
|
||||
The overall structure of the `updateHero()` method is similar to that of
|
||||
`getHeroes()`, but it uses `http.put()` to persist the changed hero
|
||||
on the server. Add the following to the `HeroService`.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" region="updateHero" header="src/app/hero.service.ts (update)">
|
||||
</code-example>
|
||||
|
||||
The `HttpClient.put()` method takes three parameters:
|
||||
* the URL
|
||||
* the data to update (the modified hero in this case)
|
||||
* options
|
||||
|
||||
The URL is unchanged. The heroes web API knows which hero to update by looking at the hero's `id`.
|
||||
|
||||
The heroes web API expects a special header in HTTP save requests.
|
||||
That header is in the `httpOptions` constant defined in the `HeroService`. Add the following to the `HeroService` class.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" region="http-options" header="src/app/hero.service.ts">
|
||||
</code-example>
|
||||
|
||||
Refresh the browser, change a hero name and save your change. The `save()`
|
||||
method in `HeroDetailComponent` navigates to the previous view.
|
||||
The hero now appears in the list with the changed name.
|
||||
|
||||
|
||||
## Add a new hero
|
||||
|
||||
To add a hero, this app only needs the hero's name. You can use an `<input>`
|
||||
element paired with an add button.
|
||||
|
||||
Insert the following into the `HeroesComponent` template, just after
|
||||
the heading:
|
||||
|
||||
<code-example path="toh-pt6/src/app/heroes/heroes.component.html" region="add" header="src/app/heroes/heroes.component.html (add)"></code-example>
|
||||
|
||||
In response to a click event, call the component's click handler, `add()`, and then
|
||||
clear the input field so that it's ready for another name. Add the following to the
|
||||
`HeroesComponent` class:
|
||||
|
||||
<code-example path="toh-pt6/src/app/heroes/heroes.component.ts" region="add" header="src/app/heroes/heroes.component.ts (add)"></code-example>
|
||||
|
||||
When the given name is non-blank, the handler creates a `Hero`-like object
|
||||
from the name (it's only missing the `id`) and passes it to the services `addHero()` method.
|
||||
|
||||
When `addHero()` saves successfully, the `subscribe()` callback
|
||||
receives the new hero and pushes it into to the `heroes` list for display.
|
||||
|
||||
Add the following `addHero()` method to the `HeroService` class.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" region="addHero" header="src/app/hero.service.ts (addHero)"></code-example>
|
||||
|
||||
`addHero()` differs from `updateHero()` in two ways:
|
||||
|
||||
* It calls `HttpClient.post()` instead of `put()`.
|
||||
* It expects the server to generate an id for the new hero,
|
||||
which it returns in the `Observable<Hero>` to the caller.
|
||||
|
||||
Refresh the browser and add some heroes.
|
||||
|
||||
## Delete a hero
|
||||
|
||||
Each hero in the heroes list should have a delete button.
|
||||
|
||||
Add the following button element to the `HeroesComponent` template, after the hero
|
||||
name in the repeated `<li>` element.
|
||||
|
||||
<code-example path="toh-pt6/src/app/heroes/heroes.component.html" header="src/app/heroes/heroes.component.html" region="delete"></code-example>
|
||||
|
||||
The HTML for the list of heroes should look like this:
|
||||
|
||||
<code-example path="toh-pt6/src/app/heroes/heroes.component.html" region="list" header="src/app/heroes/heroes.component.html (list of heroes)"></code-example>
|
||||
|
||||
To position the delete button at the far right of the hero entry,
|
||||
add some CSS to the `heroes.component.css`. You'll find that CSS
|
||||
in the [final review code](#heroescomponent) below.
|
||||
|
||||
Add the `delete()` handler to the component class.
|
||||
|
||||
<code-example path="toh-pt6/src/app/heroes/heroes.component.ts" region="delete" header="src/app/heroes/heroes.component.ts (delete)"></code-example>
|
||||
|
||||
Although the component delegates hero deletion to the `HeroService`,
|
||||
it remains responsible for updating its own list of heroes.
|
||||
The component's `delete()` method immediately removes the _hero-to-delete_ from that list,
|
||||
anticipating that the `HeroService` will succeed on the server.
|
||||
|
||||
There's really nothing for the component to do with the `Observable` returned by
|
||||
`heroService.delete()` **but it must subscribe anyway**.
|
||||
|
||||
<div class="alert is-important">
|
||||
|
||||
If you neglect to `subscribe()`, the service will not send the delete request to the server.
|
||||
As a rule, an `Observable` _does nothing_ until something subscribes.
|
||||
|
||||
Confirm this for yourself by temporarily removing the `subscribe()`,
|
||||
clicking "Dashboard", then clicking "Heroes".
|
||||
You'll see the full list of heroes again.
|
||||
|
||||
</div>
|
||||
|
||||
Next, add a `deleteHero()` method to `HeroService` like this.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" region="deleteHero" header="src/app/hero.service.ts (delete)"></code-example>
|
||||
|
||||
Note the following key points:
|
||||
|
||||
* `deleteHero()` calls `HttpClient.delete()`.
|
||||
* The URL is the heroes resource URL plus the `id` of the hero to delete.
|
||||
* You don't send data as you did with `put()` and `post()`.
|
||||
* You still send the `httpOptions`.
|
||||
|
||||
Refresh the browser and try the new delete functionality.
|
||||
|
||||
## Search by name
|
||||
|
||||
In this last exercise, you learn to chain `Observable` operators together
|
||||
so you can minimize the number of similar HTTP requests
|
||||
and consume network bandwidth economically.
|
||||
|
||||
You will add a heroes search feature to the Dashboard.
|
||||
As the user types a name into a search box,
|
||||
you'll make repeated HTTP requests for heroes filtered by that name.
|
||||
Your goal is to issue only as many requests as necessary.
|
||||
|
||||
#### `HeroService.searchHeroes()`
|
||||
|
||||
Start by adding a `searchHeroes()` method to the `HeroService`.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" region="searchHeroes" header="src/app/hero.service.ts">
|
||||
</code-example>
|
||||
|
||||
The method returns immediately with an empty array if there is no search term.
|
||||
The rest of it closely resembles `getHeroes()`, the only significant difference being
|
||||
the URL, which includes a query string with the search term.
|
||||
|
||||
### Add search to the Dashboard
|
||||
|
||||
Open the `DashboardComponent` template and
|
||||
add the hero search element, `<app-hero-search>`, to the bottom of the markup.
|
||||
|
||||
<code-example path="toh-pt6/src/app/dashboard/dashboard.component.html" header="src/app/dashboard/dashboard.component.html"></code-example>
|
||||
|
||||
This template looks a lot like the `*ngFor` repeater in the `HeroesComponent` template.
|
||||
|
||||
For this to work, the next step is to add a component with a selector that matches `<app-hero-search>`.
|
||||
|
||||
|
||||
### Create `HeroSearchComponent`
|
||||
|
||||
Create a `HeroSearchComponent` with the CLI.
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
ng generate component hero-search
|
||||
</code-example>
|
||||
|
||||
The CLI generates the three `HeroSearchComponent` files and adds the component to the `AppModule` declarations.
|
||||
|
||||
Replace the generated `HeroSearchComponent` template with an `<input>` and a list of matching search results, as follows.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero-search/hero-search.component.html" header="src/app/hero-search/hero-search.component.html"></code-example>
|
||||
|
||||
Add private CSS styles to `hero-search.component.css`
|
||||
as listed in the [final code review](#herosearchcomponent) below.
|
||||
|
||||
As the user types in the search box, an input event binding calls the
|
||||
component's `search()` method with the new search box value.
|
||||
|
||||
{@a asyncpipe}
|
||||
|
||||
### `AsyncPipe`
|
||||
|
||||
The `*ngFor` repeats hero objects. Notice that the `*ngFor` iterates over a list called `heroes$`, not `heroes`. The `$` is a convention that indicates `heroes$` is an `Observable`, not an array.
|
||||
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero-search/hero-search.component.html" header="src/app/hero-search/hero-search.component.html" region="async"></code-example>
|
||||
|
||||
Since `*ngFor` can't do anything with an `Observable`, use the
|
||||
pipe character (`|`) followed by `async`. This identifies Angular's `AsyncPipe` and subscribes to an `Observable` automatically so you won't have to
|
||||
do so in the component class.
|
||||
|
||||
### Edit the `HeroSearchComponent` class
|
||||
|
||||
Replace the generated `HeroSearchComponent` class and metadata as follows.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero-search/hero-search.component.ts" header="src/app/hero-search/hero-search.component.ts"></code-example>
|
||||
|
||||
Notice the declaration of `heroes$` as an `Observable`:
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero-search/hero-search.component.ts" header="src/app/hero-search/hero-search.component.ts" region="heroes-stream">
|
||||
</code-example>
|
||||
|
||||
You'll set it in [`ngOnInit()`](#search-pipe).
|
||||
Before you do, focus on the definition of `searchTerms`.
|
||||
|
||||
### The `searchTerms` RxJS subject
|
||||
|
||||
The `searchTerms` property is an RxJS `Subject`.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero-search/hero-search.component.ts" header="src/app/hero-search/hero-search.component.ts" region="searchTerms"></code-example>
|
||||
|
||||
A `Subject` is both a source of observable values and an `Observable` itself.
|
||||
You can subscribe to a `Subject` as you would any `Observable`.
|
||||
|
||||
You can also push values into that `Observable` by calling its `next(value)` method
|
||||
as the `search()` method does.
|
||||
|
||||
The event binding to the textbox's `input` event calls the `search()` method.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero-search/hero-search.component.html" header="src/app/hero-search/hero-search.component.html" region="input"></code-example>
|
||||
|
||||
Every time the user types in the textbox, the binding calls `search()` with the textbox value, a "search term".
|
||||
The `searchTerms` becomes an `Observable` emitting a steady stream of search terms.
|
||||
|
||||
{@a search-pipe}
|
||||
|
||||
### Chaining RxJS operators
|
||||
|
||||
Passing a new search term directly to the `searchHeroes()` after every user keystroke would create an excessive amount of HTTP requests,
|
||||
taxing server resources and burning through data plans.
|
||||
|
||||
Instead, the `ngOnInit()` method pipes the `searchTerms` observable through a sequence of RxJS operators that reduce the number of calls to the `searchHeroes()`,
|
||||
ultimately returning an observable of timely hero search results (each a `Hero[]`).
|
||||
|
||||
Here's a closer look at the code.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero-search/hero-search.component.ts" header="src/app/hero-search/hero-search.component.ts" region="search">
|
||||
</code-example>
|
||||
|
||||
Each operator works as follows:
|
||||
|
||||
* `debounceTime(300)` waits until the flow of new string events pauses for 300 milliseconds
|
||||
before passing along the latest string. You'll never make requests more frequently than 300ms.
|
||||
|
||||
* `distinctUntilChanged()` ensures that a request is sent only if the filter text changed.
|
||||
|
||||
* `switchMap()` calls the search service for each search term that makes it through `debounce()` and `distinctUntilChanged()`.
|
||||
It cancels and discards previous search observables, returning only the latest search service observable.
|
||||
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
With the [switchMap operator](http://www.learnrxjs.io/operators/transformation/switchmap.html),
|
||||
every qualifying key event can trigger an `HttpClient.get()` method call.
|
||||
Even with a 300ms pause between requests, you could have multiple HTTP requests in flight
|
||||
and they may not return in the order sent.
|
||||
|
||||
`switchMap()` preserves the original request order while returning only the observable from the most recent HTTP method call.
|
||||
Results from prior calls are canceled and discarded.
|
||||
|
||||
Note that canceling a previous `searchHeroes()` Observable
|
||||
doesn't actually abort a pending HTTP request.
|
||||
Unwanted results are simply discarded before they reach your application code.
|
||||
|
||||
</div>
|
||||
|
||||
Remember that the component _class_ does not subscribe to the `heroes$` _observable_.
|
||||
That's the job of the [`AsyncPipe`](#asyncpipe) in the template.
|
||||
|
||||
#### Try it
|
||||
|
||||
Run the app again. In the *Dashboard*, enter some text in the search box.
|
||||
If you enter characters that match any existing hero names, you'll see something like this.
|
||||
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/toh/toh-hero-search.png' alt="Hero Search Component">
|
||||
</div>
|
||||
|
||||
## Final code review
|
||||
|
||||
Here are the code files discussed on this page (all in the `src/app/` folder).
|
||||
|
||||
{@a heroservice}
|
||||
{@a inmemorydataservice}
|
||||
{@a appmodule}
|
||||
#### `HeroService`, `InMemoryDataService`, `AppModule`
|
||||
|
||||
<code-tabs>
|
||||
<code-pane
|
||||
header="hero.service.ts"
|
||||
path="toh-pt6/src/app/hero.service.ts">
|
||||
</code-pane>
|
||||
<code-pane
|
||||
header="in-memory-data.service.ts"
|
||||
path="toh-pt6/src/app/in-memory-data.service.ts">
|
||||
</code-pane>
|
||||
<code-pane
|
||||
header="app.module.ts"
|
||||
path="toh-pt6/src/app/app.module.ts">
|
||||
</code-pane>
|
||||
</code-tabs>
|
||||
|
||||
{@a heroescomponent}
|
||||
#### `HeroesComponent`
|
||||
|
||||
<code-tabs>
|
||||
<code-pane
|
||||
header="heroes/heroes.component.html"
|
||||
path="toh-pt6/src/app/heroes/heroes.component.html">
|
||||
</code-pane>
|
||||
<code-pane
|
||||
header="heroes/heroes.component.ts"
|
||||
path="toh-pt6/src/app/heroes/heroes.component.ts">
|
||||
</code-pane>
|
||||
<code-pane
|
||||
header="heroes/heroes.component.css"
|
||||
path="toh-pt6/src/app/heroes/heroes.component.css">
|
||||
</code-pane>
|
||||
</code-tabs>
|
||||
|
||||
{@a herodetailcomponent}
|
||||
#### `HeroDetailComponent`
|
||||
|
||||
<code-tabs>
|
||||
<code-pane
|
||||
header="hero-detail/hero-detail.component.html"
|
||||
path="toh-pt6/src/app/hero-detail/hero-detail.component.html">
|
||||
</code-pane>
|
||||
<code-pane
|
||||
header="hero-detail/hero-detail.component.ts"
|
||||
path="toh-pt6/src/app/hero-detail/hero-detail.component.ts">
|
||||
</code-pane>
|
||||
</code-tabs>
|
||||
|
||||
{@a dashboardcomponent}
|
||||
#### `DashboardComponent`
|
||||
|
||||
<code-tabs>
|
||||
<code-pane
|
||||
header="src/app/dashboard/dashboard.component.html"
|
||||
path="toh-pt6/src/app/dashboard/dashboard.component.html">
|
||||
</code-pane>
|
||||
</code-tabs>
|
||||
|
||||
{@a herosearchcomponent}
|
||||
#### `HeroSearchComponent`
|
||||
|
||||
<code-tabs>
|
||||
<code-pane
|
||||
header="hero-search/hero-search.component.html"
|
||||
path="toh-pt6/src/app/hero-search/hero-search.component.html">
|
||||
</code-pane>
|
||||
<code-pane
|
||||
header="hero-search/hero-search.component.ts"
|
||||
path="toh-pt6/src/app/hero-search/hero-search.component.ts">
|
||||
</code-pane>
|
||||
<code-pane
|
||||
header="hero-search/hero-search.component.css"
|
||||
path="toh-pt6/src/app/hero-search/hero-search.component.css">
|
||||
</code-pane>
|
||||
</code-tabs>
|
||||
|
||||
## Summary
|
||||
|
||||
You're at the end of your journey, and you've accomplished a lot.
|
||||
* You added the necessary dependencies to use HTTP in the app.
|
||||
* You refactored `HeroService` to load heroes from a web API.
|
||||
* You extended `HeroService` to support `post()`, `put()`, and `delete()` methods.
|
||||
* You updated the components to allow adding, editing, and deleting of heroes.
|
||||
* You configured an in-memory web API.
|
||||
* You learned how to use observables.
|
||||
|
||||
This concludes the "Tour of Heroes" tutorial.
|
||||
You're ready to learn more about Angular development in the fundamentals section,
|
||||
starting with the [Architecture](guide/architecture "Architecture") guide.
|
@ -1,467 +1,463 @@
|
||||
# Get data from a server
|
||||
# Obtener datos desde un servidor
|
||||
|
||||
In this tutorial, you'll add the following data persistence features with help from
|
||||
Angular's `HttpClient`.
|
||||
En este tutorial, agregará las siguientes características de persistencia de datos con la ayuda de
|
||||
Angular `HttpClient`.
|
||||
|
||||
* The `HeroService` gets hero data with HTTP requests.
|
||||
* Users can add, edit, and delete heroes and save these changes over HTTP.
|
||||
* Users can search for heroes by name.
|
||||
* El `HeroService` obtiene datos del héroe con solicitudes HTTP.
|
||||
* Los usuarios pueden agregar, editar y eliminar héroes y guardar estos cambios a través de HTTP.
|
||||
* Los usuarios pueden buscar héroes por nombre.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For the sample app that this page describes, see the <live-example></live-example>.
|
||||
Para ver la aplicación de ejemplo que describe esta página, consulte el<live-example></live-example>.
|
||||
|
||||
</div>
|
||||
|
||||
## Enable HTTP services
|
||||
## Habilitar servicios HTTP
|
||||
|
||||
`HttpClient` is Angular's mechanism for communicating with a remote server over HTTP.
|
||||
`HttpClient` es el mecanismo de Angular para comunicarse con un servidor remoto a través de HTTP.
|
||||
|
||||
Make `HttpClient` available everywhere in the app in two steps. First, add it to the root `AppModule` by importing it:
|
||||
Haga que `HttpClient` esté disponible en todas partes de la aplicación en dos pasos. Primero, agréguelo a la raíz `AppModule` importándolo:
|
||||
|
||||
<code-example path="toh-pt6/src/app/app.module.ts" region="import-http-client" header="src/app/app.module.ts (HttpClientModule import)">
|
||||
</code-example>
|
||||
|
||||
Next, still in the `AppModule`, add `HttpClient` to the `imports` array:
|
||||
A continuación, aún en el `AppModule`, agregue` HttpClient` a el arreglo `imports`:
|
||||
|
||||
<code-example path="toh-pt6/src/app/app.module.ts" region="import-httpclientmodule" header="src/app/app.module.ts (imports array excerpt)">
|
||||
</code-example>
|
||||
|
||||
|
||||
## Simulate a data server
|
||||
## Simular un servidor de datos
|
||||
|
||||
This tutorial sample mimics communication with a remote data server by using the
|
||||
[In-memory Web API](https://github.com/angular/in-memory-web-api "In-memory Web API") module.
|
||||
Este ejemplo de tutorial imita la comunicación con un servidor de datos remoto mediante el uso de el modulo
|
||||
[API web en memoria](https://github.com/angular/in-memory-web-api "API web en memoria").
|
||||
|
||||
After installing the module, the app will make requests to and receive responses from the `HttpClient`
|
||||
without knowing that the *In-memory Web API* is intercepting those requests,
|
||||
applying them to an in-memory data store, and returning simulated responses.
|
||||
Después de instalar el módulo, la aplicación realizará solicitudes y recibirá respuestas del `HttpClient`
|
||||
sin saber que la *API web en memoria* está interceptando esas solicitudes,
|
||||
aplicándolos a un almacén de datos en memoria y devolviendo respuestas simuladas.
|
||||
|
||||
By using the In-memory Web API, you won't have to set up a server to learn about `HttpClient`.
|
||||
Al utilizar la API web en memoria, no tendrá que configurar un servidor para obtener información sobre `HttpClient`.
|
||||
|
||||
<div class="alert is-important">
|
||||
|
||||
**Important:** the In-memory Web API module has nothing to do with HTTP in Angular.
|
||||
**Importante:** el módulo API web en memoria no tiene nada que ver con HTTP en Angular.
|
||||
|
||||
If you're just reading this tutorial to learn about `HttpClient`, you can [skip over](#import-heroes) this step.
|
||||
If you're coding along with this tutorial, stay here and add the In-memory Web API now.
|
||||
Si solo está leyendo este tutorial para aprender sobre `HttpClient`, puede [omitir](#import-heroes) este paso.
|
||||
Si está codificando junto con este tutorial, quédese aquí y agregue la API web en memoria ahora.
|
||||
|
||||
</div>
|
||||
|
||||
Install the In-memory Web API package from npm with the following command:
|
||||
Instale el paquete de API web en memoria desde npm con el siguiente comando:
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
npm install angular-in-memory-web-api --save
|
||||
</code-example>
|
||||
|
||||
In the `AppModule`, import the `HttpClientInMemoryWebApiModule` and the `InMemoryDataService` class,
|
||||
which you will create in a moment.
|
||||
En el `AppModule`, importe el `HttpClientInMemoryWebApiModule` y la clase `InMemoryDataService`,
|
||||
que crearás en un momento.
|
||||
|
||||
<code-example path="toh-pt6/src/app/app.module.ts" region="import-in-mem-stuff" header="src/app/app.module.ts (In-memory Web API imports)">
|
||||
</code-example>
|
||||
|
||||
After the `HttpClientModule`, add the `HttpClientInMemoryWebApiModule`
|
||||
to the `AppModule` `imports` array and configure it with the `InMemoryDataService`.
|
||||
Después del `HttpClientModule`, agregue el `HttpClientInMemoryWebApiModule`
|
||||
a el arreglo de `AppModule` justo en `imports` y configúrelo con el `InMemoryDataService`.
|
||||
|
||||
<code-example path="toh-pt6/src/app/app.module.ts" header="src/app/app.module.ts (imports array excerpt)" region="in-mem-web-api-imports">
|
||||
</code-example>
|
||||
|
||||
The `forRoot()` configuration method takes an `InMemoryDataService` class
|
||||
that primes the in-memory database.
|
||||
El método de configuración `forRoot()` toma una clase `InMemoryDataService`
|
||||
eso prepara la base de datos en memoria.
|
||||
|
||||
Generate the class `src/app/in-memory-data.service.ts` with the following command:
|
||||
Genere la clase `src/app/in-memory-data.service.ts` con el siguiente comando:
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
ng generate service InMemoryData
|
||||
</code-example>
|
||||
|
||||
Replace the default contents of `in-memory-data.service.ts` with the following:
|
||||
Reemplace el contenido predeterminado de `in-memory-data.service.ts` con lo siguiente:
|
||||
|
||||
<code-example path="toh-pt6/src/app/in-memory-data.service.ts" region="init" header="src/app/in-memory-data.service.ts"></code-example>
|
||||
|
||||
The `in-memory-data.service.ts` file will take over the function of `mock-heroes.ts`.
|
||||
However, don't delete `mock-heroes.ts` yet, as you still need it for a few more steps of this tutorial.
|
||||
El archivo `in-memory-data.service.ts` asumirá la función de `mock-heroes.ts`.
|
||||
Sin embargo, no elimine `mock-heroes.ts` todavía, ya que aún lo necesita para algunos pasos más de este tutorial.
|
||||
|
||||
When the server is ready, you'll detach the In-memory Web API, and the app's requests will go through to the server.
|
||||
Cuando el servidor esté listo, desconectará la API web en memoria y las solicitudes de la aplicación se enviarán al servidor.
|
||||
|
||||
|
||||
{@a import-heroes}
|
||||
## Heroes and HTTP
|
||||
## Heroes y HTTP
|
||||
|
||||
In the `HeroService`, import `HttpClient` and `HttpHeaders`:
|
||||
En el `HeroService`, importe` HttpClient` y `HttpHeaders`:
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" region="import-httpclient" header="src/app/hero.service.ts (import HTTP symbols)">
|
||||
</code-example>
|
||||
|
||||
Still in the `HeroService`, inject `HttpClient` into the constructor in a private property called `http`.
|
||||
Aún en el `HeroService`, inyecte `HttpClient` en el constructor en una propiedad privada llamada `http`.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" header="src/app/hero.service.ts" region="ctor" >
|
||||
</code-example>
|
||||
|
||||
Notice that you keep injecting the `MessageService` but since you'll call it so frequently, wrap it in a private `log()` method:
|
||||
Observe que sigue inyectando el `MessageService` pero como lo llamará con tanta frecuencia, envuélvalo en un método privado `log()`:
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" header="src/app/hero.service.ts" region="log" >
|
||||
</code-example>
|
||||
|
||||
Define the `heroesUrl` of the form `:base/:collectionName` with the address of the heroes resource on the server.
|
||||
Here `base` is the resource to which requests are made,
|
||||
and `collectionName` is the heroes data object in the `in-memory-data-service.ts`.
|
||||
Defina el `heroesUrl` del formulario `:base/:collectionName` con la dirección del recurso heroes en el servidor.
|
||||
Aquí `base` es el recurso al que se hacen las solicitudes,
|
||||
y `collectionName` es el objeto de datos de héroes en `in-memory-data-service.ts`.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" header="src/app/hero.service.ts" region="heroesUrl" >
|
||||
</code-example>
|
||||
|
||||
### Get heroes with `HttpClient`
|
||||
### Consigue héroes con `HttpClient`
|
||||
|
||||
The current `HeroService.getHeroes()`
|
||||
uses the RxJS `of()` function to return an array of mock heroes
|
||||
as an `Observable<Hero[]>`.
|
||||
El actual `HeroService.getHeroes()`
|
||||
usa la función RxJS `of()` para devolver una serie de héroes simulados
|
||||
como un `Observable<Hero[]>`.
|
||||
|
||||
<code-example path="toh-pt4/src/app/hero.service.ts" region="getHeroes-1" header="src/app/hero.service.ts (getHeroes with RxJs 'of()')">
|
||||
</code-example>
|
||||
|
||||
Convert that method to use `HttpClient` as follows:
|
||||
Convierta ese método para usar `HttpClient` de la siguiente manera:
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" header="src/app/hero.service.ts" region="getHeroes-1">
|
||||
</code-example>
|
||||
|
||||
Refresh the browser. The hero data should successfully load from the
|
||||
mock server.
|
||||
Actualiza el navegador. Los datos del héroe deben cargarse correctamente desde el
|
||||
servidor simulado.
|
||||
|
||||
You've swapped `of()` for `http.get()` and the app keeps working without any other changes
|
||||
because both functions return an `Observable<Hero[]>`.
|
||||
Ha cambiado `of()` por `http.get()` y la aplicación sigue funcionando sin ningún otro cambio
|
||||
porque ambas funciones devuelven un `Observable <Hero[]>`.
|
||||
|
||||
### `HttpClient` methods return one value
|
||||
### Los métodos `HttpClient` devuelven un valor
|
||||
|
||||
All `HttpClient` methods return an RxJS `Observable` of something.
|
||||
Todos los métodos `HttpClient` devuelven un RxJS `Observable` de algo.
|
||||
|
||||
HTTP is a request/response protocol.
|
||||
You make a request, it returns a single response.
|
||||
HTTP es un protocolo de solicitud/respuesta.
|
||||
Realiza una solicitud, devuelve una sola respuesta.
|
||||
|
||||
In general, an observable _can_ return multiple values over time.
|
||||
An observable from `HttpClient` always emits a single value and then completes, never to emit again.
|
||||
En general, un observable _puede_ devolver múltiples valores a lo largo del tiempo.
|
||||
Un observable de `HttpClient` siempre emite un único valor y luego se completa, para nunca volver a emitir.
|
||||
|
||||
This particular `HttpClient.get()` call returns an `Observable<Hero[]>`; that is, "_an observable of hero arrays_". In practice, it will only return a single hero array.
|
||||
Esta llamada particular a `HttpClient.get()` devuelve un `Observable<Hero[]>`; es decir, "un observable de un arreglo de héroes". En la práctica, solo devolverá un único conjunto de héroes.
|
||||
|
||||
### `HttpClient.get()` returns response data
|
||||
### `HttpClient.get()` devuelve datos de respuesta
|
||||
|
||||
`HttpClient.get()` returns the body of the response as an untyped JSON object by default.
|
||||
Applying the optional type specifier, `<Hero[]>` , adds TypeScript capabilities, which reduce errors during compile time.
|
||||
`HttpClient.get()` devuelve el cuerpo de la respuesta como un objeto JSON sin tipo de forma predeterminada.
|
||||
Al aplicar el especificador de tipo opcional, `<Hero[]>`, se agregan capacidades de TypeScript, que reducen los errores durante el tiempo de compilación.
|
||||
|
||||
The server's data API determines the shape of the JSON data.
|
||||
The _Tour of Heroes_ data API returns the hero data as an array.
|
||||
La API de datos del servidor determina la forma de los datos JSON.
|
||||
La API de datos _Tour of Heroes_ devuelve los datos del héroe como una matriz.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
Other APIs may bury the data that you want within an object.
|
||||
You might have to dig that data out by processing the `Observable` result
|
||||
with the RxJS `map()` operator.
|
||||
|
||||
Although not discussed here, there's an example of `map()` in the `getHeroNo404()`
|
||||
method included in the sample source code.
|
||||
Otras API pueden enterrar los datos que desea dentro de un objeto.
|
||||
Puede que tenga que desenterrar esos datos procesando el resultado `Observable`
|
||||
con el operador RxJS `map()`.
|
||||
|
||||
Aunque no se trata aquí, hay un ejemplo de `map()` en `getHeroNo404()`
|
||||
método incluido en el código fuente de muestra.
|
||||
</div>
|
||||
|
||||
### Error handling
|
||||
### Manejo de errores
|
||||
|
||||
Things go wrong, especially when you're getting data from a remote server.
|
||||
The `HeroService.getHeroes()` method should catch errors and do something appropriate.
|
||||
Las cosas salen mal, especialmente cuando obtiene datos de un servidor remoto.
|
||||
El método `HeroService.getHeroes()` debería detectar errores y hacer algo apropiado.
|
||||
|
||||
To catch errors, you **"pipe" the observable** result from `http.get()` through an RxJS `catchError()` operator.
|
||||
Para detectar errores, **"filtra" el resultado observable** desde `http.get()` a través de un operador RxJS `catchError()`.
|
||||
|
||||
Import the `catchError` symbol from `rxjs/operators`, along with some other operators you'll need later.
|
||||
Importe el símbolo `catchError` desde `rxjs/operadores`, junto con algunos otros operadores que necesitará más adelante.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" header="src/app/hero.service.ts" region="import-rxjs-operators">
|
||||
</code-example>
|
||||
|
||||
Now extend the observable result with the `pipe()` method and
|
||||
give it a `catchError()` operator.
|
||||
Ahora extienda el resultado observable con el método `pipe()` y
|
||||
darle un operador `catchError()`.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" region="getHeroes-2" header="src/app/hero.service.ts">
|
||||
</code-example>
|
||||
|
||||
The `catchError()` operator intercepts an **`Observable` that failed**.
|
||||
It passes the error an error handler that can do what it wants with the error.
|
||||
El operador `catchError()` intercepta un **`Observable` que falló**.
|
||||
Pasa el error a un controlador de errores que puede hacer lo que quiera con el error.
|
||||
|
||||
The following `handleError()` method reports the error and then returns an
|
||||
innocuous result so that the application keeps working.
|
||||
El siguiente método `handleError()` informa el error y luego devuelve un
|
||||
resultado inocuo para que la aplicación siga funcionando.
|
||||
|
||||
#### `handleError`
|
||||
|
||||
The following `handleError()` will be shared by many `HeroService` methods
|
||||
so it's generalized to meet their different needs.
|
||||
El siguiente `handleError()` será compartido por muchos métodos `HeroService`
|
||||
así que está generalizado para satisfacer sus diferentes necesidades.
|
||||
|
||||
Instead of handling the error directly, it returns an error handler function to `catchError` that it
|
||||
has configured with both the name of the operation that failed and a safe return value.
|
||||
En lugar de manejar el error directamente, devuelve una función de controlador de errores a `catchError` que
|
||||
se configuró con el nombre de la operación que falló y un valor de retorno seguro.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" header="src/app/hero.service.ts" region="handleError">
|
||||
</code-example>
|
||||
|
||||
After reporting the error to the console, the handler constructs
|
||||
a user friendly message and returns a safe value to the app so the app can keep working.
|
||||
Después de informar el error a la consola, el controlador construye
|
||||
un mensaje fácil de usar y devuelve un valor seguro a la aplicación para que la aplicación pueda seguir funcionando.
|
||||
|
||||
Because each service method returns a different kind of `Observable` result,
|
||||
`handleError()` takes a type parameter so it can return the safe value as the type that the app expects.
|
||||
Como cada método de servicio devuelve un tipo diferente de resultado 'Observable',
|
||||
`handleError()` toma un parámetro de tipo para que pueda devolver el valor seguro como el tipo que la aplicación espera.
|
||||
|
||||
### Tap into the Observable
|
||||
### Tap en el Observable
|
||||
|
||||
The `HeroService` methods will **tap** into the flow of observable values
|
||||
and send a message, via the `log()` method, to the message area at the bottom of the page.
|
||||
Los métodos `HeroService` **aprovecharán** el flujo de valores observables
|
||||
y envíe un mensaje, a través del método `log()`, al área de mensajes en la parte inferior de la página.
|
||||
|
||||
They'll do that with the RxJS `tap()` operator,
|
||||
which looks at the observable values, does something with those values,
|
||||
and passes them along.
|
||||
The `tap()` call back doesn't touch the values themselves.
|
||||
Lo harán con el operador RxJS `tap()`,
|
||||
que mira los valores observables, hace algo con esos valores,
|
||||
y los pasa
|
||||
La devolución de llamada `tap()` no toca los valores en sí mismos.
|
||||
|
||||
Here is the final version of `getHeroes()` with the `tap()` that logs the operation.
|
||||
Aquí está la versión final de `getHeroes()` con el `tap()` que registra la operación.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" header="src/app/hero.service.ts" region="getHeroes" >
|
||||
</code-example>
|
||||
|
||||
### Get hero by id
|
||||
### Obtener héroe por id
|
||||
|
||||
Most web APIs support a _get by id_ request in the form `:baseURL/:id`.
|
||||
La mayoría de las API web admiten una solicitud _get by id_ en la forma `: baseURL /: id`.
|
||||
|
||||
Here, the _base URL_ is the `heroesURL` defined in the [Heroes and HTTP](tutorial/toh-pt6#heroes-and-http) section (`api/heroes`) and _id_ is
|
||||
the number of the hero that you want to retrieve. For example, `api/heroes/11`.
|
||||
Aquí, la _base URL_ es el `heroesURL` definido en la [Heroes y HTTP](tutorial/toh-pt6#import-heroes) sección (`api/heroes`) y _id_ es
|
||||
El número del héroe que quieres recuperar. Por ejemplo, `api/heroes/11`.
|
||||
|
||||
Update the `HeroService` `getHero()` method with the following to make that request:
|
||||
Actualice el método `HeroService` `getHero()` con lo siguiente para hacer esa solicitud:
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" region="getHero" header="src/app/hero.service.ts"></code-example>
|
||||
|
||||
There are three significant differences from `getHeroes()`:
|
||||
Hay tres diferencias significativas de `getHeroes()`:
|
||||
|
||||
* `getHero()` constructs a request URL with the desired hero's id.
|
||||
* The server should respond with a single hero rather than an array of heroes.
|
||||
* `getHero()` returns an `Observable<Hero>` ("_an observable of Hero objects_")
|
||||
rather than an observable of hero _arrays_ .
|
||||
* `getHero()` construye una URL de solicitud con la identificación del héroe deseado.
|
||||
* El servidor debe responder con un solo héroe en lugar de una serie de héroes.
|
||||
* `getHero()` devuelve un `Observable<Hero>` ("_un observable de objetos Hero_")
|
||||
en lugar de un observable de _arreglos_ de héroes.
|
||||
|
||||
## Update heroes
|
||||
## Actualizar héroes
|
||||
|
||||
Edit a hero's name in the hero detail view.
|
||||
As you type, the hero name updates the heading at the top of the page.
|
||||
But when you click the "go back button", the changes are lost.
|
||||
Edite el nombre de un héroe en la vista de detalles del héroe.
|
||||
A medida que escribe, el nombre del héroe actualiza el encabezado en la parte superior de la página.
|
||||
Pero cuando hace clic en el "botón volver", los cambios se pierden.
|
||||
|
||||
If you want changes to persist, you must write them back to
|
||||
the server.
|
||||
Si desea que los cambios persistan, debe volver a escribirlos en
|
||||
el servidor.
|
||||
|
||||
At the end of the hero detail template, add a save button with a `click` event
|
||||
binding that invokes a new component method named `save()`.
|
||||
Al final de la plantilla de detalles del héroe, agregue un botón de guardar con un evento de "clic"
|
||||
enlace que invoca un nuevo método de componente llamado `save()`.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero-detail/hero-detail.component.html" region="save" header="src/app/hero-detail/hero-detail.component.html (save)"></code-example>
|
||||
|
||||
In the `HeroDetail` component class, add the following `save()` method, which persists hero name changes using the hero service
|
||||
`updateHero()` method and then navigates back to the previous view.
|
||||
En la clase de componente `HeroDetail`, agregue el siguiente método `save()`, que persiste los cambios de nombre de héroe usando el servicio de héroe
|
||||
`updateHero()` y luego navega de regreso a la vista anterior.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero-detail/hero-detail.component.ts" region="save" header="src/app/hero-detail/hero-detail.component.ts (save)"></code-example>
|
||||
|
||||
#### Add `HeroService.updateHero()`
|
||||
#### Agregar `HeroService.updateHero()`
|
||||
|
||||
The overall structure of the `updateHero()` method is similar to that of
|
||||
`getHeroes()`, but it uses `http.put()` to persist the changed hero
|
||||
on the server. Add the following to the `HeroService`.
|
||||
La estructura general del método `updateHero()` es similar a la de
|
||||
`getHeroes()`, pero usa `http.put()` para persistir el héroe cambiado
|
||||
en el servidor Agregue lo siguiente al `HeroService`.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" region="updateHero" header="src/app/hero.service.ts (update)">
|
||||
</code-example>
|
||||
|
||||
The `HttpClient.put()` method takes three parameters:
|
||||
* the URL
|
||||
* the data to update (the modified hero in this case)
|
||||
* options
|
||||
El método `HttpClient.put()` toma tres parámetros:
|
||||
* la URL
|
||||
* los datos para actualizar (el héroe modificado en este caso)
|
||||
* opciones
|
||||
|
||||
The URL is unchanged. The heroes web API knows which hero to update by looking at the hero's `id`.
|
||||
La URL no se modifica. La API web de héroes sabe qué héroe actualizar al mirar el "id" del héroe.
|
||||
|
||||
The heroes web API expects a special header in HTTP save requests.
|
||||
That header is in the `httpOptions` constant defined in the `HeroService`. Add the following to the `HeroService` class.
|
||||
La API web de héroes espera un encabezado especial en las solicitudes de guardado HTTP.
|
||||
Ese encabezado está en la constante `httpOptions` definida en el `HeroService`. Agregue lo siguiente a la clase `HeroService`.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" region="http-options" header="src/app/hero.service.ts">
|
||||
</code-example>
|
||||
|
||||
Refresh the browser, change a hero name and save your change. The `save()`
|
||||
method in `HeroDetailComponent` navigates to the previous view.
|
||||
The hero now appears in the list with the changed name.
|
||||
Actualiza el navegador, cambia el nombre de un héroe y guarda tu cambio. El `save()`
|
||||
El método en `HeroDetailComponent` navega a la vista anterior.
|
||||
El héroe ahora aparece en la lista con el nombre cambiado.
|
||||
|
||||
## Agrega un nuevo héroe
|
||||
|
||||
## Add a new hero
|
||||
Para agregar un héroe, esta aplicación solo necesita el nombre del héroe. Puede utilizar un `<input>`
|
||||
elemento emparejado con un botón Agregar.
|
||||
|
||||
To add a hero, this app only needs the hero's name. You can use an `<input>`
|
||||
element paired with an add button.
|
||||
|
||||
Insert the following into the `HeroesComponent` template, just after
|
||||
the heading:
|
||||
Inserte lo siguiente en la plantilla `HeroesComponent`, justo después
|
||||
El encabezado:
|
||||
|
||||
<code-example path="toh-pt6/src/app/heroes/heroes.component.html" region="add" header="src/app/heroes/heroes.component.html (add)"></code-example>
|
||||
|
||||
In response to a click event, call the component's click handler, `add()`, and then
|
||||
clear the input field so that it's ready for another name. Add the following to the
|
||||
`HeroesComponent` class:
|
||||
En respuesta a un evento de clic, llame al controlador de clic del componente, `add()`, y luego
|
||||
borre el campo de entrada para que esté listo para otro nombre. Agregue lo siguiente al
|
||||
Clase `Componente de héroes`:
|
||||
|
||||
<code-example path="toh-pt6/src/app/heroes/heroes.component.ts" region="add" header="src/app/heroes/heroes.component.ts (add)"></code-example>
|
||||
|
||||
When the given name is non-blank, the handler creates a `Hero`-like object
|
||||
from the name (it's only missing the `id`) and passes it to the services `addHero()` method.
|
||||
Cuando el nombre de pila no está en blanco, el controlador crea un objeto similar a un "Héroe"
|
||||
del nombre (sólo falta el `id`) y lo pasa al método `addHero()` del servicio.
|
||||
|
||||
When `addHero()` saves successfully, the `subscribe()` callback
|
||||
receives the new hero and pushes it into to the `heroes` list for display.
|
||||
Cuando `addHero()` se guarda correctamente, la devolución de llamada `subscribe()`
|
||||
recibe el nuevo héroe y lo empuja a la lista de "héroes" para mostrarlo.
|
||||
|
||||
Add the following `addHero()` method to the `HeroService` class.
|
||||
Agregue el siguiente método `addHero()` a la clase `HeroService`.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" region="addHero" header="src/app/hero.service.ts (addHero)"></code-example>
|
||||
|
||||
`addHero()` differs from `updateHero()` in two ways:
|
||||
`addHero()` difiere de `updateHero()` en dos formas:
|
||||
|
||||
* It calls `HttpClient.post()` instead of `put()`.
|
||||
* It expects the server to generate an id for the new hero,
|
||||
which it returns in the `Observable<Hero>` to the caller.
|
||||
* Llama a `HttpClient.post()` en lugar de a `put()`.
|
||||
* Espera que el servidor genere una identificación para el nuevo héroe,
|
||||
que devuelve en el `Observable<Hero>` a la persona que llama.
|
||||
|
||||
Refresh the browser and add some heroes.
|
||||
Actualiza el navegador y agrega algunos héroes.
|
||||
|
||||
## Delete a hero
|
||||
## Eliminar un héroe
|
||||
|
||||
Each hero in the heroes list should have a delete button.
|
||||
Cada héroe de la lista de héroes debe tener un botón de eliminación.
|
||||
|
||||
Add the following button element to the `HeroesComponent` template, after the hero
|
||||
name in the repeated `<li>` element.
|
||||
Agregue el siguiente elemento de botón a la plantilla `HeroesComponent`, después del héroe
|
||||
nombre en el elemento repetido `<li>`.
|
||||
|
||||
<code-example path="toh-pt6/src/app/heroes/heroes.component.html" header="src/app/heroes/heroes.component.html" region="delete"></code-example>
|
||||
|
||||
The HTML for the list of heroes should look like this:
|
||||
El HTML de la lista de héroes debería verse así:
|
||||
|
||||
<code-example path="toh-pt6/src/app/heroes/heroes.component.html" region="list" header="src/app/heroes/heroes.component.html (list of heroes)"></code-example>
|
||||
|
||||
To position the delete button at the far right of the hero entry,
|
||||
add some CSS to the `heroes.component.css`. You'll find that CSS
|
||||
in the [final review code](#heroescomponent) below.
|
||||
Para colocar el botón de eliminar en el extremo derecho de la entrada del héroe,
|
||||
agregue algo de CSS al `heroes.component.css`. Encontrarás ese CSS
|
||||
en el [código de revisión final](#heroescomponent) a continuación.
|
||||
|
||||
Add the `delete()` handler to the component class.
|
||||
Agregue el controlador `delete()` a la clase del componente.
|
||||
|
||||
<code-example path="toh-pt6/src/app/heroes/heroes.component.ts" region="delete" header="src/app/heroes/heroes.component.ts (delete)"></code-example>
|
||||
|
||||
Although the component delegates hero deletion to the `HeroService`,
|
||||
it remains responsible for updating its own list of heroes.
|
||||
The component's `delete()` method immediately removes the _hero-to-delete_ from that list,
|
||||
anticipating that the `HeroService` will succeed on the server.
|
||||
Aunque el componente delega la eliminación de héroes al `HeroService`,
|
||||
sigue siendo responsable de actualizar su propia lista de héroes.
|
||||
El método `delete()` del componente elimina inmediatamente el _hero-to-delete_ de esa lista,
|
||||
anticipando que el `HeroService` tendrá éxito en el servidor.
|
||||
|
||||
There's really nothing for the component to do with the `Observable` returned by
|
||||
`heroService.delete()` **but it must subscribe anyway**.
|
||||
Realmente no hay nada que ver el componente con el "Observable" devuelto por
|
||||
`heroService.delete()` **pero debe suscribirse de todos modos**.
|
||||
|
||||
<div class="alert is-important">
|
||||
|
||||
If you neglect to `subscribe()`, the service will not send the delete request to the server.
|
||||
As a rule, an `Observable` _does nothing_ until something subscribes.
|
||||
Si se olvida de `subscribe()`, el servicio no enviará la solicitud de eliminación al servidor.
|
||||
Como regla general, un "Observable" _no hace nada_ hasta que algo se suscribe.
|
||||
|
||||
Confirm this for yourself by temporarily removing the `subscribe()`,
|
||||
clicking "Dashboard", then clicking "Heroes".
|
||||
You'll see the full list of heroes again.
|
||||
Confirme esto por sí mismo eliminando temporalmente el `subscribe()`,
|
||||
haciendo clic en "Panel de control", luego en "Héroes".
|
||||
Verás la lista completa de héroes nuevamente.
|
||||
|
||||
</div>
|
||||
|
||||
Next, add a `deleteHero()` method to `HeroService` like this.
|
||||
A continuación, agregue un método `deleteHero()` a `HeroService` como este.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" region="deleteHero" header="src/app/hero.service.ts (delete)"></code-example>
|
||||
|
||||
Note the following key points:
|
||||
Tenga en cuenta los siguientes puntos clave:
|
||||
|
||||
* `deleteHero()` calls `HttpClient.delete()`.
|
||||
* The URL is the heroes resource URL plus the `id` of the hero to delete.
|
||||
* You don't send data as you did with `put()` and `post()`.
|
||||
* You still send the `httpOptions`.
|
||||
* `deleteHero()` llama a `HttpClient.delete()`.
|
||||
* La URL es la URL del recurso de héroes más el "id" del héroe a eliminar.
|
||||
* No envías datos como lo hiciste con `put()` y `post()`.
|
||||
* Aún envías las `httpOptions`.
|
||||
|
||||
Refresh the browser and try the new delete functionality.
|
||||
Actualice el navegador y pruebe la nueva función de eliminación.
|
||||
|
||||
## Search by name
|
||||
## Buscar por nombre
|
||||
|
||||
In this last exercise, you learn to chain `Observable` operators together
|
||||
so you can minimize the number of similar HTTP requests
|
||||
and consume network bandwidth economically.
|
||||
En este último ejercicio, aprenderá a encadenar operadores "observables"
|
||||
para que pueda minimizar la cantidad de solicitudes HTTP similares
|
||||
y consumir ancho de banda de la red de forma económica.
|
||||
|
||||
You will add a heroes search feature to the Dashboard.
|
||||
As the user types a name into a search box,
|
||||
you'll make repeated HTTP requests for heroes filtered by that name.
|
||||
Your goal is to issue only as many requests as necessary.
|
||||
Agregará una función de búsqueda de héroes al Tablero.
|
||||
A medida que el usuario escribe un nombre en un cuadro de búsqueda,
|
||||
harás solicitudes HTTP repetidas para héroes filtrados por ese nombre.
|
||||
Su objetivo es emitir solo tantas solicitudes como sea necesario.
|
||||
|
||||
#### `HeroService.searchHeroes()`
|
||||
|
||||
Start by adding a `searchHeroes()` method to the `HeroService`.
|
||||
Comience agregando un método `searchHeroes()` al `HeroService`.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero.service.ts" region="searchHeroes" header="src/app/hero.service.ts">
|
||||
</code-example>
|
||||
|
||||
The method returns immediately with an empty array if there is no search term.
|
||||
The rest of it closely resembles `getHeroes()`, the only significant difference being
|
||||
the URL, which includes a query string with the search term.
|
||||
El método regresa inmediatamente con una matriz vacía si no hay un término de búsqueda.
|
||||
El resto se parece mucho a "getHeroes()", siendo la única diferencia significativa
|
||||
la URL, que incluye una cadena de consulta con el término de búsqueda.
|
||||
|
||||
### Add search to the Dashboard
|
||||
### Agregar búsqueda al panel
|
||||
|
||||
Open the `DashboardComponent` template and
|
||||
add the hero search element, `<app-hero-search>`, to the bottom of the markup.
|
||||
Abra la plantilla `DashboardComponent` y
|
||||
agregue el elemento de búsqueda de héroe, `<app-hero-search>`, al final del marcado.
|
||||
|
||||
<code-example path="toh-pt6/src/app/dashboard/dashboard.component.html" header="src/app/dashboard/dashboard.component.html"></code-example>
|
||||
|
||||
This template looks a lot like the `*ngFor` repeater in the `HeroesComponent` template.
|
||||
Esta plantilla se parece mucho al repetidor `*ngFor` en la plantilla `HeroesComponent`.
|
||||
|
||||
For this to work, the next step is to add a component with a selector that matches `<app-hero-search>`.
|
||||
Para que esto funcione, el siguiente paso es agregar un componente con un selector que coincida con `<app-hero-search>`.
|
||||
|
||||
|
||||
### Create `HeroSearchComponent`
|
||||
### Crear `HeroSearchComponent`
|
||||
|
||||
Create a `HeroSearchComponent` with the CLI.
|
||||
Cree un "HeroSearchComponent" con El Cli.
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
ng generate component hero-search
|
||||
</code-example>
|
||||
|
||||
The CLI generates the three `HeroSearchComponent` files and adds the component to the `AppModule` declarations.
|
||||
El Cli genera los tres archivos de `HeroSearchComponent` y agrega el componente a las declaraciones en `AppModule`.
|
||||
|
||||
Replace the generated `HeroSearchComponent` template with an `<input>` and a list of matching search results, as follows.
|
||||
Reemplace la plantilla `HeroSearchComponent` generada con un `<input>` y una lista de resultados de búsqueda coincidentes, de la siguiente manera.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero-search/hero-search.component.html" header="src/app/hero-search/hero-search.component.html"></code-example>
|
||||
|
||||
Add private CSS styles to `hero-search.component.css`
|
||||
as listed in the [final code review](#herosearchcomponent) below.
|
||||
Agregue estilos CSS privados a `hero-search.component.css`
|
||||
como se indica en la [revisión final del código](#herosearchcomponent) a continuación.
|
||||
|
||||
As the user types in the search box, an input event binding calls the
|
||||
component's `search()` method with the new search box value.
|
||||
A medida que el usuario escribe en el cuadro de búsqueda, un enlace de evento de entrada llama al
|
||||
el método `search()` del componente con el nuevo valor del cuadro de búsqueda.
|
||||
|
||||
{@a asyncpipe}
|
||||
|
||||
### `AsyncPipe`
|
||||
|
||||
The `*ngFor` repeats hero objects. Notice that the `*ngFor` iterates over a list called `heroes$`, not `heroes`. The `$` is a convention that indicates `heroes$` is an `Observable`, not an array.
|
||||
|
||||
El `*ngFor` repite los objetos hero. Note que el `*ngFor` itera sobre una lista llamada `heroes$`, no sobre `heroes`. El `$` es una convención que indica que `heroes$` es un `Observable`, no un arreglo.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero-search/hero-search.component.html" header="src/app/hero-search/hero-search.component.html" region="async"></code-example>
|
||||
|
||||
Since `*ngFor` can't do anything with an `Observable`, use the
|
||||
pipe character (`|`) followed by `async`. This identifies Angular's `AsyncPipe` and subscribes to an `Observable` automatically so you won't have to
|
||||
do so in the component class.
|
||||
Como `*ngFor` no puede hacer nada con un `Observable`, use el
|
||||
carácter de filtración (`|`) seguido de `async`. Esto identifica el "AsyncPipe" de Angular y se suscribe automáticamente a un "Observable" para que no tenga que
|
||||
hacerlo en la clase de componente.
|
||||
|
||||
### Edit the `HeroSearchComponent` class
|
||||
### Editar la clase `HeroSearchComponent`
|
||||
|
||||
Replace the generated `HeroSearchComponent` class and metadata as follows.
|
||||
Reemplace la clase generada `HeroSearchComponent` y los metadatos de la siguiente manera.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero-search/hero-search.component.ts" header="src/app/hero-search/hero-search.component.ts"></code-example>
|
||||
|
||||
Notice the declaration of `heroes$` as an `Observable`:
|
||||
|
||||
Observe la declaración de `heroes$` como un `Observable`:
|
||||
<code-example path="toh-pt6/src/app/hero-search/hero-search.component.ts" header="src/app/hero-search/hero-search.component.ts" region="heroes-stream">
|
||||
</code-example>
|
||||
|
||||
You'll set it in [`ngOnInit()`](#search-pipe).
|
||||
Before you do, focus on the definition of `searchTerms`.
|
||||
Lo configurará en [`ngOnInit()`](#search-pipe).
|
||||
Antes de hacerlo, concéntrese en la definición de `searchTerms`.
|
||||
|
||||
### The `searchTerms` RxJS subject
|
||||
### El subject RxJS `searchTerms`
|
||||
|
||||
The `searchTerms` property is an RxJS `Subject`.
|
||||
La propiedad `searchTerms` es un `Subject` de RxJS.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero-search/hero-search.component.ts" header="src/app/hero-search/hero-search.component.ts" region="searchTerms"></code-example>
|
||||
|
||||
A `Subject` is both a source of observable values and an `Observable` itself.
|
||||
You can subscribe to a `Subject` as you would any `Observable`.
|
||||
Un `Subject` es tanto una fuente de valores observables como un `Observable` en sí mismo.
|
||||
Puede suscribirse a un `Subject` como lo haría con cualquier `Observable`.
|
||||
|
||||
You can also push values into that `Observable` by calling its `next(value)` method
|
||||
as the `search()` method does.
|
||||
También puede insertar valores en ese `Observable` llamando a su método `next(value)`
|
||||
como lo hace el método `search()`.
|
||||
|
||||
The event binding to the textbox's `input` event calls the `search()` method.
|
||||
El evento vinculado al evento `input` del cuadro de texto llama al método `search()`.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero-search/hero-search.component.html" header="src/app/hero-search/hero-search.component.html" region="input"></code-example>
|
||||
|
||||
@ -470,61 +466,61 @@ The `searchTerms` becomes an `Observable` emitting a steady stream of search ter
|
||||
|
||||
{@a search-pipe}
|
||||
|
||||
### Chaining RxJS operators
|
||||
### Encadenamiento de operadores RxJS
|
||||
|
||||
Passing a new search term directly to the `searchHeroes()` after every user keystroke would create an excessive amount of HTTP requests,
|
||||
taxing server resources and burning through data plans.
|
||||
Pasar un nuevo término de búsqueda directamente a `searchHeroes()` después de cada pulsación de tecla del usuario crearía una cantidad excesiva de solicitudes HTTP,
|
||||
gravando los recursos del servidor y quemando a través de planes de datos.
|
||||
|
||||
Instead, the `ngOnInit()` method pipes the `searchTerms` observable through a sequence of RxJS operators that reduce the number of calls to the `searchHeroes()`,
|
||||
ultimately returning an observable of timely hero search results (each a `Hero[]`).
|
||||
En cambio, el método `ngOnInit()` filtra los `searchTerms` observables a través de una secuencia de operadores RxJS que reducen el número de llamadas `searchHeroes()`,
|
||||
en última instancia, devuelve un observable de resultados de búsqueda de héroes oportunos (cada uno un `Héroe[]`).
|
||||
|
||||
Here's a closer look at the code.
|
||||
Aquí hay un vistazo más de cerca al código.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero-search/hero-search.component.ts" header="src/app/hero-search/hero-search.component.ts" region="search">
|
||||
</code-example>
|
||||
|
||||
Each operator works as follows:
|
||||
Cada operador funciona de la siguiente manera:
|
||||
|
||||
* `debounceTime(300)` waits until the flow of new string events pauses for 300 milliseconds
|
||||
before passing along the latest string. You'll never make requests more frequently than 300ms.
|
||||
* `debounceTime(300)` espera hasta que el flujo de nuevos eventos de cadena se detenga durante 300 milisegundos
|
||||
antes de pasar por la última cuerda. Nunca hará solicitudes con más frecuencia que 300 ms.
|
||||
|
||||
* `distinctUntilChanged()` ensures that a request is sent only if the filter text changed.
|
||||
* `distinctUntilChanged()` asegura que una solicitud se envíe solo si el texto del filtro cambió.
|
||||
|
||||
* `switchMap()` calls the search service for each search term that makes it through `debounce()` and `distinctUntilChanged()`.
|
||||
It cancels and discards previous search observables, returning only the latest search service observable.
|
||||
* `switchMap()` llama al servicio de búsqueda para cada término de búsqueda que pasa por `debounce()` y `distinctUntilChanged()`.
|
||||
Cancela y descarta los observables de búsqueda anteriores, devolviendo solo el último servicio de búsqueda observable.
|
||||
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
With the [switchMap operator](http://www.learnrxjs.io/operators/transformation/switchmap.html),
|
||||
every qualifying key event can trigger an `HttpClient.get()` method call.
|
||||
Even with a 300ms pause between requests, you could have multiple HTTP requests in flight
|
||||
and they may not return in the order sent.
|
||||
Con el [operador de switchMap](http://www.learnrxjs.io/operators/transformation/switchmap.html),
|
||||
cada evento clave que califique puede activar una llamada al método `HttpClient.get()`.
|
||||
Incluso con una pausa de 300 ms entre solicitudes, podría tener varias solicitudes HTTP en vuelo
|
||||
y no pueden regresar en el orden enviado.
|
||||
|
||||
`switchMap()` preserves the original request order while returning only the observable from the most recent HTTP method call.
|
||||
Results from prior calls are canceled and discarded.
|
||||
`switchMap()` conserva el orden de solicitud original mientras devuelve solo lo observable de la llamada al método HTTP más reciente.
|
||||
Los resultados de llamadas anteriores se cancelan y descartan.
|
||||
|
||||
Note that canceling a previous `searchHeroes()` Observable
|
||||
doesn't actually abort a pending HTTP request.
|
||||
Unwanted results are simply discarded before they reach your application code.
|
||||
Tenga en cuenta que cancelar un `searchHeroes()` anterior observable
|
||||
en realidad no aborta una solicitud HTTP pendiente.
|
||||
Los resultados no deseados simplemente se descartan antes de que lleguen al código de su aplicación.
|
||||
|
||||
</div>
|
||||
|
||||
Remember that the component _class_ does not subscribe to the `heroes$` _observable_.
|
||||
That's the job of the [`AsyncPipe`](#asyncpipe) in the template.
|
||||
Recuerde que el componente _class_ no se suscribe a los `heroes$` _observable_.
|
||||
Ese es el trabajo de [`Filtro asíncrono (asynpipe)`](#asyncpipe) en la plantilla.
|
||||
|
||||
#### Try it
|
||||
#### Intentalo
|
||||
|
||||
Run the app again. In the *Dashboard*, enter some text in the search box.
|
||||
If you enter characters that match any existing hero names, you'll see something like this.
|
||||
Ejecute la aplicación nuevamente. En el *Tablero*, ingrese texto en el cuadro de búsqueda.
|
||||
Si ingresas personajes que coinciden con cualquier nombre de héroe existente, verás algo como esto.
|
||||
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/toh/toh-hero-search.png' alt="Hero Search Component">
|
||||
</div>
|
||||
|
||||
## Final code review
|
||||
## Revisión final del código
|
||||
|
||||
Here are the code files discussed on this page (all in the `src/app/` folder).
|
||||
Aquí están los archivos de código discutidos en esta página (todos en la carpeta `src/app/`).
|
||||
|
||||
{@a heroservice}
|
||||
{@a inmemorydataservice}
|
||||
@ -547,7 +543,7 @@ Here are the code files discussed on this page (all in the `src/app/` folder).
|
||||
</code-tabs>
|
||||
|
||||
{@a heroescomponent}
|
||||
#### `HeroesComponent`
|
||||
#### `Componente de heroes`
|
||||
|
||||
<code-tabs>
|
||||
<code-pane
|
||||
@ -565,7 +561,7 @@ Here are the code files discussed on this page (all in the `src/app/` folder).
|
||||
</code-tabs>
|
||||
|
||||
{@a herodetailcomponent}
|
||||
#### `HeroDetailComponent`
|
||||
#### `Componete de detalles de el heroe`
|
||||
|
||||
<code-tabs>
|
||||
<code-pane
|
||||
@ -579,7 +575,7 @@ Here are the code files discussed on this page (all in the `src/app/` folder).
|
||||
</code-tabs>
|
||||
|
||||
{@a dashboardcomponent}
|
||||
#### `DashboardComponent`
|
||||
#### `Componente de panel(dashboard)`
|
||||
|
||||
<code-tabs>
|
||||
<code-pane
|
||||
@ -589,7 +585,7 @@ Here are the code files discussed on this page (all in the `src/app/` folder).
|
||||
</code-tabs>
|
||||
|
||||
{@a herosearchcomponent}
|
||||
#### `HeroSearchComponent`
|
||||
#### `Componente de búsqueda de héroe`
|
||||
|
||||
<code-tabs>
|
||||
<code-pane
|
||||
@ -606,16 +602,17 @@ Here are the code files discussed on this page (all in the `src/app/` folder).
|
||||
</code-pane>
|
||||
</code-tabs>
|
||||
|
||||
## Summary
|
||||
## Resumen
|
||||
|
||||
You're at the end of your journey, and you've accomplished a lot.
|
||||
* You added the necessary dependencies to use HTTP in the app.
|
||||
* You refactored `HeroService` to load heroes from a web API.
|
||||
* You extended `HeroService` to support `post()`, `put()`, and `delete()` methods.
|
||||
* You updated the components to allow adding, editing, and deleting of heroes.
|
||||
* You configured an in-memory web API.
|
||||
* You learned how to use observables.
|
||||
Este es el final de su viaje y ha logrado mucho.
|
||||
|
||||
This concludes the "Tour of Heroes" tutorial.
|
||||
You're ready to learn more about Angular development in the fundamentals section,
|
||||
starting with the [Architecture](guide/architecture "Architecture") guide.
|
||||
* Agrego las dependencias necesarias para usar HTTP en la aplicación.
|
||||
* Refactorizó `HeroService` para cargar héroes desde una API web.
|
||||
* Extendió `HeroService` para admitir los métodos `post()`, `put()` y `delete()`.
|
||||
* Actualizo los componentes para permitir agregar, editar y eliminar héroes.
|
||||
* Configuro una API web en memoria.
|
||||
* Aprendio a usar observables.
|
||||
|
||||
Esto concluye el tutorial "Tour de los Heroes".
|
||||
Estás listo para aprender más sobre el desarrollo Angular en la sección de fundamentos,
|
||||
comenzando con la guía [Arquitectura](guide/architecture "Architecture") guide.
|
||||
|
50
aio/diccionario-de-términos.md
Normal file
50
aio/diccionario-de-términos.md
Normal file
@ -0,0 +1,50 @@
|
||||
# Diccionario de Términos
|
||||
|
||||
En las siguiente tabla, definiremos palabras que generen dudas con respecto a su traducción. La intencion de la misma es clarificar cualquier inquitud con respecto a la palabra a utilizar, y que el colaborador simplemente utilice la palabra que se sugiere en la columna de traducción.
|
||||
|
||||
Un ejemplo de lo explicado en el parrafo anterior, en las frases de la documentación, donde veamos la palabra "Library", siguiendo la sugerencia de este archivo, la misma debe traducirse con su correspondiente palabra en el idioma español que es "Librería", y así con el resto de las sugerencias.
|
||||
|
||||
No todas las palabras en la traducción tienen que traducirse, algunas para mantener el contexto de la misma, no se debe traducir, un ejemplo claro puede ser la palabra "pipe".
|
||||
|
||||
Un detalle no menor es que al momento de traducir la documentación, debe estar en la forma de "tu", no en la forma de "usted".
|
||||
|
||||
A continuación algunas palabras las cuales hemos definido como traducción correcta.
|
||||
|
||||
| Palabra | Traducción |
|
||||
| ------------- |:------------------:|
|
||||
| About | Acerca / acerca |
|
||||
| Array | Array |
|
||||
| Angular CLI | CLI de Angular |
|
||||
| Bootstrap | Cargar |
|
||||
| Binding | Enlace |
|
||||
| Build | Crear / crear |
|
||||
| Building | Creando |
|
||||
| Builder | Constructor |
|
||||
| Bug | Bug |
|
||||
| Contributor | colaborador |
|
||||
| Company | Empresa |
|
||||
| Collaborator | colaborador |
|
||||
| Dependency Injection | Inyeción de dependencias |
|
||||
| Deployment | Despliege |
|
||||
| DI | ID |
|
||||
| Feature | Funcionalidad |
|
||||
| Lazy load | Carga diferida |
|
||||
| Library | Librería |
|
||||
| Observables | Observables |
|
||||
| Pipe | Pipe |
|
||||
| Pipeline | Pipeline |
|
||||
| Promises | Promesas |
|
||||
| Pull Request | Pull Request |
|
||||
| Map | map |
|
||||
| Module | Módulo |
|
||||
| Getting start | comenzando |
|
||||
| Issue | Issue |
|
||||
| Roadmap | Hoja de ruta |
|
||||
| Router | Enrutador |
|
||||
| Server-side Rendering | renderizado del lado del servidor |
|
||||
| Setup | Preparar |
|
||||
| Service Workers | Trabajadores de Servicio |
|
||||
| Shell | Armazón/Carcaza |
|
||||
| Schematics | Esquemas |
|
||||
| Template HTML | Plantilla HTML |
|
||||
| Cross Platform | Multiplataforma |
|
@ -52,7 +52,6 @@
|
||||
"deploy-production": "scripts/deploy-to-firebase.sh",
|
||||
"check-env": "yarn ~~check-env",
|
||||
"postcheck-env": "yarn aio-check-local",
|
||||
"payload-size": "scripts/payload.sh",
|
||||
"predocs": "node scripts/contributors/check-pictures && yarn generate-stackblitz && yarn generate-zips",
|
||||
"docs": "yarn docs-only",
|
||||
"docs-only": "dgeni ./tools/transforms/angular.io-package",
|
||||
@ -93,6 +92,7 @@
|
||||
"@angular/compiler": "10.0.2",
|
||||
"@angular/core": "10.0.2",
|
||||
"@angular/elements": "10.0.2",
|
||||
"@angular/fire": "~6.0.3",
|
||||
"@angular/forms": "10.0.2",
|
||||
"@angular/material": "10.0.1",
|
||||
"@angular/platform-browser": "10.0.2",
|
||||
@ -100,6 +100,9 @@
|
||||
"@angular/router": "10.0.2",
|
||||
"@angular/service-worker": "10.0.2",
|
||||
"@webcomponents/custom-elements": "1.2.1",
|
||||
"firebase": "~7.18.0",
|
||||
"first-input-delay": "^0.1.3",
|
||||
"proxy-polyfill": "^0.3.2",
|
||||
"rxjs": "^6.5.3",
|
||||
"tslib": "^1.10.0",
|
||||
"zone.js": "~0.10.3"
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user