Merge remote-tracking branch 'en/master' into aio

# Conflicts:
#	aio/content/cli/index.md
#	aio/content/file-not-found.md
#	aio/content/guide/architecture-modules.md
#	aio/content/guide/architecture-services.md
#	aio/content/guide/build.md
#	aio/content/guide/deployment.md
#	aio/content/guide/elements.md
#	aio/content/guide/feature-modules.md
#	aio/content/guide/file-structure.md
#	aio/content/guide/forms-overview.md
#	aio/content/guide/glossary.md
#	aio/content/guide/i18n.md
#	aio/content/guide/npm-packages.md
#	aio/content/guide/releases.md
#	aio/content/guide/router.md
#	aio/content/guide/service-worker-config.md
#	aio/content/guide/service-worker-intro.md
#	aio/content/guide/testing.md
#	aio/content/guide/upgrade-performance.md
#	aio/content/navigation.json
#	aio/content/tutorial/toh-pt0.md
#	aio/content/tutorial/toh-pt5.md
#	aio/content/tutorial/toh-pt6.md
#	aio/package.json
#	aio/src/app/custom-elements/api/api-list.component.ts
#	aio/src/app/documents/document.service.ts
#	aio/src/app/layout/top-menu/top-menu.component.ts
#	aio/src/index.html
#	aio/src/styles/2-modules/_api-pages.scss
#	aio/tools/transforms/templates/api/base.template.html
#	aio/tools/transforms/templates/api/lib/memberHelpers.html
#	aio/tools/transforms/templates/cli/cli-container.template.html
#	aio/tools/transforms/templates/lib/githubLinks.html
#	aio/yarn.lock
#	packages/animations/src/animation_metadata.ts
#	packages/common/http/src/backend.ts
#	packages/common/http/src/client.ts
#	packages/common/http/src/headers.ts
#	packages/common/http/src/interceptor.ts
#	packages/common/http/src/module.ts
#	packages/common/http/src/params.ts
#	packages/common/http/src/request.ts
#	packages/common/http/src/response.ts
#	packages/common/src/common_module.ts
#	packages/common/src/directives/ng_class.ts
#	packages/common/src/directives/ng_style.ts
#	packages/common/src/directives/ng_switch.ts
#	packages/common/src/i18n/format_date.ts
#	packages/common/src/pipes/number_pipe.ts
#	packages/core/src/change_detection/change_detection_util.ts
#	packages/core/src/change_detection/pipe_transform.ts
#	packages/core/src/di/injectable.ts
#	packages/core/src/linker/element_ref.ts
#	packages/core/src/linker/template_ref.ts
#	packages/core/src/metadata/di.ts
#	packages/core/src/metadata/directives.ts
#	packages/core/src/metadata/lifecycle_hooks.ts
#	packages/core/src/metadata/ng_module.ts
#	packages/core/src/render/api.ts
#	packages/forms/src/directives/form_interface.ts
#	packages/forms/src/directives/ng_form.ts
#	packages/forms/src/directives/ng_model.ts
#	packages/forms/src/directives/reactive_directives/form_control_name.ts
#	packages/forms/src/directives/select_control_value_accessor.ts
#	packages/forms/src/directives/validators.ts
#	packages/forms/src/form_builder.ts
#	packages/forms/src/form_providers.ts
#	packages/forms/src/model.ts
#	packages/forms/src/validators.ts
#	packages/platform-browser/src/browser.ts
#	packages/platform-browser/src/security/dom_sanitization_service.ts
#	packages/router/src/config.ts
#	packages/router/src/events.ts
#	packages/router/src/router.ts
#	packages/router/src/router_module.ts
#	packages/router/src/shared.ts
This commit is contained in:
Zhicheng WANG 2018-12-29 16:04:37 +08:00
commit 8744f17f5d
1273 changed files with 80901 additions and 44768 deletions

4
.bazelignore Normal file
View File

@ -0,0 +1,4 @@
node_modules
dist
aio/node_modules
aio/tools/examples/shared/node_modules

View File

@ -1,3 +1,11 @@
# Load any settings specific to the current user
try-import .bazelrc.user
################################
# Settings for Angular team members only
################################
# To enable this feature check the "Remote caching" section in docs/BAZEL.md.
build:angular-team --remote_http_cache=https://storage.googleapis.com/angular-team-cache
###############################
# Typescript / Angular / Sass #
###############################
@ -24,12 +32,18 @@ build --symlink_prefix=/
# Performance: avoid stat'ing input files
build --watchfs
# Turn off legacy external runfiles
run --nolegacy_external_runfiles
test --nolegacy_external_runfiles
###############################
# Release support #
# Turn on these settings with #
# --config=release #
###############################
# Releases should always be stamped with version control info
build --workspace_status_command=./tools/bazel_stamp_vars.sh
build:release --workspace_status_command=./tools/bazel_stamp_vars.sh
###############################
# Output #
@ -57,6 +71,31 @@ test --experimental_ui
################################
# Temporary Settings for Ivy #
################################
# to determine if the compiler used should be Ivy or ViewEngine one can use `--define=compile=local` on
# to determine if the compiler used should be Ivy or ViewEngine one can use `--define=compile=aot` on
# any bazel target. This is a temporary flag until codebase is permanently switched to Ivy.
build --define=compile=legacy
build --define=compile=legacy
###############################
# Remote Build Execution support
# Turn on these settings with
# --config=remote
###############################
# Load default settings for Remote Build Execution
import %workspace%/third_party/github.com/bazelbuild/bazel-toolchains/bazelrc/bazel-0.20.0.bazelrc
# Increase the default number of jobs by 50% because our build has lots of
# parallelism
build:remote --jobs=150
# Point to our custom execution platform; see tools/BUILD.bazel
build:remote --extra_execution_platforms=//tools:rbe_ubuntu1604-angular
build:remote --host_platform=//tools:rbe_ubuntu1604-angular
build:remote --platforms=//tools:rbe_ubuntu1604-angular
# Remote instance.
build:remote --remote_instance_name=projects/internal-200822/instances/default_instance
# Do not accept remote cache.
# We need to understand the security risks of using prior build artifacts.
build:remote --remote_accept_cached=false

42
.buildkite/Dockerfile Normal file
View File

@ -0,0 +1,42 @@
# Heavily based on https://github.com/StefanScherer/dockerfiles-windows/ images.
# Combines the node windowsservercore image with the Bazel Prerequisites (https://docs.bazel.build/versions/master/install-windows.html).
# msys install taken from https://github.com/StefanScherer/dockerfiles-windows/issues/30
# VS redist install taken from https://github.com/StefanScherer/dockerfiles-windows/blob/master/apache/Dockerfile
# The nanoserver image won't work because MSYS2 does not run in it https://github.com/Alexpux/MSYS2-packages/issues/1493
# Before building this image, you must locally build node-windows:10.13.0-windowsservercore-1803.
# Clone https://github.com/StefanScherer/dockerfiles-windows/commit/4ce7101a766b9b880ac262479dd9126b64d656cf and build using
# docker build -t node-windows:10.13.0-windowsservercore-1803 --build-arg core=microsoft/windowsservercore:1803 --build-arg target=microsoft/windowsservercore:1803 .
FROM node-windows:10.13.0-windowsservercore-1803
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
# Install 7zip to extract msys2
RUN Invoke-WebRequest -UseBasicParsing 'https://www.7-zip.org/a/7z1805-x64.exe' -OutFile 7z.exe
# For some reason the last letter in the destination directory is lost. So '/D=C:\\7zip0' will extract to '/D=C:\\7zip'.
RUN Start-Process -FilePath 'C:\\7z.exe' -ArgumentList '/S', '/D=C:\\7zip0' -NoNewWindow -Wait
# Extract msys2
RUN Invoke-WebRequest -UseBasicParsing 'http://repo.msys2.org/distrib/x86_64/msys2-base-x86_64-20180531.tar.xz' -OutFile msys2.tar.xz
RUN Start-Process -FilePath 'C:\\7zip\\7z' -ArgumentList 'e', 'msys2.tar.xz' -Wait
RUN Start-Process -FilePath 'C:\\7zip\\7z' -ArgumentList 'x', 'msys2.tar', '-oC:\\' -Wait
RUN Remove-Item msys2.tar.xz
RUN Remove-Item msys2.tar
RUN Remove-Item 7z.exe
RUN Remove-Item -Recurse 7zip
# Add MSYS2 to PATH, and set BAZEL_SH
RUN [Environment]::SetEnvironmentVariable('Path', $env:Path + ';C:\msys64\usr\bin', [System.EnvironmentVariableTarget]::Machine)
RUN [Environment]::SetEnvironmentVariable('BAZEL_SH', 'C:\msys64\usr\bin\bash.exe', [System.EnvironmentVariableTarget]::Machine)
# Install Microsoft Visual C++ Redistributable for Visual Studio 2015
RUN Invoke-WebRequest -UseBasicParsing 'https://download.microsoft.com/download/9/3/F/93FCF1E7-E6A4-478B-96E7-D4B285925B00/vc_redist.x64.exe' -OutFile vc_redist.x64.exe
RUN Start-Process 'c:\\vc_redist.x64.exe' -ArgumentList '/Install', '/Passive', '/NoRestart' -NoNewWindow -Wait
RUN Remove-Item vc_redist.x64.exe
# Add a fix for https://github.com/docker/for-win/issues/2920 as entry point to the container.
SHELL ["cmd", "/c"]
COPY "fix-msys64.cmd" "C:\\fix-msys64.cmd"
ENTRYPOINT cmd /C C:\\fix-msys64.cmd && cmd /c
CMD ["cmd.exe"]

96
.buildkite/README.md Normal file
View File

@ -0,0 +1,96 @@
# BuildKite configuration
This folder contains configuration for the [BuildKite](https://buildkite.com) based CI checks for
this repository.
BuildKite is a CI provider that provides build coordination and reports while we provide the
infrastructure.
CI runs are triggered by new PRs and will show up on the GitHub checks interface, along with the
other current CI solutions.
Currently it is only used for tests on Windows platforms.
## The build pipeline
BuildKite uses a pipeline for each repository. The `pipeline.yml` file defines pipeline
[build steps](https://buildkite.com/docs/pipelines/defining-steps) for this repository.
Run results can be seen in the GitHub checks interface and in the
[pipeline dashboard](https://buildkite.com/angular/angular).
Although most configuration is done via `pipeline.yml`, some options are only available
in the online [pipeline settings](https://buildkite.com/angular/angular/settings).
## Infrastructure
BuildKite does not provide the host machines where the builds runs, providing instead the
[BuildKite Agent](https://buildkite.com/docs/agent/v3) that should be run our own infrastructure.
### Agents
This agent polls the BuildKite API for builds, runs them, and reports back the results.
Agents are the unit of concurrency: each agent can run one build at any given time.
Adding agents allows more builds to be ran at the same time.
Individual agents can have tags, and pipeline steps can target only agents with certain tags via the
`agents` field in `pipeline.yml`.
For example: agents on Windows machines are tagged as `windows`, and the Windows specific build
steps list `windows: true` in their `agents` field.
You can see the current agent pool, along with their tags, in the
[agents list](https://buildkite.com/organizations/angular/agents).
### Our host machines
We use [Google Cloud](https://cloud.google.com/) as our cloud provider, under the
[Angular project](https://console.cloud.google.com/home/dashboard?project=internal-200822).
To access this project you need need to be logged in with a Google account that's a member of
team@angular.io.
For googlers this may be your google.com account, for others it is an angular.io account.
In this project we have a number of Windows VMs running, each of them with several agents.
The `provision-windows-buildkite.ps1` file contains instructions on how to create new host VMs that
are fully configured to run the BuildKite agents as services.
Our pipeline uses [docker-buildkite-plugin](https://github.com/buildkite-plugins/docker-buildkite-plugin)
to run build steps inside docker containers.
This way we achieve isolation and hermeticity.
The `Dockerfile` file describes a custom Docker image that includes NodeJs, Yarn, and the Bazel
pre-requisites on Windows.
To upload a new version of the docker image, follow any build instructions in `Dockerfile` and then
run `docker build -t angular/node-bazel-windows:NEW_VERSION`, followed by
`docker push angular/node-bazel-windows:NEW_VERSION`.
After being pushed it should be available online, and you can use the new version in `pipeline.yml`.
## Caretaker
BuildKite status can be found at https://www.buildkitestatus.com/.
Issues related to the BuildKite setup should be escalated to the Tools Team via the current
caretaker, followed by Alex Eagle and Filipe Silva.
Support requests should be submitted via email to support@buildkite.com and cc Igor, Misko, Alex,
Jeremy and Manu
## Rollout strategy
At the moment our BuildKite CI uses 1 host VM running 4 agents, thus being capable of 4 concurrent
builds.
The only test running is `bazel test //tools/ts-api-guardian:all`, and the PR check is not
mandatory.
In the future we should add cache support to speed up the initial `yarn` install, and also Bazel
remote caching to speed up Bazel builds.
After the current setup is verified as stable and reliable the GitHub PR check can become mandatory.
The tests ran should also be expanded to cover most, if not all, of the Bazel tests.

View File

@ -0,0 +1,6 @@
@echo off
REM Fix for https://github.com/docker/for-win/issues/2920
REM echo "Fixing msys64 folder..."
REM Touch all .dll files inside C:\msys64\
forfiles /p C:\msys64\ /s /m *.dll /c "cmd /c Copy /B @path+,, >NUL"
REM echo "Fixed msys64 folder."

10
.buildkite/pipeline.yml Normal file
View File

@ -0,0 +1,10 @@
steps:
- label: windows-test
commands:
- "yarn install --frozen-lockfile --non-interactive --network-timeout 100000"
- "yarn bazel test //tools/ts-api-guardian:all --noshow_progress"
plugins:
- docker#v2.1.0:
image: "filipesilva/node-bazel-windows:0.0.2"
agents:
windows: true

View File

@ -0,0 +1,92 @@
# PowerShell script to provision a Windows Server with BuildKite
# This script follows https://buildkite.com/docs/agent/v3/windows.
# Instructions
# VM creation:
# In Google Cloud Platform, create a Compute Engine instance.
# We recommend machine type n1-highcpu-16 (16 vCPUs, 14.4 GB memory).
# Use a windows boot disk with container support such as
# "Windows Server version 1803 Datacenter Core for Containers".
# Give it a name, then click "Create".
# VM setup:
# In the Compute Engine menu, select "VM Instances". Click on the VM name you chose before.
# Click "Set Windows Password" to choose a username and password.
# Click RDP to open a remote desktop via browser, using the username and password.
# In the Windows command prompt start an elevated powershell by inputing
# "powershell -Command "Start-Process PowerShell -Verb RunAs" followed by Enter.
# Download and execute this script from GitHub, passing the token (mandatory), tags (optional)
# and number of agents (optional) as args:
# ```
# Invoke-WebRequest -Uri https://raw.githubusercontent.com/angular/angular/master/.buildkite/provision-windows-buildkite.ps1 -OutFile provision.ps1
# .\provision.ps1 -token "MY_TOKEN" -tags "windows=true,another_tag=true" -agents 4
# ```
# The VM should restart and be fully configured.
# Creating extra VMs
# You can create an image of the current VM by following the instructions below.
# https://cloud.google.com/compute/docs/instances/windows/creating-windows-os-image
# Then create a new VM and choose "Custom images".
# Script proper.
# Get the token and tags from arguments.
param (
[Parameter(Mandatory=$true)][string]$token,
[string]$tags = ""
[Int]$agents = 1
)
# Allow HTTPS
[Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls"
# Helper to add to PATH.
# Will take current PATH so avoid running it after anything to modifies only the powershell session path.
function Add-Path ([string]$newPathItem) {
$Env:Path+= ";" + $newPathItem + ";"
[Environment]::SetEnvironmentVariable("Path",$env:Path, [System.EnvironmentVariableTarget]::Machine)
}
# Install Git for Windows
Write-Host "Installing Git for Windows."
Invoke-WebRequest -Uri https://github.com/git-for-windows/git/releases/download/v2.19.1.windows.1/Git-2.19.1-64-bit.exe -OutFile git.exe
.\git.exe /VERYSILENT /NORESTART /NOCANCEL /SP- /CLOSEAPPLICATIONS /RESTARTAPPLICATIONS /COMPONENTS="icons,ext\reg\shellhere,assoc,assoc_sh" /DIR="C:\git"
Add-Path "C:\git\bin"
Remove-Item git.exe
# Download NSSM (https://nssm.cc/) to run the BuildKite agent as a service.
Write-Host "Downloading NSSM."
Invoke-WebRequest -Uri https://nssm.cc/ci/nssm-2.24-101-g897c7ad.zip -OutFile nssm.zip
Expand-Archive -Path nssm.zip -DestinationPath C:\nssm
Add-Path "C:\nssm\nssm-2.24-101-g897c7ad\win64"
Remove-Item nssm.zip
# Run the BuildKite agent install script
Write-Host "Installing BuildKite agent."
$env:buildkiteAgentToken = $token
$env:buildkiteAgentTags = $tags
Set-ExecutionPolicy Bypass -Scope Process -Force
iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/buildkite/agent/master/install.ps1'))
# Configure the BuildKite agent clone and timestamp behavior
Add-Content C:\buildkite-agent\buildkite-agent.cfg "`ngit-clone-flags=--config core.autocrlf=input --config core.eol=lf --config core.longpaths=true --config core.symlinks=true`n"
Add-Content C:\buildkite-agent\buildkite-agent.cfg "`ntimestamp-lines=true`n"
# Register the BuildKite agent service using NSSM, so that it persists through restarts and is
# restarted if the process dies.
for ($i=1; $i -le $agents; $i++)
{
$agentName = "buildkite-agent-$i"
Write-Host "Registering $agentName as a service."
nssm.exe install $agentName "C:\buildkite-agent\bin\buildkite-agent.exe" "start"
nssm.exe set $agentName AppStdout "C:\buildkite-agent\$agentName.log"
nssm.exe set $agentName AppStderr "C:\buildkite-agent\$agentName.log"
nssm.exe status $agentName
nssm.exe start $agentName
nssm.exe status $agentName
}
# Restart the machine.
Restart-Computer

View File

@ -13,7 +13,7 @@ a GitHub token that enables publishing snapshots.
To create the github_token file, we take this approach:
- Find the angular-builds:token in http://valentine
- Go inside the ngcontainer docker image so you use the same version of openssl as we will at runtime: `docker run --rm -it angular/ngcontainer`
- Go inside the CircleCI default docker image so you use the same version of openssl as we will at runtime: `docker run --rm -it circleci/node:10.12`
- echo "https://[token]:@github.com" > credentials
- openssl aes-256-cbc -e -in credentials -out .circleci/github_token -k $KEY
- If needed, base64-encode the result so you can copy-paste it out of docker: `base64 github_token`

View File

@ -1,6 +1,6 @@
# These options are enabled when running on CI
# We do this by copying this file to /etc/bazel.bazelrc at the start of the build.
# See remote cache documentation in /docs/BAZEL.md
# See documentation in /docs/BAZEL.md
# Don't be spammy in the logs
# TODO(gmagolan): Hide progress again once build performance improves
@ -8,18 +8,11 @@
# error: Too long with no output (exceeded 10m0s)
# build --noshow_progress
# Don't run manual tests
test --test_tag_filters=-manual
# Print all the options that apply to the build.
# This helps us diagnose which options override others
# (e.g. /etc/bazel.bazelrc vs. tools/bazel.rc)
build --announce_rc
# Create dist/bin symlink to $(bazel info bazel-bin)
# We use this when uploading artifacts after the build finishes
build --symlink_prefix=dist/
# Workaround https://github.com/bazelbuild/bazel/issues/3645
# Bazel doesn't calculate the memory ceiling correctly when running under Docker.
# Limit Bazel to consuming resources that fit in CircleCI "xlarge" class

View File

@ -7,95 +7,121 @@
# To validate changes, use an online parser, eg.
# http://yaml-online-parser.appspot.com/
# Variables
## IMPORTANT
# If you change the `docker_image` version, also change the `cache_key` suffix and the version of
# `com_github_bazelbuild_buildtools` in the `/WORKSPACE` file.
var_1: &docker_image angular/ngcontainer:0.6.0
var_2: &cache_key v2-angular-{{ .Branch }}-{{ checksum "yarn.lock" }}-0.6.0
# Note that the browser docker image comes with Chrome and Firefox preinstalled. This is just
# needed for jobs that run tests without Bazel. Bazel runs tests with browsers that will be
# fetched by the Webtesting rules. Therefore for jobs that run tests with Bazel, we don't need a
# docker image with browsers pre-installed.
# **NOTE**: If you change the version of the docker images, also change the `cache_key` suffix.
var_1: &default_docker_image circleci/node:10.12
var_2: &browsers_docker_image circleci/node:10.12-browsers
var_3: &cache_key v2-angular-{{ .Branch }}-{{ checksum "yarn.lock" }}-node-10.12
# Define common ENV vars
var_3: &define_env_vars
run: echo "export PROJECT_ROOT=$(pwd)" >> $BASH_ENV
# See remote cache documentation in /docs/BAZEL.md
var_4: &setup-bazel-remote-cache
var_4: &define_env_vars
run:
name: Start up bazel remote cache proxy
command: ~/bazel-remote-proxy -backend circleci://
background: true
name: Define environment variables
command: ./.circleci/env.sh
var_5: &setup_bazel_remote_execution
run:
name: "Setup bazel RBE remote execution"
command: openssl aes-256-cbc -d -in .circleci/gcp_token -k "${CIRCLE_PROJECT_REPONAME}" -out /home/circleci/.gcp_credentials && echo "export GOOGLE_APPLICATION_CREDENTIALS=/home/circleci/.gcp_credentials" >> $BASH_ENV && sudo bash -c "cat .circleci/rbe-bazel.rc >> /etc/bazel.bazelrc"
command: |
openssl aes-256-cbc -d -in .circleci/gcp_token -k "$CI_REPO_NAME" -out /home/circleci/.gcp_credentials
echo "export GOOGLE_APPLICATION_CREDENTIALS=/home/circleci/.gcp_credentials" >> $BASH_ENV
sudo bash -c "echo 'build --config=remote' >> /etc/bazel.bazelrc"
# Settings common to each job
anchor_1: &job_defaults
var_6: &job_defaults
working_directory: ~/ng
docker:
- image: *docker_image
- image: *default_docker_image
# After checkout, rebase on top of master.
# Similar to travis behavior, but not quite the same.
# See https://discuss.circleci.com/t/1662
anchor_2: &post_checkout
post: git pull --ff-only origin "refs/pull/${CIRCLE_PULL_REQUEST//*pull\//}/merge"
var_7: &post_checkout
post: git pull --ff-only origin "refs/pull/${CI_PULL_REQUEST//*pull\//}/merge"
var_8: &yarn_install
run:
name: Running Yarn install
command: yarn install --frozen-lockfile --non-interactive
var_9: &setup_circleci_bazel_config
run:
name: Setting up CircleCI bazel configuration
command: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
version: 2
jobs:
lint:
<<: *job_defaults
resource_class: xlarge
steps:
- checkout:
<<: *post_checkout
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
# Check BUILD.bazel formatting before we have a node_modules directory
# Then we don't need any exclude pattern to avoid checking those files
- run: 'yarn buildifier -mode=check ||
(echo "BUILD files not formatted. Please run ''yarn buildifier''" ; exit 1)'
# Run the skylark linter to check our Bazel rules
- run: 'yarn skylint ||
(echo -e "\n.bzl files have lint errors. Please run ''yarn skylint''"; exit 1)'
- restore_cache:
key: *cache_key
- *define_env_vars
- *yarn_install
- run: 'yarn bazel:format -mode=check ||
(echo "BUILD files not formatted. Please run ''yarn bazel:format''" ; exit 1)'
# Run the skylark linter to check our Bazel rules
- run: 'yarn bazel:lint ||
(echo -e "\n.bzl files have lint errors. Please run ''yarn bazel:lint-fix''"; exit 1)'
- run: yarn install --frozen-lockfile --non-interactive
- run: ./node_modules/.bin/gulp lint
test:
<<: *job_defaults
resource_class: xlarge
steps:
- *define_env_vars
- checkout:
<<: *post_checkout
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
- restore_cache:
key: *cache_key
- *define_env_vars
- *setup_circleci_bazel_config
- *yarn_install
- run: bazel info release
- run: bazel run @nodejs//:yarn
# Use bazel query so that we explicitly ask for all buildable targets to be built as well
# This avoids waiting for the slowest build target to finish before running the first test
# See https://github.com/bazelbuild/bazel/issues/4257
# NOTE: Angular developers should typically just bazel build //packages/... or bazel test //packages/...
# Setup remote execution and run RBE-compatible tests.
- *setup_bazel_remote_execution
- run: bazel query --output=label //... | xargs bazel test --build_tag_filters=-ivy-only --test_tag_filters=-manual,-ivy-only,-local
- run: yarn bazel test //... --build_tag_filters=-ivy-only --test_tag_filters=-ivy-only,-local
# Now run RBE incompatible tests locally.
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
- run: bazel query --output=label //... | xargs bazel test --build_tag_filters=-ivy-only,local --test_tag_filters=-manual,-ivy-only,local
- run: yarn bazel test //... --build_tag_filters=-ivy-only,local --test_tag_filters=-ivy-only,local
# CircleCI will allow us to go back and view/download these artifacts from past builds.
# Also we can use a service like https://buildsize.org/ to automatically track binary size of these artifacts.
# The destination keys need be format {projectName}/{context}/{fileName} so that the github-robot can process them for size calculations
# projectName should remain consistant to group files
# context and fileName can be almost anything (within usual URI rules)
# There should only be exactly 2 forward slashes in the path
# This is so they're backwards compatiable with the existing data we have on bundle sizes
- save_cache:
key: *cache_key
paths:
- "node_modules"
- "~/bazel_repository_cache"
# Temporary job to test what will happen when we flip the Ivy flag to true
test_ivy_aot:
<<: *job_defaults
resource_class: xlarge
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- *setup_circleci_bazel_config
- *yarn_install
- *setup_bazel_remote_execution
# 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: yarn test-ivy-aot //... --symlink_prefix=dist/
# 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
@ -108,39 +134,131 @@ jobs:
- store_artifacts:
path: dist/bin/packages/core/test/bundling/todo/bundle.min.js.br
destination: core/todo/bundle.br
- save_cache:
test_aio:
<<: *job_defaults
docker:
# Needed because the AIO tests and the PWA score test depend on Chrome being available.
- image: *browsers_docker_image
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
paths:
- "node_modules"
- "~/bazel_repository_cache"
# Temporary job to test what will happen when we flip the Ivy flag to true
test_ivy_jit:
<<: *job_defaults
resource_class: xlarge
steps:
- *define_env_vars
# Build aio
- run: yarn --cwd aio build --progress=false
# Lint the code
- run: yarn --cwd aio lint
# Run PWA-score tests
# (Run before unit and e2e tests, which destroy the `dist/` directory.)
- run: yarn --cwd aio test-pwa-score-localhost $CI_AIO_MIN_PWA_SCORE
# Check the bundle sizes.
# (Run before unit and e2e tests, which destroy the `dist/` directory.)
- run: yarn --cwd aio payload-size
# Run unit tests
- run: yarn --cwd aio test --watch=false
# Run e2e tests
- run: yarn --cwd aio e2e
# Run unit tests for Firebase redirects
- run: yarn --cwd aio redirects-test
deploy_aio:
<<: *job_defaults
docker:
# Needed because before deploying the deploy-production script runs the PWA score tests.
- image: *browsers_docker_image
steps:
- checkout:
<<: *post_checkout
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
- run: bazel run @yarn//:yarn
- *setup_bazel_remote_execution
- run: bazel query --output=label //... | xargs bazel test --define=compile=jit --build_tag_filters=ivy-jit --test_tag_filters=-manual,ivy-jit
test_ivy_aot:
<<: *job_defaults
resource_class: xlarge
steps:
- restore_cache:
key: *cache_key
- *define_env_vars
# Deploy angular.io to production (if necessary)
- run: setPublicVar CI_STABLE_BRANCH "$(npm info @angular/core dist-tags.latest | sed -r 's/^\s*([0-9]+\.[0-9]+)\.[0-9]+.*$/\1.x/')"
- run: yarn --cwd aio deploy-production
test_aio_local:
<<: *job_defaults
docker:
# Needed because the AIO tests and the PWA score test depend on Chrome being available.
- image: *browsers_docker_image
steps:
- checkout:
<<: *post_checkout
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
- restore_cache:
key: *cache_key
- attach_workspace:
at: dist
- *define_env_vars
# Build aio (with local Angular packages)
- run: yarn --cwd aio build-local --progress=false
# Run PWA-score tests
# (Run before unit and e2e tests, which destroy the `dist/` directory.)
- run: yarn --cwd aio test-pwa-score-localhost $CI_AIO_MIN_PWA_SCORE
# Run unit tests
- run: yarn --cwd aio test --watch=false
# Run e2e tests
- run: yarn --cwd aio e2e
- run: bazel run @yarn//:yarn
- *setup_bazel_remote_execution
- run: bazel query --output=label //... | xargs bazel test --define=compile=local --build_tag_filters=ivy-local --test_tag_filters=-manual,ivy-local
test_aio_tools:
<<: *job_defaults
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- attach_workspace:
at: dist
- *define_env_vars
# Install
- run: yarn --cwd aio install --frozen-lockfile --non-interactive
- run: yarn --cwd aio extract-cli-command-docs
# Run tools tests
- run: yarn --cwd aio tools-test
- run: ./aio/aio-builds-setup/scripts/test.sh
# This job should only be run on PR builds, where `CIRCLE_PR_NUMBER` is defined.
test_docs_examples_0:
<<: *job_defaults
docker:
# Needed because the example e2e tests depend on Chrome.
- image: *browsers_docker_image
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- attach_workspace:
at: dist
- *define_env_vars
# Install root
- *yarn_install
# Install aio
- run: yarn --cwd aio install --frozen-lockfile --non-interactive
# Run examples tests
- run: yarn --cwd aio example-e2e --setup --local --shard=0/2
test_docs_examples_1:
<<: *job_defaults
docker:
# Needed because the example e2e tests depend on Chrome.
- image: *browsers_docker_image
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- attach_workspace:
at: dist
- *define_env_vars
# Install root
- *yarn_install
# Install aio
- run: yarn --cwd aio install --frozen-lockfile --non-interactive
# Run examples tests
- run: yarn --cwd aio example-e2e --setup --local --shard=1/2
# This job should only be run on PR builds, where `CI_PULL_REQUEST` is not `false`.
aio_preview:
<<: *job_defaults
environment:
@ -150,28 +268,32 @@ jobs:
<<: *post_checkout
- restore_cache:
key: *cache_key
- run: yarn install --frozen-lockfile --non-interactive
- run: ./aio/scripts/build-artifacts.sh $AIO_SNAPSHOT_ARTIFACT_PATH $CIRCLE_PR_NUMBER $CIRCLE_SHA1
- *define_env_vars
- *yarn_install
- run: ./aio/scripts/build-artifacts.sh $AIO_SNAPSHOT_ARTIFACT_PATH $CI_PULL_REQUEST $CI_COMMIT
- store_artifacts:
path: *aio_preview_artifact_path
# The `destination` needs to be kept in synch with the value of
# `AIO_ARTIFACT_PATH` in `aio/aio-builds-setup/Dockerfile`
destination: aio/dist/aio-snapshot.tgz
- run: node ./aio/scripts/create-preview $CIRCLE_BUILD_NUM
# This job should only be run on PR builds, where `CIRCLE_PR_NUMBER` is defined.
# This job should only be run on PR builds, where `CI_PULL_REQUEST` is not `false`.
test_aio_preview:
<<: *job_defaults
docker:
# Needed because the test-preview script runs e2e tests and the PWA score test with Chrome.
- image: *browsers_docker_image
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- run: yarn install --cwd aio --frozen-lockfile --non-interactive
- run:
name: Wait for preview and run tests
command: |
source "./scripts/ci/env.sh" print
xvfb-run --auto-servernum node aio/scripts/test-preview.js $CIRCLE_PR_NUMBER $CIRCLE_SHA1 $AIO_MIN_PWA_SCORE
command: node aio/scripts/test-preview.js $CI_PULL_REQUEST $CI_COMMIT $CI_AIO_MIN_PWA_SCORE
# This job exists only for backwards-compatibility with old scripts and tests
# that rely on the pre-Bazel dist/packages-dist layout.
@ -184,12 +306,15 @@ jobs:
<<: *job_defaults
resource_class: xlarge
steps:
- *define_env_vars
- checkout:
<<: *post_checkout
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
- run: bazel run @nodejs//:yarn
- restore_cache:
key: *cache_key
- *define_env_vars
- *setup_circleci_bazel_config
- *yarn_install
- *setup_bazel_remote_execution
- run: scripts/build-packages-dist.sh
# Save the npm packages from //packages/... for other workflow jobs to read
@ -198,8 +323,7 @@ jobs:
root: dist
paths:
- packages-dist
- packages-dist-ivy-jit
- packages-dist-ivy-local
- packages-dist-ivy-aot
# We run the integration tests outside of Bazel for now.
# They are a separate workflow job so that they can be easily re-run.
@ -209,35 +333,41 @@ jobs:
# See comments inside the integration/run_tests.sh script.
integration_test:
<<: *job_defaults
docker:
# Needed because the integration tests expect Chrome to be installed (e.g cli-hello-world)
- image: *browsers_docker_image
# Note: we run Bazel in one of the integration tests, and it can consume >2G
# of memory. Together with the system under test, this can exhaust the RAM
# on a 4G worker so we use a larger machine here too.
resource_class: xlarge
steps:
- *define_env_vars
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- attach_workspace:
at: dist
- run: xvfb-run --auto-servernum ./integration/run_tests.sh
- *define_env_vars
- run: ./integration/run_tests.sh
# This job updates the content of repos like github.com/angular/core-builds
# for every green build on angular/angular.
publish_snapshot:
<<: *job_defaults
steps:
- checkout:
<<: *post_checkout
- *define_env_vars
# 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, `|| true` on the end makes this step always exit 0
command: '[[
-v CIRCLE_PR_NUMBER
|| "$CIRCLE_PROJECT_USERNAME" != "angular"
|| "$CIRCLE_PROJECT_REPONAME" != "angular"
"$CI_PULL_REQUEST" != "false"
|| "$CI_REPO_OWNER" != "angular"
|| "$CI_REPO_NAME" != "angular"
]] && circleci step halt || true'
- checkout:
<<: *post_checkout
- attach_workspace:
at: dist
# CircleCI has a config setting to force SSH for all github connections
@ -251,16 +381,23 @@ jobs:
aio_monitoring:
<<: *job_defaults
docker:
# This job needs Chrome to be globally installed because the tests run with Protractor
# which does not load the browser through the Bazel webtesting rules.
- image: *browsers_docker_image
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- run:
name: Run tests against the deployed apps
command: |
source "./scripts/ci/env.sh" print
xvfb-run --auto-servernum ./aio/scripts/test-production.sh $AIO_MIN_PWA_SCORE
command: ./aio/scripts/test-production.sh $CI_AIO_MIN_PWA_SCORE
- run:
name: Notify caretaker about failure
command: 'curl --request POST --header "Content-Type: application/json" --data "{\"text\":\":x: \`$CIRCLE_JOB\` job failed on build $CIRCLE_BUILD_NUM: $CIRCLE_BUILD_URL :scream:\"}" $CI_SECRET_SLACK_CARETAKER_WEBHOOK_URL'
when: on_fail
workflows:
version: 2
@ -268,9 +405,24 @@ workflows:
jobs:
- lint
- test
- test_ivy_jit
- test_ivy_aot
- build-packages-dist
- test_aio
- deploy_aio:
requires:
- test_aio
- test_aio_local:
requires:
- build-packages-dist
- test_aio_tools:
requires:
- build-packages-dist
- test_docs_examples_0:
requires:
- build-packages-dist
- test_docs_examples_1:
requires:
- build-packages-dist
- aio_preview:
# Only run on PR builds. (There can be no previews for non-PR builds.)
filters:
@ -290,9 +442,12 @@ workflows:
requires:
# Only publish if tests and integration tests pass
- test
- test_ivy_jit
- test_ivy_aot
- integration_test
# Only publish if `aio`/`docs` tests using the locally built Angular packages pass
- test_aio_local
- test_docs_examples_0
- test_docs_examples_1
# Get the artifacts to publish from the build-packages-dist job
# since the publishing script expects the legacy outputs layout.
- build-packages-dist
@ -307,7 +462,3 @@ workflows:
branches:
only:
- master
notify:
webhooks:
- url: https://ngbuilds.io/circle-build

View File

@ -0,0 +1,38 @@
####################################################################################################
# Helpers for defining environment variables for CircleCI.
#
# In CircleCI, each step runs in a new shell. The way to share ENV variables across steps is to
# export them from `$BASH_ENV`, which is automatically sourced at the beginning of every step (for
# the default `bash` shell).
#
# See also https://circleci.com/docs/2.0/env-vars/#using-bash_env-to-set-environment-variables.
####################################################################################################
# Set and print an environment variable.
#
# Use this function for setting environment variables that are public, i.e. it is OK for them to be
# visible to anyone through the CI logs.
#
# Usage: `setPublicVar <name> <value>`
function setPublicVar() {
setSecretVar $1 $2;
echo "$1=$2";
}
# Set (without printing) an environment variable.
#
# Use this function for setting environment variables that are secret, i.e. should not be visible to
# everyone through the CI logs.
#
# Usage: `setSecretVar <name> <value>`
function setSecretVar() {
# WARNING: Secrets (e.g. passwords, access tokens) should NOT be printed.
# (Keep original shell options to restore at the end.)
local -r originalShellOptions=$(set +o);
set +x -eu -o pipefail;
echo "export $1=\"${2:-}\";" >> $BASH_ENV;
# Restore original shell options.
eval "$originalShellOptions";
}

35
.circleci/env.sh Executable file
View File

@ -0,0 +1,35 @@
#!/usr/bin/env bash
# Load helpers and make them available everywhere (through `$BASH_ENV`).
readonly envHelpersPath="`dirname $0`/env-helpers.inc.sh";
source $envHelpersPath;
echo "source $envHelpersPath;" >> $BASH_ENV;
####################################################################################################
# Define PUBLIC environment variables for CircleCI.
####################################################################################################
setPublicVar PROJECT_ROOT "$(pwd)";
setPublicVar CI_AIO_MIN_PWA_SCORE "95";
# This is the branch being built; e.g. `pull/12345` for PR builds.
setPublicVar CI_BRANCH "$CIRCLE_BRANCH";
setPublicVar CI_COMMIT "$CIRCLE_SHA1";
# `CI_COMMIT_RANGE` will only be available when `CIRCLE_COMPARE_URL` is also available,
# i.e. on push builds (a.k.a. non-PR builds). That is fine, since we only need it in push builds.
setPublicVar CI_COMMIT_RANGE "$(sed -r 's|^.*/([0-9a-f]+\.\.\.[0-9a-f]+)$|\1|i' <<< ${CIRCLE_COMPARE_URL:-})";
setPublicVar CI_PULL_REQUEST "${CIRCLE_PR_NUMBER:-false}";
setPublicVar CI_REPO_NAME "$CIRCLE_PROJECT_REPONAME";
setPublicVar CI_REPO_OWNER "$CIRCLE_PROJECT_USERNAME";
####################################################################################################
# Define SECRET environment variables for CircleCI.
####################################################################################################
setSecretVar CI_SECRET_AIO_DEPLOY_FIREBASE_TOKEN "$AIO_DEPLOY_TOKEN";
setSecretVar CI_SECRET_PAYLOAD_FIREBASE_TOKEN "$ANGULAR_PAYLOAD_TOKEN";
# Defined in https://angular-team.slack.com/apps/A0F7VRE7N-circleci.
setSecretVar CI_SECRET_SLACK_CARETAKER_WEBHOOK_URL "$SLACK_CARETAKER_WEBHOOK_URL";
# Source `$BASH_ENV` to make the variables available immediately.
source $BASH_ENV;

Binary file not shown.

View File

@ -1,77 +0,0 @@
# These options are enabled when running on CI with Remote Build Execution.
################################################################
# Toolchain related flags for remote build execution. #
################################################################
# Remote Build Execution requires a strong hash function, such as SHA256.
startup --host_jvm_args=-Dbazel.DigestFunction=SHA256
# Depending on how many machines are in the remote execution instance, setting
# this higher can make builds faster by allowing more jobs to run in parallel.
# Setting it too high can result in jobs that timeout, however, while waiting
# for a remote machine to execute them.
build --jobs=150
# Set several flags related to specifying the platform, toolchain and java
# properties.
# These flags are duplicated rather than imported from (for example)
# %workspace%/configs/ubuntu16_04_clang/1.0/toolchain.bazelrc to make this
# bazelrc a standalone file that can be copied more easily.
# These flags should only be used as is for the rbe-ubuntu16-04 container
# and need to be adapted to work with other toolchain containers.
build --host_javabase=@bazel_toolchains//configs/ubuntu16_04_clang/1.0:jdk8
build --javabase=@bazel_toolchains//configs/ubuntu16_04_clang/1.0:jdk8
build --host_java_toolchain=@bazel_tools//tools/jdk:toolchain_hostjdk8
build --java_toolchain=@bazel_tools//tools/jdk:toolchain_hostjdk8
build --crosstool_top=@bazel_toolchains//configs/ubuntu16_04_clang/1.0/bazel_0.15.0/default:toolchain
build --action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1
# Platform flags:
# The toolchain container used for execution is defined in the target indicated
# by "extra_execution_platforms", "host_platform" and "platforms".
# If you are using your own toolchain container, you need to create a platform
# target with "constraint_values" that allow for the toolchain specified with
# "extra_toolchains" to be selected (given constraints defined in
# "exec_compatible_with").
# More about platforms: https://docs.bazel.build/versions/master/platforms.html
build --extra_toolchains=@bazel_toolchains//configs/ubuntu16_04_clang/1.0/bazel_0.15.0/cpp:cc-toolchain-clang-x86_64-default
build --extra_execution_platforms=//tools:rbe_ubuntu1604-angular
build --host_platform=//tools:rbe_ubuntu1604-angular
build --platforms=//tools:rbe_ubuntu1604-angular
# Set various strategies so that all actions execute remotely. Mixing remote
# and local execution will lead to errors unless the toolchain and remote
# machine exactly match the host machine.
build --spawn_strategy=remote
build --strategy=Javac=remote
build --strategy=Closure=remote
build --genrule_strategy=remote
build --define=EXECUTOR=remote
# Enable the remote cache so action results can be shared across machines,
# developers, and workspaces.
build --remote_cache=remotebuildexecution.googleapis.com
# Enable remote execution so actions are performed on the remote systems.
build --remote_executor=remotebuildexecution.googleapis.com
# Remote instance.
build --remote_instance_name=projects/internal-200822/instances/default_instance
# Enable encryption.
build --tls_enabled=true
# Enforce stricter environment rules, which eliminates some non-hermetic
# behavior and therefore improves both the remote cache hit rate and the
# correctness and repeatability of the build.
build --experimental_strict_action_env=true
# Set a higher timeout value, just in case.
build --remote_timeout=3600
# Enable authentication. This will pick up application default credentials by
# default. You can use --auth_credentials=some_file.json to use a service
# account credential instead.
build --auth_enabled=true
# Do not accept remote cache.
build --remote_accept_cached=false

View File

@ -0,0 +1,107 @@
#!/usr/bin/env node
/**
* Usage (cli):
* ```
* node create-preview <build-number> <job-name> <webhook-url>
* ```
*
* Usage (JS):
* ```js
* require('./trigger-webhook').
* triggerWebhook(buildNumber, jobName, webhookUrl).
* then(...);
* ```
*
* Triggers a notification webhook with CircleCI specific info.
*
* It can be used for notifying external servers and trigger operations based on CircleCI job status
* (e.g. triggering the creation of a preview based on previously stored build atrifacts).
*
* The body of the sent payload is of the form:
* ```json
* {
* "payload": {
* "build_num": ${buildNumber}
* "build_parameters": {
* "CIRCLE_JOB": "${jobName}"
* }
* }
* }
* ```
*
* When used from JS, it returns a promise which resolves to an object of the form:
* ```json
* {
* "statucCode": ${statusCode},
* "responseText": "${responseText}"
* }
* ```
*
* NOTE:
* - When used from the cli, the command will exit with an error code if the response's status code
* is outside the [200, 400) range.
* - When used from JS, the returned promise will be resolved, even if the response's status code is
* outside the [200, 400) range. It is up to the caller to decide how this should be handled.
*/
// Imports
const {request} = require('https');
// Exports
module.exports = {
triggerWebhook,
};
// Run
if (require.resolve === module) {
_main(process.argv.slice(2));
}
// Helpers
function _main(args) {
triggerWebhook(...args).
then(({statusCode, responseText}) => (200 <= statusCode && statusCode < 400) ?
console.log(`Status: ${statusCode}\n${responseText}`) :
Promise.reject(new Error(`Request failed (status: ${statusCode}): ${responseText}`))).
catch(err => {
console.error(err);
process.exit(1);
});
}
function postJson(url, data) {
return new Promise((resolve, reject) => {
const opts = {method: 'post', headers: {'Content-Type': 'application/json'}};
const onResponse = res => {
const statusCode = res.statusCode || -1;
let responseText = '';
res.
on('error', reject).
on('data', d => responseText += d).
on('end', () => resolve({statusCode, responseText}));
};
request(url, opts, onResponse).
on('error', reject).
end(JSON.stringify(data));
});
}
async function triggerWebhook(buildNumber, jobName, webhookUrl) {
if (!buildNumber || !jobName || !webhookUrl || isNaN(buildNumber)) {
throw new Error(
'Missing or invalid arguments.\n' +
'Expected: buildNumber (number), jobName (string), webhookUrl (string)');
}
const data = {
payload: {
build_num: +buildNumber,
build_parameters: {CIRCLE_JOB: jobName},
},
};
return postJson(webhookUrl, data);
}

View File

@ -1,4 +1,4 @@
# http://editorconfig.org
# https://editorconfig.org
root = true

View File

@ -1,59 +1,10 @@
<!--
PLEASE HELP US PROCESS GITHUB ISSUES FASTER BY PROVIDING THE FOLLOWING INFORMATION.
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
ISSUES MISSING IMPORTANT INFORMATION MAY BE CLOSED WITHOUT INVESTIGATION.
-->
Please help us process issues more efficiently by filing an
issue using one of the following templates:
## I'm submitting a...
<!-- Check one of the following options with "x" -->
<pre><code>
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report <!-- Please search GitHub for a similar issue or PR before submitting -->
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
[ ] Other... Please describe:
</code></pre>
https://github.com/angular/angular/issues/new/choose
## Current behavior
<!-- Describe how the issue manifests. -->
Thank you!
## Expected behavior
<!-- Describe what the desired behavior would be. -->
## Minimal reproduction of the problem with instructions
<!--
For bug reports please provide the *STEPS TO REPRODUCE* and if possible a *MINIMAL DEMO* of the problem via
https://stackblitz.com or similar (you can use this template as a starting point: https://stackblitz.com/fork/angular-gitter).
-->
## What is the motivation / use case for changing the behavior?
<!-- Describe the motivation or the concrete use case. -->
## Environment
<pre><code>
Angular version: X.Y.Z
<!-- Check whether this is still an issue in the most recent Angular version -->
Browser:
- [ ] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
For Tooling issues:
- Node version: XX <!-- run `node --version` -->
- Platform: <!-- Mac, Linux, Windows -->
Others:
<!-- Anything else relevant? Operating system version, IDE, package manager, HTTP server, ... -->
</code></pre>
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑

67
.github/ISSUE_TEMPLATE/1-bug-report.md vendored Normal file
View File

@ -0,0 +1,67 @@
---
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-issue-repro2
-->
<!-- ✍️--> 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. 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. -->

View File

@ -0,0 +1,32 @@
---
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 Normal file
View File

@ -0,0 +1,55 @@
---
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. -->

View File

@ -0,0 +1,11 @@
---
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.
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑

View File

@ -0,0 +1,16 @@
---
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 Normal file
View File

@ -0,0 +1,13 @@
---
name: "\U0001F6E0Angular 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.
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑

View File

@ -0,0 +1,13 @@
---
name: "\U0001F48EAngular Material"
about: Issues and feature requests for Angular Material
---
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
Please file any Angular Material issues at: https://github.com/angular/material2/issues/new
For the time being, we keep Angular Material issues in a separate repository.
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑

View File

@ -4,7 +4,7 @@
size:
disabled: false
maxSizeIncrease: 2000
circleCiStatusName: "ci/circleci: test"
circleCiStatusName: "ci/circleci: test_ivy_aot"
# options for the merge plugin
merge:
@ -39,14 +39,28 @@ merge:
- "packages/**"
# list of patterns to ignore for the files changed by the PR
exclude:
- "packages/*"
- "packages/bazel/*"
- "packages/bazel/src/builders/**"
- "packages/bazel/src/ng_package/**"
- "packages/bazel/src/protractor/**"
- "packages/bazel/src/schematics/**"
- "packages/compiler-cli/src/ngcc/**"
- "packages/docs/**"
- "packages/elements/schematics/**"
- "packages/examples/**"
- "packages/language-service/**"
- "packages/private/**"
- "packages/service-worker/**"
- "**/.gitignore"
- "**/.gitkeep"
- "**/yarn.lock"
- "**/package.json"
- "**/tsconfig-build.json"
- "**/tsconfig.json"
- "**/rollup.config.js"
- "**/BUILD.bazel"
- "**/*.md"
- "packages/**/integrationtest/**"
- "packages/**/test/**"
@ -57,6 +71,10 @@ merge:
# label to monitor
mergeLabel: "PR action: merge"
# adding any of these labels will also add the merge label
mergeLinkedLabels:
- "PR action: merge-assistance"
# list of checks that will determine if the merge label can be added
checks:

8
.gitignore vendored
View File

@ -1,7 +1,8 @@
.DS_STORE
/dist/
bazel-*
/bazel-*
/integration/bazel/bazel-*
e2e_test.*
node_modules
bower_components
@ -14,7 +15,6 @@ pubspec.lock
.settings/
*.swo
modules/.settings
.bazelrc
.vscode
modules/.vscode
@ -30,3 +30,7 @@ yarn-error.log
# rollup-test output
/modules/rollup-test/dist/
# User specific bazel settings
.bazelrc.user

View File

@ -87,10 +87,10 @@ groups:
files:
include:
- "WORKSPACE"
- ".bazel*"
- "*.bazel"
- "*.bzl"
- "packages/bazel/*"
- "tools/bazel.rc"
- "/docs/BAZEL.md"
users:
- alexeagle #primary
@ -98,6 +98,7 @@ groups:
- IgorMinar #fallback
- mhevery
- vikerman #fallback
- kara
build-and-ci:
conditions:
@ -108,9 +109,9 @@ groups:
- "*.lock"
- "tools/*"
exclude:
- "tools/bazel.rc"
- "tools/public_api_guard/*"
- "aio/*"
- "packages/core/test/bundling/*"
- "tools/public_api_guard/*"
users:
- IgorMinar #primary
- alexeagle
@ -211,6 +212,7 @@ groups:
- mhevery #fallback
- IgorMinar #fallback
- jenniferfell #docs only
- kara
compiler/i18n:
conditions:
@ -223,6 +225,7 @@ groups:
- IgorMinar #fallback
- mhevery #fallback
- jenniferfell #docs only
- kara
compiler:
conditions:
@ -234,6 +237,7 @@ groups:
- mhevery
- IgorMinar #fallback
- jenniferfell #docs only
- kara
compiler-cli/ngtools:
conditions:
@ -243,13 +247,13 @@ groups:
- hansl
- filipesilva #fallback
- IgorMinar #fallback
- kara
compiler-cli:
conditions:
files:
include:
- "packages/compiler-cli/*"
- "packages/bazel/*"
exclude:
- "packages/compiler-cli/src/ngtools*"
users:
@ -257,6 +261,7 @@ groups:
- alxhub
- IgorMinar #fallback
- mhevery #fallback
- kara
common:
conditions:
@ -269,6 +274,7 @@ groups:
- pkozlowski-opensource #primary
- IgorMinar #fallback
- mhevery #fallback
- kara
forms:
conditions:
@ -334,6 +340,7 @@ groups:
- IgorMinar #fallback
- mhevery #fallback
- jenniferfell #docs only
- kara
testing:
conditions:
@ -367,6 +374,7 @@ groups:
- IgorMinar #fallback
- mhevery #fallback
- jenniferfell #docs only
- kara
platform-browser:
conditions:
@ -376,6 +384,7 @@ groups:
- mhevery #primary
# needs secondary
- IgorMinar #fallback
- kara
platform-server:
conditions:
@ -398,6 +407,7 @@ groups:
- mhevery #primary
# needs secondary
- IgorMinar #fallback
- kara
service-worker:
conditions:
@ -431,6 +441,7 @@ groups:
- IgorMinar #fallback
- mhevery #fallback
- jenniferfell #docs only
- kara
benchpress:
conditions:

View File

@ -30,14 +30,6 @@ env:
# GITHUB_TOKEN_ANGULAR=<github token, a personal access token of the angular-builds account, account access in valentine>
# This is needed for the e2e Travis matrix task to publish packages to github for continuous packages delivery.
- secure: "aCdHveZuY8AT4Jr1JoJB4LxZsnGWRe/KseZh1YXYe5UtufFCtTVHvUcLn0j2aLBF0KpdyS+hWf0i4np9jthKu2xPKriefoPgCMpisYeC0MFkwbmv+XlgkUbgkgVZMGiVyX7DCYXVahxIoOUjVMEDCbNiHTIrfEuyq24U3ok2tHc="
# FIREBASE_TOKEN
# This is needed for publishing builds to the "aio-staging" and "angular-io" firebase projects.
# This token was generated using the aio-deploy@angular.io account using `firebase login:ci` and password from valentine
- secure: "L5CyQmpwWtoR4Qi4xlWQh/cL1M6ZeJL4W4QAr4HdKFMgYt9h+Whqkymyh2NxwmCbPvWa7yUd+OiLQUDCY7L2VIg16hTwoe2CgYDyQA0BEwLzxtRrJXl93TfwMlrUx5JSIzAccD6D4sjtz8kSFMomK2Nls33xOXOukwyhVMjd0Cg="
# ANGULAR_PAYLOAD_FIREBASE_TOKEN
# This is for payload size data to "angular-payload-size" firebase project
# This token was generated using the payload@angular.io account using `firebase login:ci` and password from valentine
- secure: "SxotP/ymNy6uWAVbfwM9BlwETPEBpkRvU/F7fCtQDDic99WfQHzzUSQqHTk8eKk3GrGAOSL09vT0WfStQYEIGEoS5UHWNgOnelxhw+d5EnaoB8vQ0dKQBTK092hQg4feFprr+B/tCasyMV6mVwpUzZMbIJNn/Rx7H5g1bp+Gkfg="
matrix:
# Order: a slower build first, so that we don't occupy an idle travis worker waiting for others to complete.
- CI_MODE=e2e
@ -45,18 +37,16 @@ env:
- CI_MODE=saucelabs_required
# deactivated, see #19768
# - CI_MODE=browserstack_required
- CI_MODE=saucelabs_optional
- CI_MODE=browserstack_optional
- CI_MODE=aio_tools_test
- CI_MODE=aio
- CI_MODE=aio_local
- CI_MODE=aio_e2e AIO_SHARD=0
- CI_MODE=aio_e2e AIO_SHARD=1
# We disable these optional jobs because those acquire tunnel and browser instances which
# could lead to rate limit excess while those are failing most of the time and nobody pays
# attention anyway.
# - CI_MODE=saucelabs_optional
# - CI_MODE=browserstack_optional
matrix:
fast_finish: true
allow_failures:
- env: "CI_MODE=aio_local"
- env: "CI_MODE=saucelabs_optional"
- env: "CI_MODE=browserstack_optional"
@ -70,8 +60,6 @@ install:
script:
- ./scripts/ci/build.sh
- ./scripts/ci/test.sh
# deploy is part of 'script' and not 'after_success' so that we fail the build if the deployment fails
- ./scripts/ci/deploy.sh
- ./scripts/ci/angular.sh
# all the scripts under this line will not quickly abort in case ${TRAVIS_TEST_RESULT} is 1 (job failure)
- ./scripts/ci/cleanup.sh

View File

@ -8,26 +8,14 @@ exports_files([
"protractor-perf.conf.js",
])
# Developers should always run `bazel run :install`
# This ensures that package.json in subdirectories get installed as well.
alias(
name = "install",
actual = "@nodejs//:yarn",
)
alias(
name = "node_modules",
actual = "@angular_deps//:node_modules",
)
filegroup(
name = "web_test_bootstrap_scripts",
# do not sort
srcs = [
"@angular_deps//:node_modules/reflect-metadata/Reflect.js",
"@angular_deps//:node_modules/zone.js/dist/zone.js",
"@angular_deps//:node_modules/zone.js/dist/zone-testing.js",
"@angular_deps//:node_modules/zone.js/dist/task-tracking.js",
"@ngdeps//node_modules/reflect-metadata:Reflect.js",
"@ngdeps//node_modules/zone.js:dist/zone.js",
"@ngdeps//node_modules/zone.js:dist/zone-testing.js",
"@ngdeps//node_modules/zone.js:dist/task-tracking.js",
"//:test-events.js",
],
)
@ -35,11 +23,34 @@ filegroup(
filegroup(
name = "angularjs_scripts",
srcs = [
"@angular_deps//:node_modules/angular-1.5/angular.js",
"@angular_deps//:node_modules/angular-1.6/angular.js",
"@angular_deps//:node_modules/angular-mocks-1.5/angular-mocks.js",
"@angular_deps//:node_modules/angular-mocks-1.6/angular-mocks.js",
"@angular_deps//:node_modules/angular-mocks/angular-mocks.js",
"@angular_deps//:node_modules/angular/angular.js",
# We also declare the unminfied AngularJS files since these can be used for
# local debugging (e.g. see: packages/upgrade/test/common/test_helpers.ts)
"@ngdeps//node_modules/angular:angular.js",
"@ngdeps//node_modules/angular:angular.min.js",
"@ngdeps//node_modules/angular-1.5:angular.js",
"@ngdeps//node_modules/angular-1.5:angular.min.js",
"@ngdeps//node_modules/angular-1.6:angular.js",
"@ngdeps//node_modules/angular-1.6:angular.min.js",
"@ngdeps//node_modules/angular-mocks:angular-mocks.js",
"@ngdeps//node_modules/angular-mocks-1.5:angular-mocks.js",
"@ngdeps//node_modules/angular-mocks-1.6:angular-mocks.js",
],
)
load("@build_bazel_rules_nodejs//:defs.bzl", "nodejs_binary")
# A nodejs_binary for @angular/bazel/ngc-wrapped to use by default in
# ng_module that depends on @npm//@angular/bazel instead of the
# output of the //packages/bazel/src/ngc-wrapped ts_library rule. This
# default is for downstream users that depend on the @angular/bazel npm
# package. The generated @npm//@angular/bazel/ngc-wrapped target
# does not work because it does not have the node `--expose-gc` flag
# set which is required to support the call to `global.gc()`.
nodejs_binary(
name = "@angular/bazel/ngc-wrapped",
configuration_env_vars = ["compile"],
data = ["@npm//@angular/bazel"],
entry_point = "@angular/bazel/src/ngc-wrapped/index.js",
install_source_map_support = False,
templated_args = ["--node_options=--expose-gc"],
)

View File

@ -1,3 +1,300 @@
<a name="7.2.0-rc.0"></a>
# [7.2.0-rc.0](https://github.com/angular/angular/compare/7.2.0-beta.2...7.2.0-rc.0) (2018-12-18)
### Bug Fixes
* **animations:** do not truncate decimals for delay ([#24455](https://github.com/angular/angular/issues/24455)) ([f1c9d6a](https://github.com/angular/angular/commit/f1c9d6a))
* **animations:** mark actual descendant node as disabled ([#26180](https://github.com/angular/angular/issues/26180)) ([df123e0](https://github.com/angular/angular/commit/df123e0))
* **bazel:** devserver entry_module should have underscore name ([#27719](https://github.com/angular/angular/issues/27719)) ([f57916c](https://github.com/angular/angular/commit/f57916c))
* **bazel:** emit full node stack traces when Angular compilation crashes ([#27678](https://github.com/angular/angular/issues/27678)) ([522919a](https://github.com/angular/angular/commit/522919a))
* **bazel:** fix major/minor semver check between [@angular](https://github.com/angular)/bazel npm packager version and angular bazel repo version ([#27635](https://github.com/angular/angular/issues/27635)) ([1cc08b4](https://github.com/angular/angular/commit/1cc08b4))
* **bazel:** Load http_archive and rules_nodejs dependencies ([#27609](https://github.com/angular/angular/issues/27609)) ([8313ffc](https://github.com/angular/angular/commit/8313ffc))
* **bazel:** ng_package writes unrelevant definitions to bazel out ([#27519](https://github.com/angular/angular/issues/27519)) ([44dfa60](https://github.com/angular/angular/commit/44dfa60)), closes [/github.com/angular/angular/blob/4f9374951d67c75f67a31c110bd61ab72563db7d/packages/bazel/src/ng_package/packager.ts#L105-L124](https://github.com//github.com/angular/angular/blob/4f9374951d67c75f67a31c110bd61ab72563db7d/packages/bazel/src/ng_package/packager.ts/issues/L105-L124)
* **bazel:** Set module_name and enable ng test ([#27715](https://github.com/angular/angular/issues/27715)) ([85866de](https://github.com/angular/angular/commit/85866de))
* **common:** KeyValuePipe should return empty array for empty objects ([#27258](https://github.com/angular/angular/issues/27258)) ([b39efdd](https://github.com/angular/angular/commit/b39efdd))
* **compiler-cli:** create LiteralLikeNode for String and Number literal ([#27536](https://github.com/angular/angular/issues/27536)) ([2c9b6c0](https://github.com/angular/angular/commit/2c9b6c0))
* **router:** ensure URL is updated after second redirect with UrlUpdateStrategy="eager" ([#27523](https://github.com/angular/angular/issues/27523)) ([ad26cd6](https://github.com/angular/angular/commit/ad26cd6)), closes [#27116](https://github.com/angular/angular/issues/27116)
* **upgrade:** upgrade Directive facade should not return different instance from constructor ([#27660](https://github.com/angular/angular/issues/27660)) ([c986d3d](https://github.com/angular/angular/commit/c986d3d))
### Features
* add support for typescript 3.2 ([#27536](https://github.com/angular/angular/issues/27536)) ([17e702b](https://github.com/angular/angular/commit/17e702b))
* **router:** add predicate function mode for runGuardsAndResolvers ([#27682](https://github.com/angular/angular/issues/27682)) ([12c3176](https://github.com/angular/angular/commit/12c3176)), closes [#26861](https://github.com/angular/angular/issues/26861) [#18253](https://github.com/angular/angular/issues/18253) [#27464](https://github.com/angular/angular/issues/27464)
<a name="7.1.4"></a>
## [7.1.4](https://github.com/angular/angular/compare/7.1.3...7.1.4) (2018-12-18)
### Bug Fixes
* **animations:** do not truncate decimals for delay ([#24455](https://github.com/angular/angular/issues/24455)) ([cd1e206](https://github.com/angular/angular/commit/cd1e206))
* **animations:** mark actual descendant node as disabled ([#26180](https://github.com/angular/angular/issues/26180)) ([453589f](https://github.com/angular/angular/commit/453589f))
* **bazel:** devserver entry_module should have underscore name ([#27719](https://github.com/angular/angular/issues/27719)) ([b108e9a](https://github.com/angular/angular/commit/b108e9a))
* **bazel:** emit full node stack traces when Angular compilation crashes ([#27678](https://github.com/angular/angular/issues/27678)) ([0d8528b](https://github.com/angular/angular/commit/0d8528b))
* **bazel:** fix major/minor semver check between [@angular](https://github.com/angular)/bazel npm packager version and angular bazel repo version ([#27635](https://github.com/angular/angular/issues/27635)) ([3ed1e84](https://github.com/angular/angular/commit/3ed1e84))
* **bazel:** Load http_archive and rules_nodejs dependencies ([#27609](https://github.com/angular/angular/issues/27609)) ([89ace1a](https://github.com/angular/angular/commit/89ace1a))
* **bazel:** ng_package writes unrelevant definitions to bazel out ([#27519](https://github.com/angular/angular/issues/27519)) ([ef056c5](https://github.com/angular/angular/commit/ef056c5)), closes [/github.com/angular/angular/blob/4f9374951d67c75f67a31c110bd61ab72563db7d/packages/bazel/src/ng_package/packager.ts#L105-L124](https://github.com//github.com/angular/angular/blob/4f9374951d67c75f67a31c110bd61ab72563db7d/packages/bazel/src/ng_package/packager.ts/issues/L105-L124)
* **bazel:** Read latest versions from latest-versions.ts & use semver check ([#27591](https://github.com/angular/angular/issues/27591)) ([93078e3](https://github.com/angular/angular/commit/93078e3))
* **bazel:** Set module_name and enable ng test ([#27715](https://github.com/angular/angular/issues/27715)) ([183f278](https://github.com/angular/angular/commit/183f278))
* **common:** KeyValuePipe should return empty array for empty objects ([#27258](https://github.com/angular/angular/issues/27258)) ([fa3af8b](https://github.com/angular/angular/commit/fa3af8b))
<a name="7.2.0-beta.2"></a>
# [7.2.0-beta.2](https://github.com/angular/angular/compare/7.2.0-beta.1...7.2.0-beta.2) (2018-12-11)
### Bug Fixes
* **bazel:** fix TS errors in the `schematics/bazel-workspace` files ([#27600](https://github.com/angular/angular/issues/27600)) ([3290fc3](https://github.com/angular/angular/commit/3290fc3))
* **bazel:** Read latest versions from latest-versions.ts & use semver check ([#27526](https://github.com/angular/angular/issues/27526)) ([30a3b49](https://github.com/angular/angular/commit/30a3b49))
* **bazel:** tsickle dependency not working with typescript 3.1.x ([#27402](https://github.com/angular/angular/issues/27402)) ([f034114](https://github.com/angular/angular/commit/f034114))
* **forms:** typed argument for FormBuilder group ([#26985](https://github.com/angular/angular/issues/26985)) ([b0c7561](https://github.com/angular/angular/commit/b0c7561))
<a name="7.1.3"></a>
## [7.1.3](https://github.com/angular/angular/compare/7.1.2...7.1.3) (2018-12-11)
### Bug Fixes
* **bazel:** tsickle dependency not working with typescript 3.1.x ([#27402](https://github.com/angular/angular/issues/27402)) ([a9f39a4](https://github.com/angular/angular/commit/a9f39a4))
<a name="7.1.2"></a>
## [7.1.2](https://github.com/angular/angular/compare/7.1.1...7.1.2) (2018-12-06)
### Bug Fixes
* **bazel:** do not throw error when writing tsickle externs ([#27200](https://github.com/angular/angular/issues/27200)) ([079c4b3](https://github.com/angular/angular/commit/079c4b3))
* **bazel:** do not throw if ts compile action does not create esm5 outputs ([#27401](https://github.com/angular/angular/issues/27401)) ([9b4d959](https://github.com/angular/angular/commit/9b4d959))
* **bazel:** ng_package cannot be run multiple times without clean ([#27200](https://github.com/angular/angular/issues/27200)) ([1ca2923](https://github.com/angular/angular/commit/1ca2923))
* **bazel:** ng_package not generating UMD bundles on windows ([#27200](https://github.com/angular/angular/issues/27200)) ([e476c38](https://github.com/angular/angular/commit/e476c38))
* **bazel:** ng_package should correctly map to source maps in secondary entry-points ([#27313](https://github.com/angular/angular/issues/27313)) ([fc2c23e](https://github.com/angular/angular/commit/fc2c23e)), closes [#25510](https://github.com/angular/angular/issues/25510)
* **compiler-cli:** flatModuleIndex files not generated on windows with multiple input files ([#27200](https://github.com/angular/angular/issues/27200)) ([8087b6b](https://github.com/angular/angular/commit/8087b6b))
* **compiler-cli:** ngtsc shim files not being generated on case-insensitive platforms ([#27466](https://github.com/angular/angular/issues/27466)) ([84f2928](https://github.com/angular/angular/commit/84f2928)), closes [/github.com/Microsoft/TypeScript/blob/3e4c5c95abd515eb9713b881d27ab3a93cc00461/src/compiler/sys.ts#L681-L682](https://github.com//github.com/Microsoft/TypeScript/blob/3e4c5c95abd515eb9713b881d27ab3a93cc00461/src/compiler/sys.ts/issues/L681-L682)
* **platform-server:** add [@angular](https://github.com/angular)/http to the list of peerDependencies ([#27307](https://github.com/angular/angular/issues/27307)) ([236ac06](https://github.com/angular/angular/commit/236ac06)), closes [#26154](https://github.com/angular/angular/issues/26154)
<a name="7.2.0-beta.1"></a>
# [7.2.0-beta.1](https://github.com/angular/angular/compare/7.1.0...7.2.0-beta.1) (2018-12-06)
### Bug Fixes
* **bazel:** do not throw error when writing tsickle externs ([#27200](https://github.com/angular/angular/issues/27200)) ([20a2bae](https://github.com/angular/angular/commit/20a2bae))
* **bazel:** do not throw if ts compile action does not create esm5 outputs ([#27401](https://github.com/angular/angular/issues/27401)) ([c61a8b7](https://github.com/angular/angular/commit/c61a8b7))
* **bazel:** ng_package cannot be run multiple times without clean ([#27200](https://github.com/angular/angular/issues/27200)) ([4f93749](https://github.com/angular/angular/commit/4f93749))
* **bazel:** ng_package not generating UMD bundles on windows ([#27200](https://github.com/angular/angular/issues/27200)) ([7d59880](https://github.com/angular/angular/commit/7d59880))
* **bazel:** ng_package should correctly map to source maps in secondary entry-points ([#27313](https://github.com/angular/angular/issues/27313)) ([eb17502](https://github.com/angular/angular/commit/eb17502)), closes [#25510](https://github.com/angular/angular/issues/25510)
* **bazel:** Respect existing angular installation ([#27495](https://github.com/angular/angular/issues/27495)) ([4da739a](https://github.com/angular/angular/commit/4da739a))
* **common:** expose request url in network error ([#27143](https://github.com/angular/angular/issues/27143)) ([1db53da](https://github.com/angular/angular/commit/1db53da)), closes [#27029](https://github.com/angular/angular/issues/27029)
* **compiler-cli:** flatModuleIndex files not generated on windows with multiple input files ([#27200](https://github.com/angular/angular/issues/27200)) ([d3c08e7](https://github.com/angular/angular/commit/d3c08e7))
* **core:** export a value for InjectFlags ([#27279](https://github.com/angular/angular/issues/27279)) ([23b06af](https://github.com/angular/angular/commit/23b06af)), closes [#27251](https://github.com/angular/angular/issues/27251)
* **core:** More precise return type for `InjectableDecorator` ([#27360](https://github.com/angular/angular/issues/27360)) ([4b9948c](https://github.com/angular/angular/commit/4b9948c)), closes [#26942](https://github.com/angular/angular/issues/26942)
* **forms:** apply unicode flag to pattern attribute when supported ([#20819](https://github.com/angular/angular/issues/20819)) ([3c34b8b](https://github.com/angular/angular/commit/3c34b8b))
* **platform-server:** add [@angular](https://github.com/angular)/http to the list of peerDependencies ([#27307](https://github.com/angular/angular/issues/27307)) ([32c5be9](https://github.com/angular/angular/commit/32c5be9)), closes [#26154](https://github.com/angular/angular/issues/26154)
* **router:** update URL after redirects when urlHandlingStrategy='eager' ([#27356](https://github.com/angular/angular/issues/27356)) ([11a8bd8](https://github.com/angular/angular/commit/11a8bd8)), closes [#27076](https://github.com/angular/angular/issues/27076)
* **upgrade:** don't rely upon the runtime to resolve forward refs ([#27132](https://github.com/angular/angular/issues/27132)) ([a4462c2](https://github.com/angular/angular/commit/a4462c2))
### Features
* **bazel:** ng-new schematics with Bazel ([#27277](https://github.com/angular/angular/issues/27277)) ([06d4a0c](https://github.com/angular/angular/commit/06d4a0c))
* **router:** add a Navigation type available during navigation ([#27198](https://github.com/angular/angular/issues/27198)) ([d40af0c](https://github.com/angular/angular/commit/d40af0c))
* **router:** add pathParamsOrQueryParamsChange mode for runGuardsAndResolvers ([#27464](https://github.com/angular/angular/issues/27464)) ([d70a7f3](https://github.com/angular/angular/commit/d70a7f3)), closes [#26861](https://github.com/angular/angular/issues/26861) [#18253](https://github.com/angular/angular/issues/18253)
* **router:** allow passing `state` to routerLink directives ([#27198](https://github.com/angular/angular/issues/27198)) ([73f6ed9](https://github.com/angular/angular/commit/73f6ed9)), closes [#24617](https://github.com/angular/angular/issues/24617)
* **router:** allow passing state to `NavigationExtras` ([#27198](https://github.com/angular/angular/issues/27198)) ([67f4a5d](https://github.com/angular/angular/commit/67f4a5d))
* **router:** restore whole object when navigating back to a page managed by Angular router ([#27198](https://github.com/angular/angular/issues/27198)) ([2684249](https://github.com/angular/angular/commit/2684249))
<a name="7.2.0-beta.0"></a>
# [7.2.0-beta.0](https://github.com/angular/angular/compare/7.1.0...7.2.0-beta.0) (2018-11-28)
### Bug Fixes
* **common:** expose request url in network error ([#27143](https://github.com/angular/angular/issues/27143)) ([1db53da](https://github.com/angular/angular/commit/1db53da)), closes [#27029](https://github.com/angular/angular/issues/27029)
* **upgrade:** don't rely upon the runtime to resolve forward refs ([#27132](https://github.com/angular/angular/issues/27132)) ([a4462c2](https://github.com/angular/angular/commit/a4462c2))
<a name="7.1.1"></a>
## [7.1.1](https://github.com/angular/angular/compare/7.1.0...7.1.1) (2018-11-28)
### Bug Fixes
* **core:** export a value for InjectFlags ([#27279](https://github.com/angular/angular/issues/27279)) ([bdf5f3e](https://github.com/angular/angular/commit/bdf5f3e)), closes [#27251](https://github.com/angular/angular/issues/27251)
<a name="7.1.0"></a>
# [7.1.0](https://github.com/angular/angular/compare/7.1.0-rc.0...7.1.0) (2018-11-21)
### Bug Fixes
* **core:** allow null value for renderer setElement(…) ([#17065](https://github.com/angular/angular/issues/17065)) ([ff15043](https://github.com/angular/angular/commit/ff15043)), closes [#13686](https://github.com/angular/angular/issues/13686)
* **router:** fix regression where navigateByUrl promise didn't resolve on CanLoad failure ([#26455](https://github.com/angular/angular/issues/26455)) ([1c9b065](https://github.com/angular/angular/commit/1c9b065)), closes [#26284](https://github.com/angular/angular/issues/26284)
* **service-worker:** clean up caches from old SW versions ([#26319](https://github.com/angular/angular/issues/26319)) ([2326b9c](https://github.com/angular/angular/commit/2326b9c))
* **upgrade:** properly destroy upgraded component elements and descendants ([#26209](https://github.com/angular/angular/issues/26209)) ([071934e](https://github.com/angular/angular/commit/071934e)), closes [#26208](https://github.com/angular/angular/issues/26208)
* **compiler:** generate inputs with aliases properly ([#26774](https://github.com/angular/angular/issues/26774)) ([19fcfc3](https://github.com/angular/angular/commit/19fcfc3))
* **compiler:** generate relative paths only in summary file errors ([#26759](https://github.com/angular/angular/issues/26759)) ([56f44be](https://github.com/angular/angular/commit/56f44be))
* **core:** ignore comment nodes under unsafe elements ([#25879](https://github.com/angular/angular/issues/25879)) ([d5cbcef](https://github.com/angular/angular/commit/d5cbcef))
* **core:** Remove static dependency from [@angular](https://github.com/angular)/core to [@angular](https://github.com/angular)/compiler ([#26734](https://github.com/angular/angular/issues/26734)) ([d042c4a](https://github.com/angular/angular/commit/d042c4a))
* **core:** support computed base class in metadata inheritance ([#24014](https://github.com/angular/angular/issues/24014)) ([95743e3](https://github.com/angular/angular/commit/95743e3))
* **bazel:** unknown replay compiler error in windows ([#26711](https://github.com/angular/angular/issues/26711)) ([aed95fd](https://github.com/angular/angular/commit/aed95fd))
* **core:** ensure that `ɵdefineNgModule` is available in flat-file formats ([#26403](https://github.com/angular/angular/issues/26403)) ([a64859b](https://github.com/angular/angular/commit/a64859b))
* **router:** remove type bludgeoning of context and outlet when running CanDeactivate ([#26496](https://github.com/angular/angular/issues/26496)) ([496372d](https://github.com/angular/angular/commit/496372d)), closes [#18253](https://github.com/angular/angular/issues/18253)
* **service-worker:** add typing to public api guard and fix lint errors ([#25860](https://github.com/angular/angular/issues/25860)) ([1061875](https://github.com/angular/angular/commit/1061875))
* **upgrade:** improve downgrading-related error messages ([#26217](https://github.com/angular/angular/issues/26217)) ([7dbc103](https://github.com/angular/angular/commit/7dbc103))
* **upgrade:** make typings compatible with older AngularJS typings ([#26880](https://github.com/angular/angular/issues/26880)) ([64647af](https://github.com/angular/angular/commit/64647af)), closes [#26420](https://github.com/angular/angular/issues/26420)
* **compiler-cli:** add missing tslib dependency ([#27063](https://github.com/angular/angular/issues/27063)) ([c31e78f](https://github.com/angular/angular/commit/c31e78f))
* **compiler-cli:** only pass canonical genfile paths to compiler host ([#27062](https://github.com/angular/angular/issues/27062)) ([0ada23a](https://github.com/angular/angular/commit/0ada23a))
* **router:** add `relativeLinkResolution` to `recognize` operator ([#26990](https://github.com/angular/angular/issues/26990)) ([a752971](https://github.com/angular/angular/commit/a752971)), closes [#26983](https://github.com/angular/angular/issues/26983)
### Features
* **bazel:** Bazel workspace schematics ([#26971](https://github.com/angular/angular/issues/26971)) ([b07bd30](https://github.com/angular/angular/commit/b07bd30))
* **router:** add prioritizedGuardValue operator optimization and allowing UrlTree return from guard ([#26478](https://github.com/angular/angular/issues/26478)) ([fdfedce](https://github.com/angular/angular/commit/fdfedce))
* **compiler:** ability to mark an InvokeFunctionExpr as pure ([#26860](https://github.com/angular/angular/issues/26860)) ([4dfa71f](https://github.com/angular/angular/commit/4dfa71f))
* **forms:** add updateOn option to FormBuilder ([#24599](https://github.com/angular/angular/issues/24599)) ([e9e804f](https://github.com/angular/angular/commit/e9e804f))
* **router:** allow guards to return UrlTree as well as boolean ([#26521](https://github.com/angular/angular/issues/26521)) ([081f95c](https://github.com/angular/angular/commit/081f95c))
* **router:** allow redirect from guards by returning UrlTree ([#26521](https://github.com/angular/angular/issues/26521)) ([152ca66](https://github.com/angular/angular/commit/152ca66))
* **router:** guard returning UrlTree cancels current navigation and redirects ([#26521](https://github.com/angular/angular/issues/26521)) ([4e9f2e5](https://github.com/angular/angular/commit/4e9f2e5)), closes [#24618](https://github.com/angular/angular/issues/24618)
* **service-worker:** add typing for messagesClicked in SwPush service ([#25860](https://github.com/angular/angular/issues/25860)) ([c78c221](https://github.com/angular/angular/commit/c78c221))
* **service-worker:** close notifications and focus window on click ([#25860](https://github.com/angular/angular/issues/25860)) ([f5d5a3d](https://github.com/angular/angular/commit/f5d5a3d))
* **service-worker:** handle 'notificationclick' events ([#25860](https://github.com/angular/angular/issues/25860)) ([cf6ea28](https://github.com/angular/angular/commit/cf6ea28)), closes [#20956](https://github.com/angular/angular/issues/20956) [#22311](https://github.com/angular/angular/issues/22311)
* **upgrade:** support downgrading multiple modules ([#26217](https://github.com/angular/angular/issues/26217)) ([93837e9](https://github.com/angular/angular/commit/93837e9)), closes [#26062](https://github.com/angular/angular/issues/26062)
* **router:** add pathParamsChange mode for runGuardsAndResolvers ([#26861](https://github.com/angular/angular/issues/26861)) ([bf6ac6c](https://github.com/angular/angular/commit/bf6ac6c)), closes [#18253](https://github.com/angular/angular/issues/18253)
<a name="7.1.0-rc.0"></a>
# [7.1.0-rc.0](https://github.com/angular/angular/compare/7.1.0-beta.2...7.1.0-rc.0) (2018-11-14)
### Bug Fixes
* **compiler-cli:** add missing tslib dependency ([#27063](https://github.com/angular/angular/issues/27063)) ([c31e78f](https://github.com/angular/angular/commit/c31e78f))
* **compiler-cli:** only pass canonical genfile paths to compiler host ([#27062](https://github.com/angular/angular/issues/27062)) ([0ada23a](https://github.com/angular/angular/commit/0ada23a))
* **router:** add `relativeLinkResolution` to `recognize` operator ([#26990](https://github.com/angular/angular/issues/26990)) ([a752971](https://github.com/angular/angular/commit/a752971)), closes [#26983](https://github.com/angular/angular/issues/26983)
### Features
* **router:** add pathParamsChange mode for runGuardsAndResolvers ([#26861](https://github.com/angular/angular/issues/26861)) ([bf6ac6c](https://github.com/angular/angular/commit/bf6ac6c)), closes [#18253](https://github.com/angular/angular/issues/18253)
<a name="7.0.4"></a>
## [7.0.4](https://github.com/angular/angular/compare/7.0.3...7.0.4) (2018-11-14)
### Bug Fixes
* **compiler-cli:** add missing tslib dependency ([#27063](https://github.com/angular/angular/issues/27063)) ([4348c47](https://github.com/angular/angular/commit/4348c47))
* **compiler-cli:** only pass canonical genfile paths to compiler host ([#27062](https://github.com/angular/angular/issues/27062)) ([188e9ce](https://github.com/angular/angular/commit/188e9ce))
* **router:** add `relativeLinkResolution` to `recognize` operator ([#26990](https://github.com/angular/angular/issues/26990)) ([d304427](https://github.com/angular/angular/commit/d304427)), closes [#26983](https://github.com/angular/angular/issues/26983)
<a name="7.1.0-beta.2"></a>
# [7.1.0-beta.2](https://github.com/angular/angular/compare/7.1.0-beta.1...7.1.0-beta.2) (2018-11-07)
### Bug Fixes
* **bazel:** unknown replay compiler error in windows ([#26711](https://github.com/angular/angular/issues/26711)) ([aed95fd](https://github.com/angular/angular/commit/aed95fd))
* **core:** ensure that `ɵdefineNgModule` is available in flat-file formats ([#26403](https://github.com/angular/angular/issues/26403)) ([a64859b](https://github.com/angular/angular/commit/a64859b))
* **router:** remove type bludgeoning of context and outlet when running CanDeactivate ([#26496](https://github.com/angular/angular/issues/26496)) ([496372d](https://github.com/angular/angular/commit/496372d)), closes [#18253](https://github.com/angular/angular/issues/18253)
* **service-worker:** add typing to public api guard and fix lint errors ([#25860](https://github.com/angular/angular/issues/25860)) ([1061875](https://github.com/angular/angular/commit/1061875))
* **upgrade:** improve downgrading-related error messages ([#26217](https://github.com/angular/angular/issues/26217)) ([7dbc103](https://github.com/angular/angular/commit/7dbc103))
* **upgrade:** make typings compatible with older AngularJS typings ([#26880](https://github.com/angular/angular/issues/26880)) ([64647af](https://github.com/angular/angular/commit/64647af)), closes [#26420](https://github.com/angular/angular/issues/26420)
### Features
* **compiler:** ability to mark an InvokeFunctionExpr as pure ([#26860](https://github.com/angular/angular/issues/26860)) ([4dfa71f](https://github.com/angular/angular/commit/4dfa71f))
* **forms:** add updateOn option to FormBuilder ([#24599](https://github.com/angular/angular/issues/24599)) ([e9e804f](https://github.com/angular/angular/commit/e9e804f))
* **router:** allow guards to return UrlTree as well as boolean ([#26521](https://github.com/angular/angular/issues/26521)) ([081f95c](https://github.com/angular/angular/commit/081f95c))
* **router:** allow redirect from guards by returning UrlTree ([#26521](https://github.com/angular/angular/issues/26521)) ([152ca66](https://github.com/angular/angular/commit/152ca66))
* **router:** guard returning UrlTree cancels current navigation and redirects ([#26521](https://github.com/angular/angular/issues/26521)) ([4e9f2e5](https://github.com/angular/angular/commit/4e9f2e5)), closes [#24618](https://github.com/angular/angular/issues/24618)
* **service-worker:** add typing for messagesClicked in SwPush service ([#25860](https://github.com/angular/angular/issues/25860)) ([c78c221](https://github.com/angular/angular/commit/c78c221))
* **service-worker:** close notifications and focus window on click ([#25860](https://github.com/angular/angular/issues/25860)) ([f5d5a3d](https://github.com/angular/angular/commit/f5d5a3d))
* **service-worker:** handle 'notificationclick' events ([#25860](https://github.com/angular/angular/issues/25860)) ([cf6ea28](https://github.com/angular/angular/commit/cf6ea28)), closes [#20956](https://github.com/angular/angular/issues/20956) [#22311](https://github.com/angular/angular/issues/22311)
* **upgrade:** support downgrading multiple modules ([#26217](https://github.com/angular/angular/issues/26217)) ([93837e9](https://github.com/angular/angular/commit/93837e9)), closes [#26062](https://github.com/angular/angular/issues/26062)
<a name="7.0.3"></a>
## [7.0.3](https://github.com/angular/angular/compare/7.0.2...7.0.3) (2018-11-07)
### Bug Fixes
* **bazel:** unknown replay compiler error in windows ([#26711](https://github.com/angular/angular/issues/26711)) ([4d532df](https://github.com/angular/angular/commit/4d532df))
* **router:** remove type bludgeoning of context and outlet when running CanDeactivate ([#26496](https://github.com/angular/angular/issues/26496)) ([dc05385](https://github.com/angular/angular/commit/dc05385)), closes [#18253](https://github.com/angular/angular/issues/18253)
* **upgrade:** make typings compatible with older AngularJS typings ([#26880](https://github.com/angular/angular/issues/26880)) ([315d95c](https://github.com/angular/angular/commit/315d95c)), closes [#26420](https://github.com/angular/angular/issues/26420)
<a name="7.1.0-beta.1"></a>
# [7.1.0-beta.1](https://github.com/angular/angular/compare/7.1.0-beta.0...7.1.0-beta.1) (2018-10-31)
### Bug Fixes
* **compiler:** generate inputs with aliases properly ([#26774](https://github.com/angular/angular/issues/26774)) ([19fcfc3](https://github.com/angular/angular/commit/19fcfc3))
* **compiler:** generate relative paths only in summary file errors ([#26759](https://github.com/angular/angular/issues/26759)) ([56f44be](https://github.com/angular/angular/commit/56f44be))
* **core:** ignore comment nodes under unsafe elements ([#25879](https://github.com/angular/angular/issues/25879)) ([d5cbcef](https://github.com/angular/angular/commit/d5cbcef))
* **core:** Remove static dependency from [@angular](https://github.com/angular)/core to [@angular](https://github.com/angular)/compiler ([#26734](https://github.com/angular/angular/issues/26734)) ([d042c4a](https://github.com/angular/angular/commit/d042c4a))
* **core:** support computed base class in metadata inheritance ([#24014](https://github.com/angular/angular/issues/24014)) ([95743e3](https://github.com/angular/angular/commit/95743e3))
<a name="7.0.2"></a>
## [7.0.2](https://github.com/angular/angular/compare/7.0.1...7.0.2) (2018-10-31)
### Bug Fixes
* **compiler:** generate relative paths only in summary file errors ([#26759](https://github.com/angular/angular/issues/26759)) ([c01f340](https://github.com/angular/angular/commit/c01f340))
* **core:** Remove static dependency from [@angular](https://github.com/angular)/core to [@angular](https://github.com/angular)/compiler ([#26734](https://github.com/angular/angular/issues/26734)) ([#26879](https://github.com/angular/angular/issues/26879)) ([257ac83](https://github.com/angular/angular/commit/257ac83))
* **core:** support computed base class in metadata inheritance ([#24014](https://github.com/angular/angular/issues/24014)) ([b3c6409](https://github.com/angular/angular/commit/b3c6409))
<a name="7.1.0-beta.0"></a>
# [7.1.0-beta.0](https://github.com/angular/angular/compare/7.0.0-rc.1...7.1.0-beta.0) (2018-10-24)
### Bug Fixes
* **core:** allow null value for renderer setElement(…) ([#17065](https://github.com/angular/angular/issues/17065)) ([ff15043](https://github.com/angular/angular/commit/ff15043)), closes [#13686](https://github.com/angular/angular/issues/13686)
* **router:** fix regression where navigateByUrl promise didn't resolve on CanLoad failure ([#26455](https://github.com/angular/angular/issues/26455)) ([1c9b065](https://github.com/angular/angular/commit/1c9b065)), closes [#26284](https://github.com/angular/angular/issues/26284)
* **service-worker:** clean up caches from old SW versions ([#26319](https://github.com/angular/angular/issues/26319)) ([2326b9c](https://github.com/angular/angular/commit/2326b9c))
* **upgrade:** properly destroy upgraded component elements and descendants ([#26209](https://github.com/angular/angular/issues/26209)) ([071934e](https://github.com/angular/angular/commit/071934e)), closes [#26208](https://github.com/angular/angular/issues/26208)
### Features
* **router:** add prioritizedGuardValue operator optimization and allowing UrlTree return from guard ([#26478](https://github.com/angular/angular/issues/26478)) ([fdfedce](https://github.com/angular/angular/commit/fdfedce))
<a name="7.0.1"></a>
## [7.0.1](https://github.com/angular/angular/compare/7.0.0...7.0.1) (2018-10-24)
<a name="7.0.0"></a>
# [7.0.0](https://github.com/angular/angular/compare/7.0.0-rc.1...7.0.0) (2018-10-18)

View File

@ -51,19 +51,15 @@ and help you to craft the change so that it is successfully accepted into the pr
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 will systematically ask you to provide a minimal reproduction scenario using http://plnkr.co. Having a live, reproducible scenario gives us a wealth of important information without going back & forth to you with additional questions like:
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 will systematically ask you to provide a minimal reproduction. Having a minimal reproducible scenario gives us a wealth of important information without going back & forth to you with additional questions.
- version of Angular used
- 3rd-party libraries and their versions
- and most importantly - a use-case that fails
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.
A minimal reproduce scenario using http://plnkr.co/ allows us to quickly confirm a bug (or point out coding problem) as well as confirm that we are fixing the right problem. If plunker is not a suitable way to demonstrate the problem (for example for issues related to our npm packaging), please create a standalone git repository demonstrating the problem.
We will be insisting on a minimal reproduce scenario in order to save maintainers time and ultimately be able to fix more bugs. Interestingly, from our experience users often find coding problems themselves while preparing a minimal plunk. We understand that sometimes it might be hard to extract essentials bits of code from a larger code-base but we really need to isolate the problem before we can fix it.
We will be insisting on a minimal reproduction scenario in order to save maintainers time and ultimately be able to fix more bugs. Interestingly, from our experience users often 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 code-base 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 filling out our [new issue form](https://github.com/angular/angular/issues/new).
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)

View File

@ -13,12 +13,10 @@ Angular is a development platform for building mobile and desktop web applicatio
[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

144
WORKSPACE
View File

@ -1,91 +1,52 @@
workspace(name = "angular")
#
# Download Bazel toolchain dependencies as needed by build actions
#
http_archive(
name = "build_bazel_rules_typescript",
sha256 = "1626ee2cc9770af6950bfc77dffa027f9aedf330fe2ea2ee7e504428927bd95d",
strip_prefix = "rules_typescript-0.17.0",
url = "https://github.com/bazelbuild/rules_typescript/archive/0.17.0.zip",
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load(
"//packages/bazel:package.bzl",
"rules_angular_dependencies",
"rules_angular_dev_dependencies",
)
http_archive(
name = "io_bazel_rules_go",
sha256 = "b7a62250a3a73277ade0ce306d22f122365b513f5402222403e507f2f997d421",
url = "https://github.com/bazelbuild/rules_go/releases/download/0.16.3/rules_go-0.16.3.tar.gz",
)
# Uncomment for local bazel rules development
#local_repository(
# name = "build_bazel_rules_nodejs",
# path = "../rules_nodejs",
#)
#local_repository(
# name = "build_bazel_rules_typescript",
# path = "../rules_typescript",
#)
# Angular Bazel users will call this function
rules_angular_dependencies()
# Install transitive deps of rules_nodejs
load("@build_bazel_rules_nodejs//:package.bzl", "rules_nodejs_dependencies")
rules_nodejs_dependencies()
# These are the dependencies only for us
rules_angular_dev_dependencies()
# Install transitive deps of rules_typescript
load("@build_bazel_rules_typescript//:package.bzl", "rules_typescript_dependencies")
rules_typescript_dependencies()
http_archive(
name = "bazel_toolchains",
sha256 = "c3b08805602cd1d2b67ebe96407c1e8c6ed3d4ce55236ae2efe2f1948f38168d",
strip_prefix = "bazel-toolchains-5124557861ebf4c0b67f98180bff1f8551e0b421",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/5124557861ebf4c0b67f98180bff1f8551e0b421.tar.gz",
"https://github.com/bazelbuild/bazel-toolchains/archive/5124557861ebf4c0b67f98180bff1f8551e0b421.tar.gz",
],
)
http_archive(
name = "io_bazel_rules_sass",
sha256 = "dbe9fb97d5a7833b2a733eebc78c9c1e3880f676ac8af16e58ccf2139cbcad03",
strip_prefix = "rules_sass-1.11.0",
url = "https://github.com/bazelbuild/rules_sass/archive/1.11.0.zip",
)
# This commit matches the version of buildifier in angular/ngcontainer
# If you change this, also check if it matches the version in the angular/ngcontainer
# version in /.circleci/config.yml
BAZEL_BUILDTOOLS_VERSION = "49a6c199e3fbf5d94534b2771868677d3f9c6de9"
http_archive(
name = "com_github_bazelbuild_buildtools",
sha256 = "edf39af5fc257521e4af4c40829fffe8fba6d0ebff9f4dd69a6f8f1223ae047b",
strip_prefix = "buildtools-%s" % BAZEL_BUILDTOOLS_VERSION,
url = "https://github.com/bazelbuild/buildtools/archive/%s.zip" % BAZEL_BUILDTOOLS_VERSION,
)
# Fetching the Bazel source code allows us to compile the Skylark linter
http_archive(
name = "io_bazel",
sha256 = "ace8cced3b21e64a8fdad68508e9b0644201ec848ad583651719841d567fc66d",
strip_prefix = "bazel-0.17.1",
url = "https://github.com/bazelbuild/bazel/archive/0.17.1.zip",
)
http_archive(
name = "io_bazel_skydoc",
sha256 = "7bfb5545f59792a2745f2523b9eef363f9c3e7274791c030885e7069f8116016",
strip_prefix = "skydoc-fe2e9f888d28e567fef62ec9d4a93c425526d701",
# TODO: switch to upstream when https://github.com/bazelbuild/skydoc/pull/103 is merged
url = "https://github.com/alexeagle/skydoc/archive/fe2e9f888d28e567fef62ec9d4a93c425526d701.zip",
)
# We have a source dependency on the Devkit repository, because it's built with
# Bazel.
# This allows us to edit sources and have the effect appear immediately without
# re-packaging or "npm link"ing.
# Even better, things like aspects will visit the entire graph including
# ts_library rules in the devkit repository.
http_archive(
name = "angular_cli",
sha256 = "8cf320ea58c321e103f39087376feea502f20eaf79c61a4fdb05c7286c8684fd",
strip_prefix = "angular-cli-6.1.0-rc.0",
url = "https://github.com/angular/angular-cli/archive/v6.1.0-rc.0.zip",
)
http_archive(
name = "org_brotli",
sha256 = "774b893a0700b0692a76e2e5b7e7610dbbe330ffbe3fe864b4b52ca718061d5a",
strip_prefix = "brotli-1.0.5",
url = "https://github.com/google/brotli/archive/v1.0.5.zip",
)
#
# Point Bazel to WORKSPACEs that live in subdirectories
#
local_repository(
http_archive(
name = "rxjs",
path = "node_modules/rxjs/src",
sha256 = "72b0b4e517f43358f554c125e40e39f67688cd2738a8998b4a266981ed32f403",
strip_prefix = "package/src",
url = "https://registry.yarnpkg.com/rxjs/-/rxjs-6.3.3.tgz",
)
# Point to the integration test workspace just so that Bazel doesn't descend into it
@ -98,12 +59,13 @@ local_repository(
#
# Load and install our dependencies downloaded above.
#
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories", "yarn_install")
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories")
check_bazel_version("0.17.0", """
If you are on a Mac and using Homebrew, there is a breaking change to the installation in Bazel 0.16
See https://blog.bazel.build/2018/08/22/bazel-homebrew.html
check_bazel_version("0.20.0", """
You no longer need to install Bazel on your machine.
Angular has a dependency on the @bazel/bazel package which supplies it.
Try running `yarn bazel` instead.
(If you did run that, check that you've got a fresh `yarn install`)
""")
@ -111,10 +73,15 @@ node_repositories(
node_version = "10.9.0",
package_json = ["//:package.json"],
preserve_symlinks = True,
yarn_version = "1.9.2",
yarn_version = "1.12.1",
)
load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains")
local_repository(
name = "npm",
path = "tools/npm_workspace",
)
load("@io_bazel_rules_go//go:def.bzl", "go_register_toolchains", "go_rules_dependencies")
go_rules_dependencies()
@ -147,14 +114,3 @@ sass_repositories()
load("@io_bazel_skydoc//skylark:skylark.bzl", "skydoc_repositories")
skydoc_repositories()
##################################
# Prevent Bazel from trying to build rxjs under angular devkit
local_repository(
name = "rxjs_ignore_nested_1",
path = "node_modules/@angular-devkit/core/node_modules/rxjs/src",
)
local_repository(
name = "rxjs_ignore_nested_2",
path = "node_modules/@angular-devkit/schematics/node_modules/rxjs/src",
)

3
aio/.gitignore vendored
View File

@ -44,6 +44,3 @@ protractor-results*.txt
# System Files
.DS_Store
Thumbs.db
# copied dependencies
src/assets/js/lunr*

View File

@ -41,8 +41,6 @@ Here are the most important tasks you might need to use:
- `yarn example-e2e --filter=foo` - limit e2e tests to those containing the word "foo"
- `yarn example-e2e --setup --local` - run e2e tests with the local version of Angular contained in the "dist" folder
* `yarn build-ie-polyfills` - generates a js file of polyfills that can be loaded in Internet Explorer.
## Developing on Windows
The `packages/` directory may contain Linux-specific symlinks, which are not recognized by Windows.
These unresolved links cause the docs generation process to fail because it cannot locate certain files.
@ -50,7 +48,7 @@ These unresolved links cause the docs generation process to fail because it cann
> Hint: The following steps require administration rights or [Windows Developer Mode](https://docs.microsoft.com/en-us/windows/uwp/get-started/enable-your-device-for-development) enabled!
To fix this problem, run `scripts/windows/create-symlinks.sh`. This command creates temporary files where the symlinks used to be. Make sure not to commit those files with your documentation changes.
When you are done making and testing your documentation changes, you can restore the original symlinks and delete the temporary files by running `scripts/windows/remove-symlinks.sh`.
When you are done making and testing your documentation changes, you can restore the original symlinks and delete the temporary files by running `scripts/windows/remove-symlinks.sh`.
It's necessary to remove the temporary files, because otherwise they're displayed as local changes in your git working copy and certain operations are blocked.

View File

@ -2,17 +2,17 @@
import * as bodyParser from 'body-parser';
import * as express from 'express';
import * as http from 'http';
import {AddressInfo} from 'net';
import {CircleCiApi} from '../common/circle-ci-api';
import {GithubApi} from '../common/github-api';
import {GithubPullRequests} from '../common/github-pull-requests';
import {GithubTeams} from '../common/github-teams';
import {assert, assertNotMissingOrEmpty, Logger} from '../common/utils';
import {BuildCreator} from './build-creator';
import {ChangedPrVisibilityEvent, CreatedBuildEvent} from './build-events';
import {BuildRetriever} from './build-retriever';
import {BuildVerifier} from './build-verifier';
import {respondWithError, throwRequestError} from './utils';
import { AddressInfo } from 'net';
import { CircleCiApi } from '../common/circle-ci-api';
import { GithubApi } from '../common/github-api';
import { GithubPullRequests } from '../common/github-pull-requests';
import { GithubTeams } from '../common/github-teams';
import { assert, assertNotMissingOrEmpty, computeShortSha, Logger } from '../common/utils';
import { BuildCreator } from './build-creator';
import { ChangedPrVisibilityEvent, CreatedBuildEvent } from './build-events';
import { BuildRetriever } from './build-retriever';
import { BuildVerifier } from './build-verifier';
import { respondWithError, throwRequestError } from './utils';
const AIO_PREVIEW_JOB = 'aio_preview';
@ -144,7 +144,10 @@ export class PreviewServerFactory {
const artifactPath = await buildRetriever.downloadBuildArtifact(buildNum, pr, sha, cfg.buildArtifactPath);
const isPublic = await buildVerifier.getPrIsTrusted(pr);
await buildCreator.create(pr, sha, artifactPath, isPublic);
res.sendStatus(isPublic ? 201 : 202);
logger.log(`PR:${pr}, SHA:${computeShortSha(sha)}, Build:${buildNum} - ` +
`Successfully created ${isPublic ? 'public' : 'non-public'} preview.`);
} catch (err) {
logger.error('CircleCI webhook error', err);
respondWithError(res, err);

View File

@ -46,7 +46,7 @@
"@types/shelljs": "^0.8.0",
"@types/supertest": "^2.0.5",
"nodemon": "^1.18.3",
"npm-run-all": "^4.1.3",
"npm-run-all": "^4.1.5",
"supertest": "^3.1.0",
"tslint": "^5.11.0",
"tslint-jasmine-noSkipOrFocus": "^1.0.9",

View File

@ -129,7 +129,7 @@ ansi-styles@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
ansi-styles@^3.2.0, ansi-styles@^3.2.1:
ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
dependencies:
@ -384,7 +384,7 @@ chalk@^1.1.3:
strip-ansi "^3.0.0"
supports-color "^2.0.0"
chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0:
chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e"
dependencies:
@ -532,9 +532,10 @@ cross-spawn@^5.0.1:
shebang-command "^1.2.0"
which "^1.2.9"
cross-spawn@^6.0.4:
cross-spawn@^6.0.5:
version "6.0.5"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
dependencies:
nice-try "^1.0.4"
path-key "^2.0.1"
@ -1630,16 +1631,17 @@ npm-packlist@^1.1.6:
ignore-walk "^3.0.1"
npm-bundled "^1.0.1"
npm-run-all@^4.1.3:
version "4.1.3"
resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.3.tgz#49f15b55a66bb4101664ce270cb18e7103f8f185"
npm-run-all@^4.1.5:
version "4.1.5"
resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba"
integrity sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==
dependencies:
ansi-styles "^3.2.0"
chalk "^2.1.0"
cross-spawn "^6.0.4"
ansi-styles "^3.2.1"
chalk "^2.4.1"
cross-spawn "^6.0.5"
memorystream "^0.3.1"
minimatch "^3.0.4"
ps-tree "^1.1.0"
pidtree "^0.3.0"
read-pkg "^3.0.0"
shell-quote "^1.6.1"
string.prototype.padend "^3.0.0"
@ -1786,6 +1788,11 @@ pause-stream@0.0.11:
dependencies:
through "~2.3"
pidtree@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.0.tgz#f6fada10fccc9f99bf50e90d0b23d72c9ebc2e6b"
integrity sha512-9CT4NFlDcosssyg8KVFltgokyKZIFjoBxw8CTGy+5F38Y1eQWrt8tRayiUOXE+zVKQnYu5BR8JjCtvK3BcnBhg==
pify@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"

View File

@ -3,7 +3,7 @@
TODO (gkalpak): Add docs. Mention:
- Testing on CI.
Relevant files: `scripts/ci/test-aio.sh`, `aio/aio-builds-setup/scripts/test.sh`
Relevant files: `aio/aio-builds-setup/scripts/test.sh`
- Deploying from CI.
Relevant files: `.circleci/config.yml`, `scripts/ci/deploy.sh`, `aio/scripts/build-artifacts.sh`,
`aio/scripts/deploy-to-firebase.sh`

View File

@ -2,7 +2,10 @@
"$schema": "./node_modules/@angular-devkit/core/src/workspace/workspace-schema.json",
"version": 1,
"cli": {
"packageManager": "yarn"
"packageManager": "yarn",
"warnings": {
"typescriptMismatch": false
}
},
"newProjectRoot": "projects",
"projects": {

View File

@ -23,7 +23,7 @@ Install the CLI using the `npm` package manager:
npm install -g @angular/cli
</code-example>
For details about changes between versions, and information about updating from previous releases,
For details about changes between versions, and information about updating from previous releases,
see the Releases tab on GitHub: https://github.com/angular/angular-cli/releases
有关版本变更的详情,以及如何从以前版本升级的信息,参见 GitHub 上的 Releases 页:<https://github.com/angular/angular-cli/releases>
@ -32,8 +32,8 @@ see the Releases tab on GitHub: https://github.com/angular/angular-cli/releases
## 基本工作流
Invoke the tool on the command line through the `ng` executable.
Online help is available on the command line.
Invoke the tool on the command line through the `ng` executable.
Online help is available on the command line.
Enter the following to list commands or options for a given command (such as [generate](cli/generate)) with a short description.
通过 `ng` 可执行文件可以在命令行上调用此工具。
@ -56,6 +56,7 @@ ng serve
</code-example>
In your browser, open http://localhost:4200/ to see the new app run.
When you use the [ng serve](cli/serve) command to build an app and serve it locally, the server automatically rebuilds the app and reloads the page when you change any of the source files.
在浏览器中,打开 <http://localhost:4200/> 查看运行效果。
@ -63,9 +64,9 @@ In your browser, open http://localhost:4200/ to see the new app run.
## 工作空间与项目文件
The [ng new](cli/new) command creates an *Angular workspace* folder and generates a new app skeleton.
The [ng new](cli/new) command creates an *Angular workspace* folder and generates a new app skeleton.
A workspace can contain multiple apps and libraries.
The initial app created by the [ng new](cli/new) command is at the top level of the workspace.
The initial app created by the [ng new](cli/new) command is at the top level of the workspace.
When you generate an additional app or library in a workspace, it goes into a `projects/` subfolder.
[ng new](cli/new) 命令会创建一个 *Angular 工作空间*目录,并生成一个新的应用骨架。
@ -73,45 +74,47 @@ When you generate an additional app or library in a workspace, it goes into a `p
由 [ng new](cli/new) 命令创建的初始应用位于工作空间的顶层。
你在工作区中生成的其它应用或库,会放在 `projects/` 子目录下。
A newly generated app contains the source files for a root module, with a root component and template.
A newly generated app contains the source files for a root module, with a root component and template.
Each app has a `src` folder that contains the logic, data, and assets.
新生成的应用中包含根模块的源码,还有根组件和模板。
每个应用都有一个 `src` 目录,其中包含逻辑、数据和静态文件。
You can edit the generated files directly, or add to and modify them using CLI commands.
Use the [ng generate](cli/generate) command to add new files for additional components and services, and code for new pipes, directives, and so on.
You can edit the generated files directly, or add to and modify them using CLI commands.
Use the [ng generate](cli/generate) command to add new files for additional components and services, and code for new pipes, directives, and so on.
Commands such as [add](cli/add) and [generate](cli/generate), which create or operate on apps and libraries, must be executed from within a workspace or project folder.
你可以直接编辑这些生成的文件,也可以使用 CLI 命令来添加或修改它们。
使用 [ng generate](cli/generate) 命令也可以添加其它组件和服务,以及管道、指令的源码等。
必须在工作空间或项目目录下才能执行 [add](cli/add) 或 [generate](cli/generate) 之类的命令,因为这些命令需要在应用或库上进行创建或其它操作。
When you use the [ng serve](cli/serve) command to build an app and serve it locally, the server automatically rebuilds the app and reloads the page when you change any of the source files.
当你使用 [ng serve](cli/serve) 命令构建应用,并在本地启动它时,服务器会自动重新构建应用,并在你修改了任何源码时都自动刷新页面。
* See more about the [Workspace file structure](guide/file-structure).
欲知详情,参见[工作空间的文件结构](guide/file-structure)。
### Workspace and project configuration
A single workspace configuration file, `angular.json`, is created at the top level of the workspace.
This is where you can set workspace-wide defaults, and specify configurations to use when the CLI builds a project for different targets.
### 工作空间与项目的配置
A single workspace configuration file, `angular.json`, is created at the top level of the workspace.
This is where you can set per-project defaults for CLI command options, and specify configurations to use when the CLI builds a project for different targets.
工作空间的配置文件 `angular.json` 位于此工作空间的顶层。
在这里,你可以设置全工作空间范围的默认值,并指定当 CLI 为不同目标构建项目时要用到的配置。
The [ng config](cli/config) command lets you set and retrieve configuration values from the command line, or you can edit the `angular.json` file directly.
Note that option names in the configuration file must use [camelCase](guide/glossary#case-types), while option names supplied to commands can use either camelCase or dash-case.
[ng config](cli/config) 让你可以从命令行中设置和获取配置项的值。你也可以直接编辑 `angular.json` 文件。
* See more about [Workspace Configuration](guide/workspace-config).
参见 [工作空间配置](guide/workspace-config)。
* See the [complete schema](https://github.com/angular/angular-cli/wiki/angular-workspace) for `angular.json`.
参见 `angular.json` 的[完整 schema](https://github.com/angular/angular-cli/wiki/angular-workspace)。
<!-- * Learn more about *configuration options for Angular(links to new guide or topics TBD)*. -->
## CLI command-language syntax
## CLI 命令语法
@ -126,22 +129,29 @@ Command syntax is shown as follows:
大多数命令以及少量选项,会有别名。别名会显示在每个命令的语法描述中。
* option names are prefixed with a double dash (--).
option aliases are prefixed with a single dash (-).
arguments are not prefixed.
for example: `ng build my-app -c production`
* Option names are prefixed with a double dash (--).
Option aliases are prefixed with a single dash (-).
Arguments are not prefixed.
For example:
<code-example format="." language="bash">
ng build my-app -c production
</code-example>
选项名带有双中线前缀(--)。
选项别名带有单中线前缀(-)。
参数没有前缀。
比如:`ng build my-app -c production`
* Typically, the name of a generated artifact can be given as an argument to the command or specified with the --name option.
比如:
<code-example format="." language="bash">
ng build my-app -c production
</code-example>
* Typically, the name of a generated artifact can be given as an argument to the command or specified with the --name option.
通常生成的工件artifact名称可以作为命令的参数进行指定也可以使用 --name 选项。
* Argument and option names can be given in either
[camelCase or dash-case](guide/glossary#case-types).
* Argument and option names can be given in either
[camelCase or dash-case](guide/glossary#case-types).
`--myOptionName` is equivalent to `--my-option-name`.
参数和选项的名称可以用[小驼峰或中线分隔的格式](guide/glossary#case-types)给出。
@ -151,7 +161,7 @@ Command syntax is shown as follows:
### 逻辑型与枚举型选项
Boolean options have two forms: `--thisOption` sets the flag, `--noThisOption` clears it.
Boolean options have two forms: `--thisOption` sets the flag, `--noThisOption` clears it.
If neither option is supplied, the flag remains in its default state, as listed in the reference documentation.
逻辑型选项有两种形式:`--thisOption` 可以设置标志,而 `--noThisOption` 可以清除标志。
@ -173,9 +183,9 @@ Options that specify files can be given as absolute paths, or as paths relative
### 原理图schematics
The [ng generate](cli/generate) and [ng add](cli/add) commands take as an argument the artifact or library to be generated or added to the current project.
In addition to any general options, each artifact or library defines its own options in a *schematic*.
Schematic options are supplied to the command in the same format as immediate command options.
The [ng generate](cli/generate) and [ng add](cli/add) commands take as an argument the artifact or library to be generated or added to the current project.
In addition to any general options, each artifact or library defines its own options in a *schematic*.
Schematic options are supplied to the command in the same format as immediate command options.
[ng generate](cli/generate) 和 [ng add](cli/add) 命令会把要生成或要添加到当前项目中的工件或库作为参数。
除了通用选项之外,每个工件或库还可以用*原理图*定义自己的选项。

View File

@ -1,6 +1,6 @@
'use strict'; // necessary for es6 output in node
import { browser } from 'protractor';
import { browser, ExpectedConditions as EC } from 'protractor';
import { logging } from 'selenium-webdriver';
import * as openClose from './open-close.po';
import * as statusSlider from './status-slider.po';
@ -25,6 +25,8 @@ describe('Animation Tests', () => {
});
describe('Open/Close Component', () => {
const closedHeight = '100px';
const openHeight = '200px';
beforeAll(async () => {
await openCloseHref.click();
@ -32,37 +34,37 @@ describe('Animation Tests', () => {
});
it('should be open', async () => {
let text = await openClose.getComponentText();
const toggleButton = openClose.getToggleButton();
const container = openClose.getComponentContainer();
let text = await container.getText();
if (text.includes('Closed')) {
await toggleButton.click();
sleepFor();
await browser.wait(async () => await container.getCssValue('height') === openHeight, 2000);
}
text = await openClose.getComponentText();
text = await container.getText();
const containerHeight = await container.getCssValue('height');
expect(text).toContain('The box is now Open!');
expect(containerHeight).toBe('200px');
expect(containerHeight).toBe(openHeight);
});
it('should be closed', async () => {
let text = await openClose.getComponentText();
const toggleButton = openClose.getToggleButton();
const container = openClose.getComponentContainer();
let text = await container.getText();
if (text.includes('Open')) {
await toggleButton.click();
sleepFor();
await browser.wait(async () => await container.getCssValue('height') === closedHeight, 2000);
}
text = await openClose.getComponentText();
text = await container.getText();
const containerHeight = await container.getCssValue('height');
expect(text).toContain('The box is now Closed!');
expect(containerHeight).toBe('100px');
expect(containerHeight).toBe(closedHeight);
});
it('should log animation events', async () => {
@ -72,8 +74,7 @@ describe('Animation Tests', () => {
await toggleButton.click();
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
const animationMessages = logs.filter(({ message }) => message.indexOf('Animation') !== -1 ? true : false);
const animationMessages = logs.filter(({ message }) => message.includes('Animation'));
expect(animationMessages.length).toBeGreaterThan(0);
});
@ -89,16 +90,16 @@ describe('Animation Tests', () => {
});
it('should be inactive with an orange background', async () => {
let text = await statusSlider.getComponentText();
const toggleButton = statusSlider.getToggleButton();
const container = statusSlider.getComponentContainer();
let text = await container.getText();
if (text === 'Active') {
await toggleButton.click();
sleepFor(2000);
await browser.wait(async () => await container.getCssValue('backgroundColor') === inactiveColor, 2000);
}
text = await statusSlider.getComponentText();
text = await container.getText();
const bgColor = await container.getCssValue('backgroundColor');
expect(text).toBe('Inactive');
@ -106,16 +107,16 @@ describe('Animation Tests', () => {
});
it('should be active with a blue background', async () => {
let text = await statusSlider.getComponentText();
const toggleButton = statusSlider.getToggleButton();
const container = statusSlider.getComponentContainer();
let text = await container.getText();
if (text === 'Inactive') {
await toggleButton.click();
sleepFor(2000);
await browser.wait(async () => await container.getCssValue('backgroundColor') === activeColor, 2000);
}
text = await statusSlider.getComponentText();
text = await container.getText();
const bgColor = await container.getCssValue('backgroundColor');
expect(text).toBe('Active');
@ -163,10 +164,7 @@ describe('Animation Tests', () => {
const hero = heroesList.get(0);
await hero.click();
await sleepFor(100);
const newTotal = await heroesList.count();
expect(newTotal).toBeLessThan(total);
await browser.wait(async () => await heroesList.count() < total, 2000);
});
});
@ -190,10 +188,7 @@ describe('Animation Tests', () => {
const hero = heroesList.get(0);
await hero.click();
await sleepFor(250);
const newTotal = await heroesList.count();
expect(newTotal).toBeLessThan(total);
await browser.wait(async () => await heroesList.count() < total, 2000);
});
});
@ -213,14 +208,14 @@ describe('Animation Tests', () => {
it('should filter down the list when a search is performed', async () => {
const heroesList = filterStagger.getHeroesList();
const total = await heroesList.count();
const formInput = filterStagger.getFormInput();
await formInput.sendKeys('Mag');
await sleepFor(500);
const newTotal = await heroesList.count();
await browser.wait(async () => await heroesList.count() === 2, 2000);
const newTotal = await heroesList.count();
expect(newTotal).toBeLessThan(total);
expect(newTotal).toBe(2);
});
});
@ -248,10 +243,7 @@ describe('Animation Tests', () => {
const hero = heroesList.get(0);
await hero.click();
await sleepFor(300);
const newTotal = await heroesList.count();
expect(newTotal).toBeLessThan(total);
await browser.wait(async () => await heroesList.count() < total, 2000);
});
});
});

View File

@ -23,11 +23,3 @@ export function getComponentContainer() {
const findContainer = () => by.css('div');
return locate(getComponent(), findContainer());
}
export async function getComponentText() {
const findContainerText = () => by.css('div');
const contents = locate(getComponent(), findContainerText());
const componentText = await contents.getText();
return componentText;
}

View File

@ -18,11 +18,3 @@ export function getComponentContainer() {
const findContainer = () => by.css('div');
return locate(getComponent(), findContainer());
}
export async function getComponentText() {
const findContainerText = () => by.css('div');
const contents = locate(getComponent(), findContainerText());
const componentText = await contents.getText();
return componentText;
}

View File

@ -9,7 +9,7 @@ import { AdComponent } from './ad.component';
selector: 'app-ad-banner',
// #docregion ad-host
template: `
<div class="ad-banner">
<div class="ad-banner-example">
<h3>Advertisements</h3>
<ng-template ad-host></ng-template>
</div>

View File

@ -18,6 +18,6 @@
color: black;
}
.ad-banner {
.ad-banner-example {
width: 400px;
}

View File

@ -1,12 +1,23 @@
'use strict'; // necessary for es6 output in node
import { browser, by, element } from 'protractor';
import { browser, by, element, ElementFinder, ExpectedConditions as EC } from 'protractor';
/* tslint:disable:quotemark */
describe('Elements', () => {
const messageInput = element(by.css('input'));
const popupButtons = element.all(by.css('button'));
// Helpers
const click = (elem: ElementFinder) => {
// Waiting for the element to be clickable, makes the tests less flaky.
browser.wait(EC.elementToBeClickable(elem), 5000);
elem.click();
};
const waitForText = (elem: ElementFinder) => {
// Waiting for the element to have some text, makes the tests less flaky.
browser.wait(async () => /\S/.test(await elem.getText()), 5000);
}
beforeEach(() => browser.get(''));
describe('popup component', () => {
@ -17,7 +28,7 @@ describe('Elements', () => {
it('should be displayed on button click', () => {
expect(popupComponent.isPresent()).toBe(false);
popupComponentButton.click();
click(popupComponentButton);
expect(popupComponent.isPresent()).toBe(true);
});
@ -25,7 +36,9 @@ describe('Elements', () => {
messageInput.clear();
messageInput.sendKeys('Angular rocks!');
popupComponentButton.click();
click(popupComponentButton);
waitForText(popupComponent);
expect(popupComponent.getText()).toContain('Popup: Angular rocks!');
});
@ -33,7 +46,7 @@ describe('Elements', () => {
popupComponentButton.click();
expect(popupComponent.isPresent()).toBe(true);
closeButton.click();
click(closeButton);
expect(popupComponent.isPresent()).toBe(false);
});
});
@ -46,7 +59,7 @@ describe('Elements', () => {
it('should be displayed on button click', () => {
expect(popupElement.isPresent()).toBe(false);
popupElementButton.click();
click(popupElementButton);
expect(popupElement.isPresent()).toBe(true);
});
@ -54,7 +67,9 @@ describe('Elements', () => {
messageInput.clear();
messageInput.sendKeys('Angular rocks!');
popupElementButton.click();
click(popupElementButton);
waitForText(popupElement);
expect(popupElement.getText()).toContain('Popup: Angular rocks!');
});
@ -62,7 +77,7 @@ describe('Elements', () => {
popupElementButton.click();
expect(popupElement.isPresent()).toBe(true);
closeButton.click();
click(closeButton);
expect(popupElement.isPresent()).toBe(false);
});
});

View File

@ -72,15 +72,15 @@
<h2>You submitted the following:</h2>
<div class="row">
<div class="col-xs-3">Name</div>
<div class="col-xs-9 pull-left">{{ model.name }}</div>
<div class="col-xs-9">{{ model.name }}</div>
</div>
<div class="row">
<div class="col-xs-3">Alter Ego</div>
<div class="col-xs-9 pull-left">{{ model.alterEgo }}</div>
<div class="col-xs-9">{{ model.alterEgo }}</div>
</div>
<div class="row">
<div class="col-xs-3">Power</div>
<div class="col-xs-9 pull-left">{{ model.power }}</div>
<div class="col-xs-9">{{ model.power }}</div>
</div>
<br>
<button class="btn btn-primary" (click)="submitted=false">Edit</button>

View File

@ -10,7 +10,7 @@ describe('Security E2E Tests', () => {
expect(interpolated.getText())
.toContain('Template <script>alert("0wned")</script> <b>Syntax</b>');
let bound = element(By.className('e2e-inner-html-bound'));
expect(bound.getText()).toContain('Template alert("0wned") Syntax');
expect(bound.getText()).toContain('Template Syntax');
let bold = element(By.css('.e2e-inner-html-bound b'));
expect(bold.getText()).toContain('Syntax');
});

View File

@ -7,7 +7,8 @@
box-sizing: border-box;
}
h3 {
text-align: center; margin-bottom: 0;
text-align: center;
margin-bottom: 0;
}
[class*='col-'] {
padding-right: 20px;

View File

@ -17,7 +17,8 @@ button {
border: none;
padding: 5px 10px;
border-radius: 4px;
cursor: pointer; cursor: hand;
cursor: pointer;
cursor: hand;
}
button:hover {
background-color: #cfd8dc;

View File

@ -12,7 +12,7 @@ h2, h3 {
body {
margin: 2em;
}
body, input[text], button {
body, input[type="text"], button {
color: #888;
font-family: Cambria, Georgia;
}

View File

@ -16,7 +16,8 @@ a {
box-sizing: border-box;
}
h3 {
text-align: center; margin-bottom: 0;
text-align: center;
margin-bottom: 0;
}
h4 {
position: relative;

View File

@ -18,7 +18,8 @@ button {
border: none;
padding: 5px 10px;
border-radius: 4px;
cursor: pointer; cursor: hand;
cursor: pointer;
cursor: hand;
}
button:hover {
background-color: #cfd8dc;

View File

@ -16,7 +16,8 @@ a {
box-sizing: border-box;
}
h3 {
text-align: center; margin-bottom: 0;
text-align: center;
margin-bottom: 0;
}
h4 {
position: relative;

View File

@ -3,7 +3,7 @@
border-bottom: 1px solid gray;
border-left: 1px solid gray;
border-right: 1px solid gray;
width:195px;
width: 195px;
height: 16px;
padding: 5px;
background-color: white;

View File

@ -2,7 +2,7 @@
<h4>Hero Search</h4>
<!-- #docregion input -->
<input #searchBox id="search-box" (keyup)="search(searchBox.value)" />
<input #searchBox id="search-box" (input)="search(searchBox.value)" />
<!-- #enddocregion input -->
<ul class="search-result">

View File

@ -40,7 +40,7 @@ export class HeroService {
// #enddocregion getHeroes-1
.pipe(
// #enddocregion getHeroes-2
tap(heroes => this.log('fetched heroes')),
tap(_ => this.log('fetched heroes')),
// #docregion getHeroes-2
catchError(this.handleError('getHeroes', []))
);

View File

@ -1,7 +1,11 @@
// #docregion , init
import { InMemoryDbService } from 'angular-in-memory-web-api';
import { Hero } from './hero';
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class InMemoryDataService implements InMemoryDbService {
createDb() {
const heroes = [

View File

@ -16,7 +16,8 @@ a {
box-sizing: border-box;
}
h3 {
text-align: center; margin-bottom: 0;
text-align: center;
margin-bottom: 0;
}
h4 {
position: relative;

View File

@ -18,7 +18,8 @@ button {
border: none;
padding: 5px 10px;
border-radius: 4px;
cursor: pointer; cursor: hand;
cursor: pointer;
cursor: hand;
}
button:hover {
background-color: #cfd8dc;

View File

@ -3,7 +3,7 @@
border-bottom: 1px solid gray;
border-left: 1px solid gray;
border-right: 1px solid gray;
width:195px;
width: 195px;
height: 16px;
padding: 5px;
background-color: white;

View File

@ -1,7 +1,7 @@
<div id="search-component">
<h4>Hero Search</h4>
<input #searchBox id="search-box" (keyup)="search(searchBox.value)" />
<input #searchBox id="search-box" (input)="search(searchBox.value)" />
<ul class="search-result">
<li *ngFor="let hero of heroes | async" >

View File

@ -1,6 +1,6 @@
'use strict'; // necessary for es6 output in node
import { browser, element, by, ElementFinder } from 'protractor';
import { browser, element, by, ElementArrayFinder, ElementFinder } from 'protractor';
// Angular E2E Testing Guide:
// https://docs.angularjs.org/guide/e2e-testing
@ -20,6 +20,12 @@ describe('PhoneCat Application', function() {
describe('View: Phone list', function() {
// Helpers
const waitForCount = (elems: ElementArrayFinder, count: number) => {
// Wait for the list to stabilize, which may take a while (e.g. due to animations).
browser.wait(() => elems.count().then(c => c === count), 5000);
};
beforeEach(function() {
browser.get('index.html#!/phones');
});
@ -28,13 +34,16 @@ describe('PhoneCat Application', function() {
let phoneList = element.all(by.repeater('phone in $ctrl.phones'));
let query = element(by.model('$ctrl.query'));
waitForCount(phoneList, 20);
expect(phoneList.count()).toBe(20);
query.sendKeys('nexus');
waitForCount(phoneList, 1);
expect(phoneList.count()).toBe(1);
query.clear();
query.sendKeys('motorola');
waitForCount(phoneList, 8);
expect(phoneList.count()).toBe(8);
});
@ -51,6 +60,7 @@ describe('PhoneCat Application', function() {
}
queryField.sendKeys('tablet'); // Let's narrow the dataset to make the assertions shorter
waitForCount(phoneNameColumn, 2);
expect(getNames()).toEqual([
'Motorola XOOM\u2122 with Wi-Fi',
@ -66,10 +76,16 @@ describe('PhoneCat Application', function() {
});
it('should render phone specific links', function() {
let phoneList = element.all(by.repeater('phone in $ctrl.phones'));
let query = element(by.model('$ctrl.query'));
query.sendKeys('nexus');
element.all(by.css('.phones li a')).first().click();
query.sendKeys('nexus');
waitForCount(phoneList, 1);
let nexusPhone = phoneList.first();
let detailLink = nexusPhone.all(by.css('a')).first()
detailLink.click();
expect(browser.getLocationAbsUrl()).toBe('/phones/nexus-s');
});

View File

@ -6,8 +6,7 @@
<div class="nf-response l-flex-wrap">
<h1 class="no-toc">Page Not Found</h1>
<h1 class="no-anchor no-toc">Page Not Found</h1>
<p>We're sorry. The page you are looking for cannot be found.</p>
</div>

View File

@ -104,7 +104,6 @@ When you create a component, it's associated directly with a single view, called
**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.
**注意:** 视图的这种层次结构是 Angular 在 DOM 和应用数据中检测与响应变更时的关键因素。
</div>
## NgModules and JavaScript modules

View File

@ -81,7 +81,7 @@ Similarly, use the `@Injectable()` decorator to indicate that a component or oth
该注入器会创建依赖、维护一个*容器*来管理这些依赖,并尽可能复用它们。
* A *provider* is an object that tell an injector how to obtain or create a dependency.
* A *provider* is an object that tells an injector how to obtain or create a dependency.
*提供商*是一个对象,用来告诉注入器应该如何获取或创建依赖。

View File

@ -54,11 +54,11 @@ The base file `environment.ts`, contains the default environment settings. For e
基础环境 `environment.ts` 包含了默认的环境设置。比如:
<code-example language="none" class="code-shell">
```
export const environment = {
production: false
};
</code-example>
```
The `build` command uses this as the build target when no environment is specified.
You can add further variables, either as additional properties on the environment object, or as separate objects.
@ -198,7 +198,11 @@ Any option that your build supports can be overridden in a build target configur
你还可以往目标环境中添加更多配置项。
你的构建目标支持的任何选项都可以在构建目标配置中进行覆盖。
To build using the staging configuration, run `ng build --configuration=staging`.
To build using the staging configuration, run the following command:
<code-example language="sh" class="code-shell">
ng build --configuration=staging
</code-example>
要想使用预生产环境进行构建,请运行 `ng build --configuration=staging`

View File

@ -3,7 +3,7 @@
# 部署
When you are ready to deploy your Angular application to a remote server, you have various options for
deployment.
deployment.
当你准备把 Angular 应用部署到远程服务器上时,有很多关于部署的选项。
@ -15,16 +15,16 @@ deployment.
## 最简化的部署方式
For the simplest deployment, build for development and copy the output directory to a web server.
For the simplest deployment, create a production build and copy the output directory to a web server.
最简化的部署方式就是为开发环境构建,并把其输出复制到 Web 服务器上。
1. Start with the development build:
1. Start with the production build:
使用开发环境进行构建
<code-example language="none" class="code-shell">
ng build
ng build --prod
</code-example>
2. Copy _everything_ within the output folder (`dist/` by default) to a folder on the server.
@ -37,8 +37,7 @@ Learn more about server-side redirects [below](#fallback).
配置服务器,让缺失的文件都重定向到 `index.html` 上。
欲知详情,参见[稍后](#fallback)的服务端重定向部分。
This is _not_ a production deployment. It's not optimized, and it won't be fast for users.
It might be good enough for sharing your progress and ideas internally with managers, teammates, and other stakeholders. For the next steps in deployment, see [Optimize for production](#optimize).
This is the simplest production-ready deployment of your application.
这*不是*生产环境部署。它没有优化过,对最终用户来说也不快。
但是,这足够用来跟管理者、团队成员和其它涉众在内部分享你的进度和想法了。
@ -54,7 +53,7 @@ Another simple way to deploy your Angular app is to use [GitHub Pages](https://h
另一种发布 Angular 应用的简单途径是使用 [GitHub Pages](https://help.github.com/articles/what-is-github-pages/)。
1. You need to [create a GitHub account](https://github.com/join) if you don't have one, and then [create a repository](https://help.github.com/articles/create-a-repo/) for your project.
1. You need to [create a GitHub account](https://github.com/join) if you don't have one, and then [create a repository](https://help.github.com/articles/create-a-repo/) for your project.
Make a note of the user name and project name in GitHub.
你需要[创建一个 GitHub 账号](https://github.com/join)(如果没有的话),然后为你的项目[创建一个仓库](https://help.github.com/articles/create-a-repo/)。记下 GitHub 中的用户名和项目名。
@ -67,11 +66,11 @@ Make a note of the user name and project name in GitHub.
ng build --prod --output-path docs --base-href <project_name>
</code-example>
1. When the build is complete, make a copy of `docs/index.html` and name it `docs/404.html`.
1. When the build is complete, make a copy of `docs/index.html` and name it `docs/404.html`.
当构建完成时,把 `docs/index.html` 复制为 `docs/404.html`
1. Commit your changes and push.
1. Commit your changes and push.
提交你的更改,并推送。
@ -165,82 +164,6 @@ The list is by no means exhaustive, but should provide you with a good starting
后面这些部分会描述对常见服务器的配置方式。
这个列表虽然不够详尽,但可以为你提供一个良好的起点。
#### Development servers
#### 开发服务器
During development, the [`ng serve`](cli/serve) CLI command lets you run your app in a local browser.
The CLI recompiles the application each time you save a file,
and reloads the browser with the newly compiled application.
在开发期间CLI 命令 [`ng serve`](cli/serve) 能让你在本地浏览器中运行你的应用。
每当你保存文件时CLI 就会重新编译该应用,并刷新浏览器,来加载最新编译的应用。
The app is hosted in local memory and served on `http://localhost:4200/`, using [webpack-dev-server](https://webpack.js.org/guides/development/#webpack-dev-server).
该应用运行在本地内存里,并使用 [webpack-dev-server](https://webpack.js.org/guides/development/#webpack-dev-server) 来在 `http://localhost:4200/` 端口上提供服务。
{@a serve-from-disk}
Later in development, you might want a closer approximation of how your app will behave when deployed.
You can output your distribution folder (`dist`) to disk, but you need to install a different web server.
Try installing [lite-server](https://github.com/johnpapa/lite-server); like `webpack-dev-server`, it can automatically reload your browser when you write new files.
在开发的后期阶段,你可能会希望让应用更接近部署后的行为方式。
这时,你可以把发布目录(`dist`)输出到磁盘上,但还要安装另一个 Web 服务器。
可以尝试安装 [lite-server](https://github.com/johnpapa/lite-server),像 `webpack-dev-server` 一样,当你修改了文件时,它可以自动刷新浏览器。
To get the live-reload experience, you will need to run two terminals.
The first runs the build in a watch mode and compiles the application to the `dist` folder.
The second runs the web server against the `dist` folder.
The combination of these two processes provides the same behavior as `ng serve`.
要想获得实时刷新live-reload的体验你需要运行两个终端。
第一个在监视模式下运行 `build` 命令,把应用随时编译到 `dist` 目录下。
第二个针对 `dist` 目录运行 Web 服务器。
这两个过程组合起来,提供了与 `ng serve` 相同的行为。
1. Start the build in terminal A:
在终端 A 中启动构建:
<code-example language="none" class="code-shell">
ng build --watch
</code-example>
1. Start the web server in terminal B:
在终端 B 中启动 Web 服务器:
<code-example language="none" class="code-shell">
lite-server --baseDir="dist"
</code-example>
The default browser opens to the appropriate URL.
默认的浏览器会打开相应的 URL。
* [Lite-Server](https://github.com/johnpapa/lite-server): the default dev server installed with the
[Quickstart repo](https://github.com/angular/quickstart) is pre-configured to fallback to `index.html`.
[Lite-Server](https://github.com/johnpapa/lite-server)是["快速上手"仓库](https://github.com/angular/quickstart)中安装的默认开发服务器,它被预先配置为回退到 `index.html`
* [Webpack-Dev-Server](https://github.com/webpack/webpack-dev-server): setup the
`historyApiFallback` entry in the dev server options as follows:
[Webpack-Dev-Server](https://github.com/webpack/webpack-dev-server)在开发服务器的配置中设置了 `historyApiFallback`,代码如下:
<code-example>
historyApiFallback: {
disableDotRule: true,
htmlAcceptHeaders: ['text/html', 'application/xhtml+xml']
}
</code-example>
#### Production servers
#### 生产服务器
* [Apache](https://httpd.apache.org/): add a
[rewrite rule](http://httpd.apache.org/docs/current/mod/mod_rewrite.html) to the `.htaccess` file as shown
(https://ngmilk.rocks/2015/03/09/angularjs-html5-mode-or-pretty-urls-on-apache-using-htaccess/):
@ -348,25 +271,11 @@ Read about how to enable CORS for specific servers at
{@a optimize}
## Optimize for production
## Production optimizations
## 生产环境优化
## 生产环境优化
Although deploying directly from the development environment works,
you can generate an optimized build with additional CLI command line flags,
starting with `--prod`.
虽然也可以直接用开发环境部署,但也可以使用其它的 CLI 命令行标志来生成优化过的构建成果,我们先从 `--prod` 开始讲。
### Build with _--prod_
### 使用*--prod*构建
<code-example language="none" class="code-shell">
ng build --prod
</code-example>
The `--prod` _meta-flag_ engages the following optimization features.
The `--prod` _meta-flag_ engages the following build optimization features.
`--prod` 标志具有如下优化特性。
@ -394,38 +303,31 @@ The `--prod` _meta-flag_ engages the following optimization features.
消除死代码:删除未引用过的模块和很多未用到的代码。
The remaining [copy deployment steps](#copy-files) are the same as before.
其余的[复制等部署步骤](#copy-files)步骤和以前的一样。
See [`ng build`](cli/build) for more about CLI build options and what they do.
要了解关于 CLI 构建选项及其作用的更多知识,参见 [`ng build`](cli/build)。
{@a enable-prod-mode}
### Enable production mode
### Enable runtime production mode
### 启用生产模式
Angular apps run in development mode by default, as you can see by the following message on the browser
console:
In addition to build optimizations, Angular also has a runtime production mode. Angular apps run in development mode by default, as you can see by the following message on the browser console:
Angular 应用默认运行在开发模式下,你可以在浏览器的控制台中看到如下信息:
除了构建期优化之外Angular 还支持运行期生产模式。Angular 应用默认运行在开发模式下,你可以在浏览器的控制台中看到如下信息:
<code-example format="nocode">
Angular is running in the development mode. Call enableProdMode() to enable the production mode.
</code-example>
Switching to _production mode_ can make it run faster by disabling development specific checks such as the dual change detection cycles.
Switching to _production mode_ makes it run faster by disabling development specific checks such as the dual change detection cycles.
切换到*生产模式*可以通过禁用开发阶段特有的检查(比如双重变更检测周期)来让它运行得更快。
Building for production (or appending the `--environment=prod` flag) enables _production mode_
Look at the CLI-generated `main.ts` to see how this works.
When you enable production builds via `--prod` command line flag, the runtime production mode is enabled as well.
为生产环境构建(添加 `--environment=prod` 标识)可以启用*生产模式*。
阅读 CLI 生成的 `main.ts` 以了解它的工作原理。
如果在构建时添加了 `--prod` 标识,也会同时启用*运行期生产模式*。
{@a lazy-loading}
@ -460,7 +362,7 @@ If you do that, the module will be loaded immediately.
The bundling configuration must take lazy loading into consideration.
Because lazy-loaded modules aren't imported in JavaScript, bundlers exclude them by default.
Bundlers don't know about the router configuration and can't create separate bundles for lazy-loaded modules.
Bundlers don't know about the router configuration and can't create separate bundles for lazy-loaded modules.
You would have to create these bundles manually.
配置打包方式时必须考虑惰性加载。
@ -609,7 +511,7 @@ for the missing files. Look at where it _tried_ to find those files and adjust t
## 为部署而构建和启动服务器
When you are designing and developing applications, you typically use `ng serve` to build your app for fast, local, iterative development.
When you are designing and developing applications, you typically use `ng serve` to build your app for fast, local, iterative development.
When you are ready to deploy, however, you must use the `ng build` command to build the app and deploy the build artifacts elsewhere.
在设计和开发应用程序时,通常使用 `ng serve` 来构建应用,已进行快速的、本地的、迭代式的开发。
@ -630,7 +532,7 @@ To output to a different folder, change the `outputPath` in `angular.json`.
</div>
The `ng serve` command builds, watches, and serves the application from local memory, using a local development server.
When you have deployed your app to another server, however, you might still want to serve the app so that you can continue to see changes that you make in it.
When you have deployed your app to another server, however, you might still want to serve the app so that you can continue to see changes that you make in it.
You can do this by adding the `--watch` option to the `ng build` command.
`ng serve` 命令会构建、监视并使用本地开发服务器从内存中提供网站服务。
@ -639,7 +541,7 @@ You can do this by adding the `--watch` option to the `ng build` command.
```
ng build --watch
```
Like the `ng serve` command, this regenerates output files when source files change.
Like the `ng serve` command, this regenerates output files when source files change.
`ng serve` 命令一样,当源码文件发生变化时,它会重新生成输出文件。

View File

@ -265,7 +265,7 @@ Here are two sample components and the `AdComponent` interface for reference:
最终的广告栏是这样的:
<figure>
<img src="generated/images/guide/dynamic-component-loader/ads.gif" alt="Ads">
<img src="generated/images/guide/dynamic-component-loader/ads-example.gif" alt="Ads">
</figure>
See the <live-example name="dynamic-component-loader"></live-example>.

View File

@ -227,19 +227,13 @@ The recently-developed [custom elements](https://developer.mozilla.org/en-US/doc
</tr>
<tr>
<td>Firefox</td>
<td>
Firefox
</td>
<td>
Set the <code>dom.webcomponents.enabled</code> and <code>dom.webcomponents.customelements.enabled</code> preferences to true. Planned to be enabled by default in version 63.
<code>dom.webcomponents.enabled</code><code>dom.webcomponents.customelements.enabled</code> 首选项设置为 true。计划在版本 60/61 中提供原生支持。
Supported natively as of version 63. In older versions: Set the <code>dom.webcomponents.enabled</code> and <code>dom.webcomponents.customelements.enabled</code> preferences to true.
在 63 版中原生支持。对于老版本,可以把 <code>dom.webcomponents.enabled</code><code>dom.webcomponents.customelements.enabled</code> 首选项设置为 true。
</td>
</tr>
<tr>
@ -337,17 +331,28 @@ For comparison, the demo shows both methods. One button adds the popup using the
-->
You can download the full code for the example <live-example downloadOnly>here</live-example>.
你可以到 <live-example downloadOnly>这里</live-example> 下载本例子的完整代码。
## Typings for custom elements
## 为自定义元素添加类型支持
Generic DOM APIs, such as `document.createElement()` or `document.querySelector()`, return an element type that is appropriate for the specified arguments. For example, calling `document.createElement('a')` will return an `HTMLAnchorElement`, which TypeScript knows has an `href` property. Similarly, `document.createElement('div')` will return an `HTMLDivElement`, which TypeScript knows has no `href` property.
一般的 DOM API比如 `document.createElement()``document.querySelector()`,会返回一个与指定的参数相匹配的元素类型。比如,调用 `document.createElement('a')` 会返回 `HTMLAnchorElement`,这样 TypeScript 就会知道它有一个 `href` 属性,而 `document.createElement('div')` 会返回 `HTMLDivElement`,这样 TypeScript 就会知道它没有 `href` 属性。
When called with unknown elements, such as a custom element name (`popup-element` in our example), the methods will return a generic type, such as `HTMLELement`, since TypeScript can't infer the correct type of the returned element.
当调用未知元素(比如自定义的元素名 `popup-element`)时,该方法会返回泛化类型,比如 `HTMLELement`,这时候 TypeScript 就无法推断出所返回元素的正确类型。
Custom elements created with Angular extend `NgElement` (which in turn extends `HTMLElement`). Additionally, these custom elements will have a property for each input of the corresponding component. For example, our `popup-element` will have a `message` property of type `string`.
用 Angular 创建的自定义元素会扩展 `NgElement` 类型(而它扩展了 `HTMLElement`)。除此之外,这些自定义元素还拥有相应组件的每个输入属性。比如,`popup-element` 元素具有一个 `string` 型的 `message` 属性。
There are a few options if you want to get correct types for your custom elements. Let's assume you create a `my-dialog` custom element based on the following component:
如果你要让你的自定义元素获得正确的类型,还可使用一些选项。假设你要创建一个基于下列组件的自定义元素 `my-dialog`
```ts
@Component(...)
class MyDialog {
@ -357,6 +362,8 @@ class MyDialog {
The most straight forward way to get accurate typings is to cast the return value of the relevant DOM methods to the correct type. For that, you can use the `NgElement` and `WithProperties` types (both exported from `@angular/elements`):
获得精确类型的最简单方式是把相关 DOM 方法的返回值转换成正确的类型。要做到这一点,你可以使用 `NgElement``WithProperties` 类型(都导出自 `@angular/elements`
```ts
const aDialog = document.createElement('my-dialog') as NgElement & WithProperties<{content: string}>;
aDialog.content = 'Hello, world!';
@ -366,8 +373,12 @@ aDialog.body = 'News'; // <-- ERROR: TypeScript knows there is no `body` proper
This is a good way to quickly get TypeScript features, such as type checking and autocomplete support, for you custom element. But it can get cumbersome if you need it in several places, because you have to cast the return type on every occurrence.
这是一种让你的自定义元素快速获得 TypeScript 特性(比如类型检查和自动完成支持)的好办法,不过如果你要在多个地方使用它,可能会有点啰嗦,因为不得不在每个地方对返回类型做转换。
An alternative way, that only requires defining each custom element's type once, is augmenting the `HTMLELementTagNameMap`, which TypeScript uses to infer the type of a returned element based on its tag name (for DOM methods such as `document.createElement()`, `document.querySelector()`, etc.):
另一种方式可以对每个自定义元素的类型只声明一次。你可以扩展 `HTMLELementTagNameMap`TypeScript 会在 DOM 方法(如 `document.createElement()`、`document.querySelector()` 等)中用它来根据标签名推断返回元素的类型。
```ts
declare global {
interface HTMLElementTagNameMap {
@ -380,6 +391,8 @@ declare global {
Now, TypeScript can infer the correct type the same way it does for built-in elements:
现在TypeScript 就可以像内置元素一样推断出它的正确类型了:
```ts
document.createElement('div') //--> HTMLDivElement (built-in element)
document.querySelector('foo') //--> Element (unknown element)

View File

@ -150,7 +150,7 @@ When the CLI generated the `CustomerDashboardComponent` for the feature module,
<code-example path="feature-modules/src/app/customer-dashboard/customer-dashboard/customer-dashboard.component.html" region="feature-template" header="src/app/customer-dashboard/customer-dashboard/customer-dashboard.component.html" linenums="false">
</code-example>
To see this HTML in the `AppComponent`, you first have to export the `CustomerDashboardComponent` in the `CustomerDashboardModule`. In `customer-dashboard.module.ts`, just beneath the `declarations` array, add an `exports` array containing `CustomerDashboardModule`:
To see this HTML in the `AppComponent`, you first have to export the `CustomerDashboardComponent` in the `CustomerDashboardModule`. In `customer-dashboard.module.ts`, just beneath the `declarations` array, add an `exports` array containing `CustomerDashboardComponent`:
要想在 `AppComponent` 中查看这些 HTML你首先要在 `CustomerDashboardModule` 中导出 `CustomerDashboardComponent`
`customer-dashboard.module.ts` 中,`declarations` 数组的紧下方,加入一个包含 `CustomerDashboardModule``exports` 数组:

View File

@ -42,16 +42,15 @@ The top level of the workspace contains a number of workspace-wide configuration
| :--------------------- | :------------------------------------------|
| `.editorconfig` | <t>Configuration for code editors. See [EditorConfig](https://editorconfig.org/). </t><t>代码编辑器配置。参见 [EditorConfig](https://editorconfig.org/)</t> |
| `.gitignore` | <t>Specifies intentionally untracked files that [Git](https://git-scm.com/) should ignore. </t><t>指定 [Git](https://git-scm.com/) 要忽略的非跟踪的文件。</t> |
| `angular.json` | <t>CLI configuration for all projects in the workspace, including configuration options for build, serve, and test tools that the CLI uses, such as [Karma](https://karma-runner.github.io/) and [Protractor](http://www.protractortest.org/). </t><t>工作区中所有项目的 CLI 配置,包括 CLI 使用的构建选项、运行选项、测试工具选项(比如 [Karma](https://karma-runner.github.io/)、[Protractor](http://www.protractortest.org/))等</t> |
| `angular.json` | <t>CLI configuration defaults for all projects in the workspace, including configuration options for build, serve, and test tools that the CLI uses, such as [TSLint](https://palantir.github.io/tslint/), [Karma](https://karma-runner.github.io/), and [Protractor](http://www.protractortest.org/). For details, see [Angular Workspace Configuration](guide/workspace-config). </t><t>工作区中所有项目的默认 CLI 配置,包括 CLI 使用的构建选项、运行选项、测试工具选项(比如 [TSLint](https://palantir.github.io/tslint/)、[Karma](https://karma-runner.github.io/)、[Protractor](http://www.protractortest.org/))等。欲知详情,参见 [Angular 工作空间配置](guide/workspace-config)。</t> |
| `node_modules` | <t>Provides [npm packages](guide/npm-packages) to the entire workspace. </t><t>提供给整个工作空间的 [npm 包](guide/npm-packages)。</t> |
| `package.json` | <t>Lists package dependencies. See [npm documentation](https://docs.npmjs.com/files/package.json) for the specific format and contents of this file.</t><t>列出包依赖项。有关此文件的特有格式和内容,参见 [npm 文档](https://docs.npmjs.com/files/package.json)。</t> |
| `tsconfig.app.json` | <t>Default [TypeScript](https://www.typescriptlang.org/) configuration for apps in the workspace. </t><t>工作空间中所有应用的默认 [TypeScript](https://www.typescriptlang.org/) 配置</t> |
| `tsconfig.spec.json` | <t>Default TypeScript configuration for e2e test apps in the workspace. </t><t>工作空间中所有端到端测试类应用的默认 TypeScript 配置。</t> |
| `package.json` | <t>Configures [npm package dependencies](guide/npm-packages) that are available to all projects in the workspace. See [npm documentation](https://docs.npmjs.com/files/package.json) for the specific format and contents of this file.</t><t>配置用于工作空间中所有项目的包依赖项。有关此文件的特有格式和内容,参见 [npm 文档](https://docs.npmjs.com/files/package.json)。</t> |
| `package-lock.json` | <t>Provides version information for all packages installed into `node_modules` by the npm client. See [npm documentation](https://docs.npmjs.com/files/package-lock.json) for details. If you use the yarn client, this file will be [yarn.lock](https://yarnpkg.com/lang/en/docs/yarn-lock/) instead. </t><t>为 npm 客户端安装到 `node_modules` 中的所有软件包提供版本信息。详情参见 [npm documentation](https://docs.npmjs.com/files/package-lock.json)。如果你使用 yarn 客户端,此文件会由 [yarn.lock](https://yarnpkg.com/lang/en/docs/yarn-lock/) 代替</t> |
| `tsconfig.json` | <t>Default [TypeScript](https://www.typescriptlang.org/) configuration for apps in the workspace, including TypeScript and Angular template compiler options. See [TypeScript Configuration](guide/typescript-configuration). </t><t>工作空间中所有应用的默认 [TypeScript](https://www.typescriptlang.org/) 配置。包括 TypeScript 选项和 Angular 模板编译器选项。参见 [TypeScript 配置](guide/typescript-configuration)</t> |
| `tslint.json` | <t>Default [TSLint](https://palantir.github.io/tslint/) configuration for apps in the workspace. </t><t>工作空间中所有应用的默认 [TSLint](https://palantir.github.io/tslint/) 配置。</t> |
| `README.md` | <t>Introductory documentation. </t><t>介绍文档</t> |
| `package-lock.json` | <t>Provides version information for all packages installed into `node_modules` by the npm client. See [npm documentation](https://docs.npmjs.com/files/package-lock.json) for details. If you use the yarn client, this file will be [yarn.lock](https://yarnpkg.com/lang/en/docs/yarn-lock/) instead. </t><t>为 npm 客户端安装到 `node_modules` 中的所有软件包提供版本信息。详情参见 [npm documentation](https://docs.npmjs.com/files/package-lock.json)。如果你使用 yarn 客户端,此文件会由 [yarn.lock](https://yarnpkg.com/lang/en/docs/yarn-lock/) 代替。</t> |
All projects within a workspace share this configuration context.
All projects within a workspace share a [CLI configuration context](guide/workspace-config).
Project-specific [TypeScript](https://www.typescriptlang.org/) configuration files inherit from the workspace-wide `tsconfig.*.json`, and app-specific [TSLint](https://palantir.github.io/tslint/) configuration files inherit from the workspace-wide `tslint.json`.
工作空间中的所有项目都共享这个配置上下文。
@ -157,18 +156,6 @@ Inside the `src/` folder, the `app/` folder contains your app's logic and data.
`src/` 目录下,`app/` 目录包含你的应用逻辑和数据。Angular 组件、模板和样式都在这里。
`assets/` 子目录包含图片和应用所需的其它文件。`src/` 顶层的文件用于支持测试和运行你的应用。
<code-example language="none" linenums="false">
src/
app/
app.component.css
app.component.html
app.component.spec.ts
app.component.ts
app.module.ts
assets/...
...
</code-example>
| <t>APP SOURCE FILES</t><t>应用源文件</t> | <t>PURPOSE</t><t>用途</t> |
| :-------------------------- | :------------------------------------------|
| `app/app.component.ts` | <t>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 app. </t><t>定义应用程序根组件(名叫 `AppComponent`)的逻辑代码。当你往应用中添加组件和服务时,根组件所关联的视图会作为 [view hierarchy](guide/glossary#view-hierarchy) 视图树的根。</t> |

View File

@ -502,7 +502,7 @@ A common UI pattern is to show a spinner while the async validation is being per
常见的 UI 处理模式是在执行异步验证时显示一个旋转指示标spinner。下面的例子展示了在模板驱动表单中该怎么做
```html
<input [(ngModel)}="name" #model="ngModel" appSomeAsyncValidator>
<input [(ngModel)]="name" #model="ngModel" appSomeAsyncValidator>
<app-spinner *ngIf="model.pending"></app-spinner>
```

View File

@ -2,7 +2,7 @@
# Angular 表单检测
Handling user input with forms is the cornerstone of many common applications. Applications use forms to enable users log in, to update a profile, to enter sensitive information, and to perform many other data-entry tasks.
Handling user input with forms is the cornerstone of many common applications. Applications use forms to enable users to log in, to update a profile, to enter sensitive information, and to perform many other data-entry tasks.
用表单处理用户输入是许多常见应用的基础功能。
应用通过表单来让用户登录、修改个人档案、输入敏感信息以及执行各种数据输入任务。
@ -12,7 +12,7 @@ Angular provides two different approaches to handling user input through forms:
Angular 提供了两种不同的方法来通过表单处理用户输入:响应式表单和模板驱动表单。
两者都从视图中捕获用户输入事件、验证用户输入、创建表单模型、修改数据模型,并提供跟踪这些更改的途径。
Reactive and template-driven forms differ, however, in how they do the work of processing and managing forms and form data. Each offers different advantages.
Reactive and template-driven forms process and manage form data differently. Each offers different advantages.
不过,响应式表单和模板驱动表单在如何处理和管理表单和表单数据方面有所不同。各有优势。
@ -20,22 +20,22 @@ Reactive and template-driven forms differ, however, in how they do the work of p
**一般来说:**
* **Reactive forms** are more robust: they are more scalable, reusable, and testable. If forms are a key part of your application, or you're already using reactive patterns for building your application, use reactive forms.
* **Reactive forms** are more robust: they're more scalable, reusable, and testable. If forms are a key part of your application, or you're already using reactive patterns for building your application, use reactive forms.
**响应式表单**更健壮:它们的可扩展性、可复用性和可测试性更强。
如果表单是应用中的关键部分,或者你已经准备使用响应式编程模式来构建应用,请使用响应式表单。
* **Template-driven forms** are useful for adding a simple form to an app, such as an email list signup form. They are easy to add to an app, but they do not scale as well as reactive forms. If you have very basic form requirements and logic that can be managed solely in the template, use template-driven forms.
* **Template-driven forms** are useful for adding a simple form to an app, such as an email list signup form. They're easy to add to an app, but they don't scale as well as reactive forms. If you have very basic form requirements and logic that can be managed solely in the template, use template-driven forms.
**模板驱动表单**在往应用中添加简单的表单时非常有用,比如邮件列表的登记表单。它们很容易添加到应用中,但是不像响应式表单那么容易扩展。如果你有非常基本的表单需求和简单到能用模板管理的逻辑,请使用模板驱动表单。
This guide provides information to help you decide which approach works best for your situation. It introduces the common building blocks used by both approaches. It also summarizes the key differences between the two approaches, and demonstrates those differences in the context of setup, data flow, and testing.
This guide provides information to help you decide which type of form works best for your situation. It introduces the common building blocks used by both approaches. It also summarizes the key differences between the two approaches, and demonstrates those differences in the context of setup, data flow, and testing.
本指南提供的信息可以帮你确定哪种方式最适合你的情况。它介绍了这两种方法所用的公共构造块,还总结了两种方式之间的关键区别,并在建立、数据流和测试等不同的情境下展示了这些差异。
<div class="alert is-important">
<div class="alert is-helpful">
*Note:* For complete information about each kind of form, see the [Reactive Forms](guide/reactive-forms) and [Template-driven Forms](guide/forms) guides.
**Note:** For complete information about each kind of form, see [Reactive Forms](guide/reactive-forms) and [Template-driven Forms](guide/forms).
**注意:**要了解这些表单的详情,参见[响应式表单](guide/reactive-forms)和[模板驱动表单](guide/forms)。
@ -56,7 +56,7 @@ The table below summarizes the key differences between reactive and template-dri
||<t>Reactive</t><t>响应式</t>|<t>Template-driven</t><t>模板驱动</t>|
|--- |--- |--- |
|<t>Setup (form model)</t><t>建立(表单模式)</t>|<t>More explicit, created in the component class.</t><t>显式,在组件类中创建。</t>|<t>Less explicit, created by the directives.</t><t>隐式,由组件创建。</t>|
|<t>Setup (form model)</t><t>建立(表单模式)</t>|<t>More explicit, created in component class</t><t>显式,在组件类中创建。</t>|<t>Less explicit, created by directives</t><t>隐式,由组件创建。</t>|
|<t>Data model</t><t>数据模式</t>|<t>Structured</t><t>结构化</t>|<t>Unstructured</t><t>非结构化</t>|
|<t>Predictability</t><t>可预测性</t>|<t>Synchronous</t><t>同步</t>|<t>Asynchronous</t><t>异步</t>|
|<t>Form validation</t><t>表单验证</t>|<t>Functions</t><t>函数</t>|<t>Directives</t><t>指令</t>|
@ -69,33 +69,35 @@ The table below summarizes the key differences between reactive and template-dri
Both reactive and template-driven forms share underlying building blocks.
无论响应式表单还是模板驱动表单都共享了一些底层构造块。
响应式表单和模板驱动表单共享了一些底层构造块。
- A `FormControl` instance that tracks the value and validation status of an individual form control.
* `FormControl` tracks the value and validation status of an individual form control.
`FormControl` 实例用于追踪单个表单控件的值和验证状态。
- A `FormGroup` instance that tracks the same values and status for a collection of form controls.
* `FormGroup` tracks the same values and status for a collection of form controls.
`FormGroup` 实例用于追踪一个表单控件集的值和状态。
`FormGroup` 用于追踪一个表单控件组的值和状态。
- A `FormArray` instance that tracks the same values and status for an array of form controls.
* `FormArray` tracks the same values and status for an array of form controls.
`FormArray` 实例用于追踪一个表单控件数组的值和状态。
`FormArray` 用于追踪表单控件数组的值和状态。
- A `ControlValueAccessor` that creates a bridge between Angular `FormControl` instances and native DOM elements.
* `ControlValueAccessor` creates a bridge between Angular `FormControl` instances and native DOM elements.
`ControlValueAccessor` 用于在 Angular 的 `FormControl` 实例和原生 DOM 元素之间创建一个桥梁。
How these control instances are created and managed with reactive and template-driven forms is introduced in the [form model setup](#setup-the-form-model) section below and detailed further in the [data flow section](#data-flow-in-forms) of this guide.
See the [Form model setup](#setup-the-form-model) section below for an introduction to how these control instances are created and managed with reactive and template-driven forms. Further details are provided in the [data flow section](#data-flow-in-forms) of this guide.
如何使用响应式表单和模板驱动表单来创建和管理这些控件实例,参见稍后的[建立表单模型](#setup-the-form-model)部分,更详细的在本章的[数据流](#data-flow-in-forms)部分
参见稍后的[建立表单模型](#setup-the-form-model)部分,了解如何使用响应式表单和模板驱动表单来创建和管理这些控件实例。本章的[数据流](#data-flow-in-forms)部分有更详细的介绍
## Setup: The form model
{@a setup-the-form-model}
## 建立:表单模型
## Form model setup
Reactive and template-driven forms both use a form model to track value changes between Angular forms and form input elements. The examples below show how the form model is defined and created.
## 建立表单模型
Reactive and template-driven forms both use a form model to track value changes between Angular forms and form input elements. The examples below show how the form model is defined and created.
响应式表单和模板驱动表单都是用表单模型来跟踪 Angular 表单和表单输入元素之间值的变化。下面的例子展示了如何定义和创建表单模型。
@ -103,14 +105,14 @@ Reactive and template-driven forms both use a form model to track value changes
### 在响应式表单中建立
Here is a component with an input field for a single control implemented using reactive forms.
Here's a component with an input field for a single control implemented using reactive forms.
下面是一个带有输入字段的组件,它使用响应式表单实现了单个控件。
<code-example path="forms-overview/src/app/reactive/favorite-color/favorite-color.component.ts">
</code-example>
The source of truth provides the value and status of the form element at a given point in time. In reactive forms, the form model is source of truth. The form model in the above example is the `FormControl` instance.
The source of truth provides the value and status of the form element at a given point in time. In reactive forms, the form model is the source of truth. In the example above, the form model is the `FormControl` instance.
权威数据源负责提供在指定时间点上表单元素的值和状态。在响应式表单中,表单模式充当权威数据源。上例中的表单模型就是 `FormControl` 的实例。
@ -118,7 +120,7 @@ The source of truth provides the value and status of the form element at a given
<img src="generated/images/guide/forms-overview/key-diff-reactive-forms.png" alt="Reactive forms key differences">
</figure>
With reactive forms, the form model is explicitly defined in the component class. The reactive form directive (in this case, `FormControlDirective`) then links the existing form control instance to a specific form element in the view using a value accessor (instance of `ControlValueAccessor`).
With reactive forms, the form model is explicitly defined in the component class. The reactive form directive (in this case, `FormControlDirective`) then links the existing `FormControl` instance to a specific form element in the view using a value accessor (`ControlValueAccessor` instance).
在响应式表单中,表单模型是显式定义在组件类中的。接着,响应式表单指令(这里是 `FormControlDirective`)会把这个现有的表单控件实例通过数据访问器(`ControlValueAccessor` 的实例)来指派给视图中的表单元素。
@ -126,7 +128,7 @@ With reactive forms, the form model is explicitly defined in the component class
### 在模板驱动表单中建立
Here is the same component with an input field for a single control implemented using template-driven forms.
Here's the same component with an input field for a single control implemented using template-driven forms.
下面是同一个带有输入字段的组件,它使用模板驱动表单实现了单个控件。
@ -141,7 +143,9 @@ In template-driven forms, the source of truth is the template.
<img src="generated/images/guide/forms-overview/key-diff-td-forms.png" alt="Template-driven forms key differences">
</figure>
The abstraction of the form model promotes simplicity over structure. The template-driven form directive `NgModel` is responsible for creating and managing the form control instance for a given form element. It is less explicit, but you no longer have direct control over the form model.
The abstraction of the form model promotes simplicity over structure. The template-driven form directive `NgModel` is responsible for creating and managing the `FormControl` instance for a given form element. It's less explicit, but you no longer have direct control over the form model.
{@a data-flow-in-forms}
表单模型的抽象促进了结构的简化。模板驱动表单的 `NgModel` 指令负责创建和管理指定表单元素上的表单控件实例。它不那么明显,但你不必再直接操纵表单模型了。
@ -149,7 +153,7 @@ The abstraction of the form model promotes simplicity over structure. The templa
## 表单中的数据流
When building forms in Angular, it's important to understand how the framework handles data flowing from the user or from programmatic changes. Reactive and template-driven forms follow two different strategies when handling form input. The data flow examples below begin with the favorite color input field example from above, and they show how changes to favorite color are handled in reactive forms compared to template-driven forms.
When building forms in Angular, it's important to understand how the framework handles data flowing from the user or from programmatic changes. Reactive and template-driven forms follow two different strategies when handling form input. The data flow examples below begin with the favorite color input field example from above, and then show how changes to favorite color are handled in reactive forms compared to template-driven forms.
当在 Angular 中构建表单时,理解框架如何处理来自用户或程序化修改的数据流是非常重要的。
在处理表单输入时,响应式表单和模板驱动表单遵循两种不同的策略。下面的数据流范例从以前的 "喜欢的颜色" 输入框开始,展示了它在响应式表单中的工作方式与模板驱动表单相比有何不同。
@ -158,7 +162,7 @@ When building forms in Angular, it's important to understand how the framework h
### 响应式表单中的数据流
As described above, in reactive forms each form element in the view is directly linked to a form model (`FormControl` instance). Updates from the view to model and model to view are synchronous and not dependent on the UI rendered. The diagrams below use the same favorite color example to demonstrate how data flows when an input field's value is changed from the view and then from the model.
As described above, in reactive forms each form element in the view is directly linked to a form model (`FormControl` instance). Updates from the view to the model and from the model to the view are synchronous and aren't dependent on the UI rendered. The diagrams below use the same favorite color example to demonstrate how data flows when an input field's value is changed from the view and then from the model.
如前所述,在响应式表单中,视图中的每个表单元素都直接链接到一个表单模型(`FormControl` 实例)。
从视图到模型的修改以及从模型到视图的修改都是同步的,不依赖于所呈现的 UI。下面的图标使用了同一个 "喜欢的颜色" 范例,来演示当输入字段的值的变更来自视图和来自模型时,数据如何流动。
@ -167,14 +171,13 @@ As described above, in reactive forms each form element in the view is directly
<img src="generated/images/guide/forms-overview/dataflow-reactive-forms-vtm.png" alt="Reactive forms data flow - view to model" width="100%">
</figure>
The steps below outline the view to model data flow.
The steps below outline the data flow from view to model.
下面这些步骤列出了 "从视图到模型" 数据流的梗概。
1. The end user types a value into the input element, in this case the favorite color "Blue".
1. The user types a value into the input element, in this case the favorite color *Blue*.
最终用户在输入框元素中键入了一个值,这里是 "Blue"。
1. The form input element emits an "input" event with the latest value.
这个输入框元素会发出一个带有最新值的 "input" 事件。
@ -195,14 +198,13 @@ The steps below outline the view to model data flow.
<img src="generated/images/guide/forms-overview/dataflow-reactive-forms-mtv.png" alt="Reactive forms data flow - model to view" width="100%">
</figure>
The steps below outline the model to view data flow.
The steps below outline the data flow from model to view.
下面这些步骤列出了从模型到视图的数据流的梗概。
1. The `favoriteColorControl.setValue()` method is called, which updates the `FormControl` value.
1. The user calls the `favoriteColorControl.setValue()` method, which updates the `FormControl` value.
`favoriteColorControl.setValue()` 方法被调用,它会更新这个 `FormControl` 的值。
1. The `FormControl` instance emits the new value through the `valueChanges` observable.
`FormControl` 实例会通过 `valueChanges` 这个可观察对象发出新值。
@ -219,26 +221,25 @@ The steps below outline the model to view data flow.
### 模板驱动表单中的数据流
In template-driven forms, each form element is linked to a directive that manages the form model internally. The diagrams below uses the same favorite color example to demonstrate how data flows when an input field's value is changed from the view and then from the model.
In template-driven forms, each form element is linked to a directive that manages the form model internally. The diagrams below use the same favorite color example to demonstrate how data flows when an input field's value is changed from the view and then from the model.
在模板驱动表单中,每个表单元素都链接到一个指令上,该指令负责管理其内部表单模型。下图使用相同的 "喜欢的颜色" 示例来演示当输入字段的值的变更来自视图和来自模板时,数据如何流动。
<figure>
<img src="generated/images/guide/forms-overview/dataflow-td-forms-vtm.png" alt="Template-driven forms view to model data flow" width="100%">
<img src="generated/images/guide/forms-overview/dataflow-td-forms-vtm.png" alt="Template-driven forms data flow - view to model" width="100%">
</figure>
The steps below outline the view to model data flow.
The steps below outline the data flow from view to model when the input value changes from *Red* to *Blue*.
下面这些步骤列出了 "从视图到模型" 数据流的梗概。
1. The end user types "Blue" into the input element.
1. The user types *Blue* into the input element.
最终用户在输入框元素中敲 "Blue"。
1. The input element emits an "input" event with the value "Blue".
1. The input element emits an "input" event with the value *Blue*.
该输入框元素会发出一个 "input" 事件,带着值 "Blue"。
1. The control value accessor attached to the input triggers the `setValue()` method on the `FormControl` instance.
附着在该输入框上的控件值访问器会触发 `FormControl` 实例上的 `setValue()` 方法。
@ -255,16 +256,16 @@ The steps below outline the view to model data flow.
控件值访问器 `ControlValueAccessory` 还会调用 `NgModel.viewToModelUpdate()` 方法,它会发出一个 `ngModelChange` 事件。
1. Because the component template uses two-way data binding for the `favoriteColor`, the `favoriteColor` property in the component
is updated to the value emitted by the `ngModelChange` event ("Blue").
1. Because the component template uses two-way data binding for the `favoriteColor` property, the `favoriteColor` property in the component
is updated to the value emitted by the `ngModelChange` event (*Blue*).
由于该组件模板双向数据绑定到了 `favoriteColor`,组件中的 `favoriteColor` 属性就会修改为 `ngModelChange` 事件所发出的值("Blue")。
<figure>
<img src="generated/images/guide/forms-overview/dataflow-td-forms-mtv.png" alt="Template-driven forms model to view data flow" width="100%">
<img src="generated/images/guide/forms-overview/dataflow-td-forms-mtv.png" alt="Template-driven forms data flow - model to view" width="100%">
</figure>
The steps below outline the model to view data flow.
The steps below outline the data flow from model to view when the `favoriteColor` changes from *Blue* to *Red*.
下面这些步骤列出了从模型到视图的数据流的梗概。
@ -308,7 +309,7 @@ The steps below outline the model to view data flow.
## 表单验证
Validation is an integral part of managing any set of forms. Whether youre checking for required fields or querying an external API for an existing username, Angular provides a set of built-in validators as well as the ability to create custom validators.
Validation is an integral part of managing any set of forms. Whether you're checking for required fields or querying an external API for an existing username, Angular provides a set of built-in validators as well as the ability to create custom validators.
验证是管理任何表单时必备的一部分。无论你是要检查必填项,还是查询外部 API 来检查用户名是否已存在Angular 都会提供一组内置的验证器,以及创建自定义验证器所需的能力。
@ -321,7 +322,7 @@ Validation is an integral part of managing any set of forms. Whether youre ch
**模板驱动表单**和模板**指令**紧密相关,并且必须提供包装了验证函数的自定义验证器指令。
For more on form validation, see the [Form Validation](guide/form-validation) guide.
For more information, see [Form Validation](guide/form-validation).
要了解验证器的更多知识,参见[表单验证](guide/form-validation)。
@ -329,7 +330,7 @@ For more on form validation, see the [Form Validation](guide/form-validation) gu
## 测试
Testing also plays a large part in complex applications and an easier testing strategy is always welcomed. One difference in testing reactive forms and template-driven forms is their reliance on rendering the UI in order to perform assertions based on form control and form field changes. The following examples demonstrate the process of testing forms with reactive and template-driven forms.
Testing plays a large part in complex applications and a simpler testing strategy is useful when validating that your forms function correctly. Reactive forms and template-driven forms have different levels of reliance on rendering the UI to perform assertions based on form control and form field changes. The following examples demonstrate the process of testing forms with reactive and template-driven forms.
测试在复杂的应用程序中也起着重要的作用,并且总是欢迎更容易的测试策略。测试响应式表单和模板驱动表单的差别之一在于它们是否需要渲染 UI 才能基于表单控件和表单字段变化来执行断言。下面的例子演示了使用响应式表单和模板驱动表单时表单的测试过程。
@ -337,22 +338,22 @@ Testing also plays a large part in complex applications and an easier testing st
### 测试响应式表单
Reactive forms provide a relatively easy testing strategy because they provide synchronous access to the form and data models, and they can be tested without rendering the UI. In these set of tests, controls and data are queried and manipulated through the control without interacting with the change detection cycle.
Reactive forms provide a relatively easy testing strategy because they provide synchronous access to the form and data models, and they can be tested without rendering the UI. In these tests, status and data are queried and manipulated through the control without interacting with the change detection cycle.
响应式表单提供了相对简单的测试策略,因为它们能提供对表单和数据模型的同步访问,而且不必渲染 UI 就能测试它们。在这些测试中,控件和数据是通过控件进行查询和操纵的,不需要和变更检测周期打交道。
The following tests use the favorite color components mentioned earlier to verify the view to model and model to view data flows for a reactive form.
The following tests use the favorite color components mentioned earlier to verify the data flows from view to model and model to view for a reactive form.
下面的测试利用前面的 "喜欢的颜色" 组件来验证响应式表单中的 "从视图到模型" 和 "从模型到视图" 数据流。
The following test verifies the view to model data flow:
The following test verifies the data flow from view to model.
下面的测试验证了 "从视图到模型" 数据流
<code-example path="forms-overview/src/app/reactive/favorite-color/favorite-color.component.spec.ts" region="view-to-model" header="Favorite color test - view to model">
</code-example>
The steps performed in the view to model test.
Here are the steps performed in the view to model test.
这个测试中执行的步骤如下。
@ -360,29 +361,28 @@ The steps performed in the view to model test.
查询表单输入框元素的视图,并为测试创建自定义的 "input" 事件
1. Set the new value for the input is set to *Red*, and dispatch the "input" event on the form input element.
1. Set the new value for the input to *Red*, and dispatch the "input" event on the form input element.
把输入的新值设置为 *Red*,并在表单输入元素上调度 "input" 事件。
1. Assert that the `favoriteColor` `FormControl` instance value matches the value from the input.
1. Assert that the component's `favoriteColorControl` value matches the value from the input.
断言 `favoriteColor` 这个 `FormControl` 实例的值与来自输入框的值是匹配的。
The following test verifies the model to view data flow:
The following test verifies the data flow from model to view.
下面的例子验证了 "从模型到视图" 的数据流:
<code-example path="forms-overview/src/app/reactive/favorite-color/favorite-color.component.spec.ts" region="model-to-view" header="Favorite color test - model to view">
</code-example>
The steps performed in the model to view test.
Here are the steps performed in the model to view test.
这个测试中执行的步骤如下。
1. Use the `favoriteColor` `FormControl` instance to set the new value.
1. Use the `favoriteColorControl`, a `FormControl` instance, to set the new value.
使用 `favoriteColor` 这个 `FormControl` 实例来设置新值。
1. Query the view for the form input element.
查询表单中输入框的视图。
@ -395,22 +395,22 @@ The steps performed in the model to view test.
### 测试模板驱动表单
Writing tests with template-driven forms requires more detailed knowledge of the change detection process and how directives run on each cycle to ensure elements are queried, tested, or changed at the correct time.
Writing tests with template-driven forms requires a detailed knowledge of the change detection process and an understanding of how directives run on each cycle to ensure that elements are queried, tested, or changed at the correct time.
使用模板驱动表单编写测试就需要详细了解变更检测过程,以及指令在每个变更检测周期中如何运行,以确保在正确的时间查询、测试或更改元素。
The following tests use the favorite color components mentioned earlier to verify the view to model and model to view data flows for a template-driven form.
The following tests use the favorite color components mentioned earlier to verify the data flows from view to model and model to view for a template-driven form.
下面的测试使用了以前的 "喜欢的颜色" 组件,来验证模板驱动表单的 "从视图到模型" 和 "从模型到视图" 数据流。
The following test verifies the view to model data flow:
The following test verifies the data flow from view to model.
下面的测试验证了 "从视图到模型" 数据流:
<code-example path="forms-overview/src/app/template/favorite-color/favorite-color.component.spec.ts" region="view-to-model" header="Favorite color test - view to model">
</code-example>
The steps performed in the view to model test.
Here are the steps performed in the view to model test.
执行的测试步骤如下:
@ -418,10 +418,9 @@ The steps performed in the view to model test.
查询表单输入元素中的视图,并为测试创建自定义 "input" 事件。
1. Set the new value for the input is set to *Red*, and dispatch the "input" event on the form input element.
1. Set the new value for the input to *Red*, and dispatch the "input" event on the form input element.
把输入框的新值设置为 *Red*,并在表单输入框元素上派发 "input" 事件。
1. Run change detection through the test fixture.
通过测试夹具Fixture来运行变更检测。
@ -430,34 +429,32 @@ The steps performed in the view to model test.
断言该组件 `favoriteColor` 属性的值与来自输入框的值是匹配的。
The following test verifies the model to view data flow:
The following test verifies the data flow from model to view.
下面的测试验证了 "从模型到视图" 的数据流:
<code-example path="forms-overview/src/app/template/favorite-color/favorite-color.component.spec.ts" region="model-to-view" header="Favorite color test - model to view">
</code-example>
The steps performed in the model to view test.
Here are the steps performed in the model to view test.
执行的测试步骤如下:
1. Use the component instance to set the value of `favoriteColor` property.
1. Use the component instance to set the value of the `favoriteColor` property.
使用组件实例来设置 `favoriteColor` 的值。
1. Run change detection through the test fixture.
通过测试夹具Fixture来运行变更检测。
1. Use the `tick()` method to simulate passage of time within the `fakeAsync()` task.
1. Use the `tick()` method to simulate the passage of time within the `fakeAsync()` task.
`fakeAsync()` 任务中使用 `tick()` 方法来模拟时间的流逝。
1. Query the view for the form input element.
查询表单输入框元素的视图。
1. Assert that the input value matches the `favoriteColor` value property in the component instance.
1. Assert that the input value matches the value of the `favoriteColor` property in the component instance.
断言输入框的值与该组件实例的 `favoriteColor` 属性值是匹配的。
@ -465,15 +462,15 @@ The steps performed in the model to view test.
## 可变性
How changes are tracked plays a role in the efficiency of your application.
The change tracking method plays a role in the efficiency of your application.
如何跟踪变更,对于应用的运行效率起着重要作用
追踪变更的方法对于应用的运行效率有着重要影响
- **Reactive forms** keep the data model pure by providing it as an immutable data structure. Each time a change is triggered on the data model, the `FormControl` instance returns a new data model rather than updating the data model directly. This gives you the ability track unique changes to the data model through the control's observable. This allows change detection to be more efficient because it only needs to update on unique changes. It also follows reactive patterns that integrate with observable operators to transform data.
* **Reactive forms** keep the data model pure by providing it as an immutable data structure. Each time a change is triggered on the data model, the `FormControl` instance returns a new data model rather than updating the existing data model. This gives you the ability to track unique changes to the data model through the control's observable. This provides one way for change detection to be more efficient because it only needs to update on unique changes. It also follows reactive patterns that integrate with observable operators to transform data.
**响应式表单**通过将数据模型提供为不可变数据结构来保持数据模型的纯粹性。每当在数据模型上触发更改时,`FormControl` 实例都会返回一个新的数据模型,而不是直接修改原来的。这样能让你通过该控件的可观察对象来跟踪那些具有唯一性的变更。这可以让变更检测更高效,因为它只需要在发生了唯一性变更的时候进行更新。它还遵循与操作符相结合使用的 "响应式" 模式来转换数据。
**响应式表单**通过将数据模型提供为不可变数据结构来保持数据模型的纯粹性。每当在数据模型上触发更改时,`FormControl` 实例都会返回一个新的数据模型,而不是直接修改原来的。这样能让你通过该控件的可观察对象来跟踪那些具有唯一性的变更。这种方式可以让变更检测更高效,因为它只需要在发生了唯一性变更的时候进行更新。它还遵循与操作符相结合使用的 "响应式" 模式来转换数据。
- **Template-driven** forms rely on mutability with two-way data binding to update the data model in the component as changes are made in the template. Because there are no unique changes to track on the data model when using two-way data binding, change detection is less efficient at determining when updates are required.
* **Template-driven** forms rely on mutability with two-way data binding to update the data model in the component as changes are made in the template. Because there are no unique changes to track on the data model when using two-way data binding, change detection is less efficient at determining when updates are required.
**模板驱动表单**依赖于可变性,它使用双向数据绑定,以便在模板中发生变更时修改数据模型。因为在使用双向数据绑定时无法在数据模型中跟踪具有唯一性的变更,因此变更检测机制在要确定何时需要更新时效率较低。
@ -481,11 +478,11 @@ The difference is demonstrated in the examples above using the **favorite color*
以 "喜欢的颜色" 输入框元素为例来看看两者有什么不同:
- With reactive forms, the **`FormControl` instance** always returns a new value when the control's value is updated.
* With reactive forms, the **`FormControl` instance** always returns a new value when the control's value is updated.
对于响应式表单,每当控件值变化时,**`FormControl` 实例**就会返回一个新的值。
- With template-driven forms, the **favorite color property** is always modified to its new value.
* With template-driven forms, the **favorite color property** is always modified to its new value.
对于模板驱动表单,**favoriteColor** 属性总是会修改成它的新值。
@ -497,31 +494,27 @@ If forms are a central part of your application, scalability is very important.
如果表单是应用程序的核心部分,那么可伸缩性就非常重要。能跨组件复用的表单模型是至关重要的。
- **Reactive forms** make creating large scale forms easier by providing access to low-level APIs and synchronous access to the form model.
* **Reactive forms** provide access to low-level APIs and synchronous access to the form model, making creating large-scale forms easier.
**响应式表单**通过提供对底层 API 的访问和对表单模型的同步访问,可以轻松地创建大型表单
**响应式表单**通过提供对底层 API 的访问和对表单模型的同步访问,让创建大型表单更轻松
- **Template-driven** forms focus on simple scenarios, are not as reusable, abstract away the low-level APIs and access to the form model is provided asynchronously. The abstraction with template-driven forms surfaces in testing also, where testing reactive forms requires less setup and no dependence on the change detection cycle when updating and validating the form and data models during testing.
* **Template-driven** forms focus on simple scenarios, are not as reusable, abstract away the low-level APIs, and provide asynchronous access to the form model. The abstraction with template-driven forms also surfaces in testing, where testing reactive forms requires less setup and no dependence on the change detection cycle when updating and validating the form and data models during testing.
**模板驱动表单**专注于简单的场景,它不可重用、对底层 API 进行抽象,而且对表单模型的访问是异步的。
在测试过程中,模板驱动表单的抽象也会参与测试。而测试响应式表单需要更少的准备代码,并且当测试期间修改和验证表单模型与数据模型时,不依赖变更检测周期。
## Final Thoughts
## Final thoughts
## 最后的想法
## 最后的思考
Choosing a strategy begins with understanding the strengths and weaknesses of the options presented. Low-level API and form model access, predictability, mutability, straightforward validation and testing strategies, and scalability are all important consideration in choosing the infrastructure you use when building your forms in Angular. Template-driven forms are similar to patterns in AngularJS, but they have limitations given the criteria of many modern, large-scale Angular apps. Reactive forms integrate with reactive patterns already present in other areas of the Angular architecture, and complement those requirements well. Those limitations are alleviated with reactive forms.
Choosing a strategy begins with understanding the strengths and weaknesses of the options presented. Low-level API and form model access, predictability, mutability, straightforward validation and testing strategies, and scalability are all important considerations in choosing the infrastructure you use to build your forms in Angular. Template-driven forms are similar to patterns in AngularJS, but they have limitations given the criteria of many modern, large-scale Angular apps. Reactive forms minimize these limitations. Reactive forms integrate with reactive patterns already present in other areas of the Angular architecture, and complement those requirements well.
选择一项策略首先要了解所提供选项的优缺点。当选择在 Angular 中构建表单要用哪种基础设施时,底层 API 访问、表单模型访问、可预测性、可变性、直截了当的验证方式和测试策略以及可伸缩性都是重要的考虑因素。
模板驱动表单和 AngularJS 中的传统模式相似,但它们具有局限性。响应式表单已经和 Angular 架构其它区域中存在的响应式模式相整合,并很好地弥补了这些需求,这些限制通过响应式表单技术得到了缓解
要选择一项策略就要先了解所提供选项的优缺点。当决定在 Angular 中构建表单要选择哪种基础设施时,底层 API 访问、表单模型访问、可预测性、可变性、直截了当的验证方式和测试策略以及可伸缩性都是重要的考虑因素。
模板驱动表单和 AngularJS 中的传统模式相似,但它们具有局限性。响应式表单已经和 Angular 架构的其它部分存在的响应式模式相整合,并很好地弥补了这些需求。
## Next Steps
## Next steps
## 下一步
The following guides are the next steps in the learning process.
下一步你可以学习如下章节。
后续步骤
To learn more about reactive forms, see the following guides:
@ -535,7 +528,7 @@ To learn more about reactive forms, see the following guides:
[表单验证](guide/form-validation#reactive-form-validation)
* [Dynamic forms](guide/dynamic-form)
* [Dynamic Forms](guide/dynamic-form)
[动态表单](guide/dynamic-form)
@ -543,10 +536,7 @@ To learn more about template-driven forms, see the following guides:
要进一步了解模板驱动表单,参见下列章节:
* [Template-driven Forms](guide/forms)
* [Template-driven Forms](guide/forms#template-driven-forms)
[模板驱动表单](guide/forms)
* [Form Validation](guide/form-validation#template-driven-validation)
[表单验证](guide/form-validation#template-driven-validation)

View File

@ -560,12 +560,47 @@ Within Angular, use [NgModules](guide/glossary#ngmodule) to make public parts av
{@a F}
{@a form-control}
## form control
<!--TODO: translate-->
A instance of `FormControl`, which is a fundamental building block for Angular forms. Together with `FormGroup` and `FormArray`, tracks the value, validation, and status of a form input element.
Read more forms in the [Introduction to forms in Angular](guide/forms-overview).
{@a form-model}
## form model
The "source of truth" for the value and validation status of a form input element at a given point in time. When using [reactive forms](guide/glossary#reactive-forms), the form model is created explicitly in the component class. When using [template-driven forms](guide/glossary#template-driven-forms), the form model is implicitly created by directives.
Learn more about reactive and template-driven forms in the [Introduction to forms in Angular](guide/forms-overview).
{@a form-validation}
## form validation
A check that runs when form values change and reports whether the given values are correct and complete, according to the defined constraints. Reactive forms apply [validator functions](guide/form-validation#adding-to-reactive-forms). Template-driven forms use [validator directives](guide/form-validation#adding-to-template-driven-forms).
To learn more, see [Form Validation](guide/form-validation).
{@a G}
{@a H}
{@a I}
{@a immutability}
## immutability
The ability to alter the state of a value after its creation. [Reactive forms](guide/glossary#reactive-forms) perform immutable changes in that
each change to the data model produces a new data model rather than modifying the existing one. [Template-driven forms](guide/glossary#template-driven-forms) perform mutable changes with `NgModel` and [two-way data binding](guide/glossary#data-binding) to modify the existing data model in place.
{@a injectable}
## injectable
@ -976,29 +1011,29 @@ The alternative is a [template-driven form](guide/glossary#template-driven-forms
通过组件中代码构建 Angular 表单的一个框架。
另一种技术是[模板驱动表单](guide/glossary#template-driven-forms)
When building reactive forms:
When using reactive forms:
构建响应式表单时:
* The "source of truth" is the component. The validation is defined using code in the component.
* The "source of truth", the form model, is defined in the component class.
* Validation is set up through validation functions rather than valdation directives.
组件是“真理之源”。表单验证在组件代码中定义。
* Each control is explicitly created in the component class with `new FormControl()` or with `FormBuilder`.
* Each control is explicitly created in the component class by creating a `FormControl` instance manually or with `FormBuilder`.
在组件类中,使用 `new FormControl()` 或者 `FormBuilder` 显性地创建每个控件。
* The template input elements do *not* use `ngModel`.
模板中的 `input` 元素**不**使用 `ngModel`
* The associated Angular directives are prefixed with `Form`, such as `FormGroup()`, `FormControl()`, and `FormControlName()`.
* The associated Angular directives are prefixed with `form`, such as `formControl`, `formGroup`, and `formControlName`.
相关联的 Angular 指令全部以 `Form` 开头,例如 `FormGroup()`、`FormControl()` 和 `FormControlName()`
Reactive forms are powerful, flexible, and a good choice for more complex data-entry form scenarios, such as dynamic generation of form controls.
The alternative is a template-driven form. For an introduction and comparison of both forms approaches, see [Introduction to Angular Forms](guide/forms-overview).
动态表单非常强大、灵活,它在复杂数据输入的场景下尤其好用,例如动态的生成表单控制器
另一种方式是模板驱动表单。模板驱动表单的简介和这两种方式的比较,参见 [Angular 表单简介](guide/forms-overview)
{@a router}
{@a router-module}
@ -1194,7 +1229,7 @@ The alternative format uses the [reactive forms](guide/glossary#reactive-forms)
一种在视图中使用 HTML 表单和输入类元素构建 Angular 表单的格式。
它的替代方案是[响应式表单](guide/glossary#reactive-forms)框架。
When building template-driven forms:
When using template-driven forms:
当构建模板驱动表单时:
@ -1214,13 +1249,9 @@ When building template-driven forms:
相关的 Angular 指令都带有 `ng` 前缀,例如 `ngForm`、`ngModel` 和 `ngModelGroup`
Template-driven forms are convenient, quick, and simple. They are a good choice for many basic data-entry form scenarios.
The alternative is a reactive form. For an introduction and comparison of both forms approaches, see [Introduction to Angular Forms](guide/forms-overview).
模板驱动表单便捷、快速、简单,是很多基础型数据输入表单的最佳选择。
Read about how to build template-driven forms in [Forms](guide/forms).
要了解如何构建模板驱动表单的更多信息,参见[表单](guide/forms)页。
另一种方式是响应式表单。响应式表单的简介和两种方式的比较参见 [Angular 表单简介](guide/forms-overview)。
{@a template-expression}

View File

@ -1100,9 +1100,9 @@ the JIT compiler or the AOT compiler.
你如何提供这些信息取决于你使用的是JIT即时编译器还是AOT预先编译器。
* With [AOT](guide/i18n#merge-aot), you pass the information as a configuration
* With [AOT](guide/i18n#merge-aot), you pass the information as configuration settings.
使用[AOT](guide/i18n#merge-aot)时,用配置项传入这些信息。
使用[AOT](guide/i18n#merge-aot)时,用配置项传入这些配置信息。
* With [JIT](guide/i18n#merge-jit), you provide the information at bootstrap time.

View File

@ -1,170 +1,153 @@
# Npm Packages
# Workspace npm dependencies
# Npm 包
The [**Angular CLI**](https://cli.angular.io/), Angular applications, and Angular itself depend upon features and functionality provided by libraries that are available as [**npm**](https://docs.npmjs.com/) packages.
The Angular Framework, Angular CLI, and components used by Angular applications are packaged as [npm packages](https://docs.npmjs.com/getting-started/what-is-npm "What is npm?") and distributed via the [npm registry](https://docs.npmjs.com/).
[**Angular CLI**](https://cli.angular.io/)、Angular 应用程序以及 Angular 本身都依赖于很多第三方包(包括 Angular 自己)提供的特性和功能。这些都是 [**npm**](https://docs.npmjs.com/) 包
Angular 框架、[**Angular CLI**](https://cli.angular.io/)、Angular 应用程序所用到的组件都打包成 [npm packages](https://docs.npmjs.com/getting-started/what-is-npm "What is npm?"),并通过 [npm registry](https://docs.npmjs.com/) 进行分发
You can download and install these npm packages with the [**npm client**](https://docs.npmjs.com/cli/install), which runs as a Node.js® application.
You can download and install these npm packages by using the [npm CLI client](https://docs.npmjs.com/cli/install), which is installed with and runs as a [Node.js®](https://nodejs.org "Nodejs.org") application. By default, the Angular CLI uses the npm client.
你可以使用 [**npm**](https://docs.npmjs.com/cli/install) 来安装这些 npm 包npm 命令也是一个 Node.js® 应用
你可以使用 [npm CLI client](https://docs.npmjs.com/cli/install) 来下载并安装这些 npm 包,它通过 [Node.js®](https://nodejs.org "Nodejs.org") 安装并运行。默认情况下Angular CLI 会使用 npm 客户端
The [**yarn client**](https://yarnpkg.com/en/) is a popular alternative for downloading and installing npm packages.
The Angular CLI uses `yarn` by default to install npm packages when you create a new project.
Alternatively, you can use the [yarn client](https://yarnpkg.com/) for downloading and installing npm packages.
[**yarn**](https://yarnpkg.com/en/) 是另一个下载和安装 npm 包的工具。
当创建新项目时Angular CLI 默认使用 `yarn` 来安装 npm 包。
另外,你还可以使用 [**yarn** 客户端](https://yarnpkg.com/en/) 来下载并安装 npm 包。
<div class="alert is-helpful">
Node.js and npm are essential to Angular development.
See [Getting Started](guide/quickstart#prerequisites) for information about the required versions and installation of Node.js and npm.
Node.js 和 npm 是做 Angular 开发的基础
参见[快速起步](guide/quickstart#prerequisites),以了解所需的 Node.js 和 npm 版本
[Get them now](https://docs.npmjs.com/getting-started/installing-node "Installing Node.js and updating npm")
if they're not already installed on your machine.
If you already have projects running on your machine that use other versions of Node.js and npm, consider using [nvm](https://github.com/creationix/nvm) to manage the multiple versions of Node.js and npm.
如果你的电脑上还没有装过,请 [立即获取它们](https://docs.npmjs.com/getting-started/installing-node "Installing Node.js and updating npm")
**Verify that you are running Node.js `v8.x` or higher and npm `5.x` or higher**
by running the commands `node -v` and `npm -v` in a terminal/console window.
Older versions produce errors.
在终端/控制器窗口运行命令 `node -v``npm -v`,来**确认你运行的 node 是 `v8.x` 或更高npm 为 `5.x` 或更高。**
老版本会产生错误。
Consider using [nvm](https://github.com/creationix/nvm) for managing multiple
versions of Node.js and npm. You may need [nvm](https://github.com/creationix/nvm) if
you already have projects running on your machine that use other versions of Node.js and npm.
建议使用[nvm](https://github.com/creationix/nvm)来管理 node 和 npm 的多个版本。如果你机器上已经有某些项目运行了 Node.js 和 npm 的其它版本,你就会需要[nvm](https://github.com/creationix/nvm)了。
如果你的电脑上已经有了使用其它 Node.js 和 npm 版本的项目,可考虑使用 [nvm](https://github.com/creationix/nvm) 来管理 Node.js 和 npm 的多个版本。
</div>
## _package.json_
Both `npm` and `yarn` install packages that are identified in a [**package.json**](https://docs.npmjs.com/files/package.json) file.
## `package.json`
无论是 `npm` 还是 `yarn`,所安装的包都记录在 [**package.json**](https://docs.npmjs.com/files/package.json) 文件中。
Both `npm` and `yarn` install the packages that are identified in a [`package.json`](https://docs.npmjs.com/files/package.json) file.
The CLI `ng new` command creates a default `package.json` file for your project.
This `package.json` specifies _a starter set of packages_ that work well together and
jointly support many common application scenarios.
无论使用 `npm` 还是 `yarn` 安装的包,都会记录在 [`package.json`](https://docs.npmjs.com/files/package.json) 文件中。
CLI 的 `ng new` 命令会给项目创建一个默认的 `package.json` 文件。
这个 `package.json` 中带有一些起步包,这些包可以很好地协同,并可用于大量常见的应用场景。
The CLI command `ng new` creates a `package.json` file when it creates the new workspace.
This `package.json` is used by all projects in the workspace, including the initial app project that is created by the CLI when it creates the workspace.
You will add packages to `package.json` as your application evolves.
You may even remove some.
CLI 的 `ng new` 命令会在创建新的工作空间的同时创建一个 `package.json`
这个 `package.json` 用于此工作空间中的所有项目,包括由 CLI 在创建工作空间时创建的那个初始项目。
随着应用的成长,你还会往 `package.json` 中添加更多包,甚至可能会移除一些。
Initially, this `package.json` includes _a starter set of packages_, some of which are required by Angular and others that support common application scenarios.
You add packages to `package.json` as your application evolves.
You may even remove some.
This guide focuses on the most important packages in the starter set.
最初,这个 `package.json` 包括*一组初始包*,其中有些是 Angular 自身需要的,另一些是用来支持一些常见的应用场景。
随着应用的演化,你可能会往 `package.json` 中添加甚至移除一些包。
本指南中会集中讲解这些初始包中的重点部分。
The `package.json` is organized into two groups of packages:
#### *dependencies* and *devDependencies*
`package.json` 文件中的包被分成了两组:
#### *dependencies* 和 *devDependencies*
* [Dependencies](guide/npm-packages#dependencies) are essential to *running* applications.
The `package.json` includes two sets of packages,
[dependencies](guide/npm-packages#dependencies) and [devDependencies](guide/npm-packages#dev-dependencies).
[dependencies](guide/npm-packages#dependencies) 是*运行*应用的基础。
`package.json` 包括两组包:[dependencies](guide/npm-packages#dependencies) 和 [devDependencies](guide/npm-packages#dev-dependencies)
* [DevDependencies](guide/npm-packages#dev-dependencies) are only necessary to *develop* applications.
The *dependencies* are essential to *running* the application.
The *devDependencies* are only necessary to *develop* the application.
[devDependencies](guide/npm-packages#dev-dependencies) 只有在*开发*应用时才会用到。
<div class="alert is-helpful">
**Library developers:** By default, the CLI command [`ng generate library`](cli/generate) creates a `package.json` for the new library. That `package.json` is used when publishing the library to npm.
For more information, see the CLI wiki page [Library Support](https://github.com/angular/angular-cli/wiki/stories-create-library).
**代码库开发者:**默认情况下CLI 命令 [`ng generate library`](cli/generate) 会为新的代码库项目创建一个 `package.json`。这个 `package.json` 会在把该代码库发布到 npm 时用到。
要了解更多信息,参见 CLI 的 wiki 页面[代码库支持](https://github.com/angular/angular-cli/wiki/stories-create-library)。
</div>
**dependencies** 是**运行**应用的基础,而 **devDependencies** 只有在**开发**应用时才会用到。
{@a dependencies}
## Dependencies
## *Dependencies*
The packages listed in the `dependencies` section of `package.json` are essential to *running* applications.
The `dependencies` section of `package.json` contains:
应用程序的 `package.json` 文件中,`dependencies` 下包括:
* **Angular packages**: Angular core and optional modules; their package names begin `@angular/`.
* [**Angular packages**](#angular-packages): Angular core and optional modules; their package names begin `@angular/`.
**Angular 包**Angular 的核心和可选模块,它们的包名以 `@angular/` 开头。
*[*Angular 包**Angular 的核心和可选模块,它们的包名以 `@angular/` 开头。
* **Support packages**: 3rd party libraries that must be present for Angular apps to run.
* **Support packages**](#support-packages): 3rd party libraries that must be present for Angular apps to run.
**支持包**:那些 Angular 应用运行时必需的第三方库。
*[*支持包**:那些 Angular 应用运行时必需的第三方库。
* **Polyfill packages**: Polyfills plug gaps in a browser's JavaScript implementation.
* **Polyfill packages**](#polyfills): Polyfills plug gaps in a browser's JavaScript implementation.
**腻子脚本**:腻子脚本负责抹平不同浏览器的 JavaScript 实现之间的差异。
### Angular Packages
To add a new dependency, use the [`ng add`](cli/add) command.
要想添加新的依赖,请使用 [`ng add`](cli/add) 命令。
{@a angular-packages}
### Angular packages
### Angular 包
**@angular/animations**: Angular's animations library makes it easy to define and apply animation effects such as page and list transitions.
Read about it in the [Animations guide](guide/animations).
The following Angular packages are included as dependencies in the default `package.json` file for a new Angular workspace.
For a complete list of Angular packages, see the [API reference](http://angular.io/api?type=package).
**@angular/animations**Angular 的动画库,它能让你更容易定义和使用动画效果,比如页面和列表的转场动画。要了解更多,请参见 [动画指南](guide/animations)。
新的 Angular 工作空间的 `package.json` 文件中默认包含下列 Angular 包。
要了解 Angular 包的完整列表,参见 [API 参考手册](http://angular.io/api?type=package)。
**@angular/common**: The commonly needed services, pipes, and directives provided by the Angular team.
The [`HttpClientModule`](guide/http) is also here, in the '@angular/common/http' subfolder.
**@angular/common**:由 Angular 开发组提供的常用服务、管道和指令。
Package name | Description
---------------------------------------- | --------------------------------------------------
[**@angular/animations**](api/animations) | Angular's animations library makes it easy to define and apply animation effects such as page and list transitions. For more information, see the [Animations guide](guide/animations).
[**@angular/common**](api/common) | The commonly-needed services, pipes, and directives provided by the Angular team. The [`HttpClientModule`](api/common/http/HttpClientModule) is also here, in the [`@angular/common/http`](api/common/http) subfolder. For more information, see the [HttpClient guide](guide/http).
**@angular/compiler** | Angular's template compiler. It understands templates and can convert them to code that makes the application run and render. Typically you dont interact with the compiler directly; rather, you use it indirectly via `platform-browser-dynamic` when JIT compiling in the browser. For more information, see the [Ahead-of-time Compilation guide](guide/aot-compiler).
[**@angular/common**:由 Angular 开发组提供的常用服务、管道和指令。
[`HttpClientModule`](guide/http)也在这里,位于'@angular/common/http'子目录下。
**@angular/core**: Critical runtime parts of the framework needed by every application.
Includes all metadata decorators, `Component`, `Directive`, dependency injection, and the component lifecycle hooks.
**@angular/core**](api/core) | Critical runtime parts of the framework that are needed by every application. Includes all metadata decorators, `Component`, `Directive`, dependency injection, and the component lifecycle hooks.
[**@angular/forms**](api/forms) | Support for both [template-driven](guide/forms) and [reactive forms](guide/reactive-forms). For information about choosing the best forms approach for your app, see [Introduction to forms](guide/forms-overview).
[**@angular/http**](api/http) | Angular's legacy HTTP client, which was deprecated in version 5.0 in favor of [@angular/common/http](api/common/http).
[**@angular/<br />platform&#8209;browser**](api/platform-browser) | Everything DOM and browser related, especially the pieces that help render into the DOM. This package also includes the `bootstrapModuleFactory()` method for bootstrapping applications for production builds that pre-compile with [AOT](guide/aot-compiler).
[**@angular/<br />platform&#8209;browser&#8209;dynamic**](api/platform-browser-dynamic) | Includes [providers](api/core/Provider) and methods to compile and run the app on the client using the [JIT compiler](guide/aot-compiler).
[**@angular/router**](api/router) | The router module navigates among your app pages when the browser URL changes. For more information, see [Routing and Navigation](guide/router).
**@angular/core**:本框架的每个应用都需要的关键运行部件。包括元数据装饰器,如 `Component``Directive`、依赖注入以及组件生命周期钩子。
**@angular/compiler**: Angular's *Template Compiler*.
It understands templates and can convert them to code that makes the application run and render.
Typically you dont interact with the compiler directly; rather, you use it indirectly via `platform-browser-dynamic` when [JIT compiling](guide/aot-compiler) in the browser.
{@a support-packages}
### Support packages
**@angular/compiler**Angular 的*模板编译器*。
它会理解模板,并且把模板转化成代码,以供应用程序运行和渲染。
开发人员通常不会直接跟这个编译器打交道,而是当在浏览器中使用 [JIT 编译](guide/aot-compiler) 时通过 `platform-browser-dynamic` 间接使用它。
### 支持包
**@angular/forms**: support for both [template-driven](guide/forms) and [reactive forms](guide/reactive-forms).
The following support packages are included as dependencies in the default `package.json` file for a new Angular workspace.
**@angular/forms**:支持 [template-driven](guide/forms) 和 [reactive forms](guide/reactive-forms)
新的 Angular 工作空间的 `package.json` 文件中默认包含下列支持包
**@angular/http**: Angular's old, deprecated, HTTP client.
**@angular/http**Angular 的老的、已废弃的 HTTP 客户端库。
**@angular/platform-browser**: Everything DOM and browser related, especially
the pieces that help render into the DOM.
This package also includes the `bootstrapModuleFactory()` method
for bootstrapping applications for production builds that pre-compile with [AOT](guide/aot-compiler).
**@angular/platform-browser**:与 DOM 和浏览器相关的每样东西,特别是帮助往 DOM 中渲染的那部分。
这个包还包含 `bootstrapModuleFactory()` 方法,用来引导那些在产品构建时要用 [AOT](guide/aot-compiler) 进行编译的应用程序。
**@angular/platform-browser-dynamic**: Includes [Providers](api/core/Provider)
and methods to compile and run the app on the client
using the [JIT compiler](guide/aot-compiler).
**@angular/platform-browser-dynamic** 为应用程序提供一些[提供商](api/core/Provider)和方法,以便在客户端使用 [JIT 编译器](guide/aot-compiler)运行本应用。
Package name | Description
---------------------------------------- | --------------------------------------------------
[**rxjs**](https://github.com/ReactiveX/rxjs) | Many Angular APIs return [_observables_](guide/glossary#observable). RxJS is an implementation of the proposed [Observables specification](https://github.com/tc39/proposal-observable) currently before the [TC39](https://www.ecma-international.org/memento/tc39-m.htm) committee, which determines standards for the JavaScript language.
[**zone.js**](https://github.com/angular/zone.js) | Angular relies on zone.js to run Angular's change detection processes when native JavaScript operations raise events. Zone.js is an implementation of a [specification](https://gist.github.com/mhevery/63fdcdf7c65886051d55) currently before the [TC39](http://www.ecma-international.org/memento/TC39.htm) committee that determines standards for the JavaScript language.
**@angular/router**: The [router module](/guide/router) navigates among your app pages when the browser URL changes.
**@angular/router**: [router 模块](/guide/router) 可以在浏览器的 URL 变化时在应用的页面之间导航。
**@angular/upgrade**: Set of utilities for upgrading AngularJS applications to Angular.
**@angular/upgrade**: 一组用来把 AngularJS 应用升级到 Angular 的工具。
{@a polyfills}
### Polyfill packages
### 腻子脚本包
Many browsers lack native support for some features in the latest HTML standards,
features that Angular requires.
"[Polyfills](https://en.wikipedia.org/wiki/Polyfill)" can emulate the missing features.
[_Polyfills_](https://en.wikipedia.org/wiki/Polyfill) can emulate the missing features.
The [Browser Support](guide/browser-support) guide explains which browsers need polyfills and
how you can add them.
@ -172,112 +155,63 @@ how you can add them.
[腻子脚本](https://en.wikipedia.org/wiki/Polyfill) 可以模拟这些缺失的特性。
[浏览器支持](guide/browser-support)一章中解释了哪些浏览器分别需要哪些腻子脚本,以及如何添加它们。
The default `package.json` installs the **[core-js](https://github.com/zloirock/core-js)** package
The `package.json` for a new Angular workspace installs the [core-js](https://github.com/zloirock/core-js) package,
which polyfills missing features for several popular browser.
默认的 `package.json` 会安装 **[core-js](https://github.com/zloirock/core-js)** 包,它会弥补很多常用浏览器缺失的特性。
### Support packages
### 支持包
**[rxjs](https://github.com/benlesh/RxJS)**: Many Angular APIs return _observables_. RxJS is an implementation of the proposed [Observables specification](https://github.com/zenparsing/es-observable) currently before the
[TC39](http://www.ecma-international.org/memento/TC39.htm) committee that determines standards for the JavaScript language.
**[rxjs](https://github.com/benlesh/RxJS)**:很多 Angular API 都会返回**可观察对象Observable**。RxJS 是个对[Observables 规范](https://github.com/zenparsing/es-observable)的当前实现。[TC39](http://www.ecma-international.org/memento/TC39.htm)委员会将来会决定它是否成为 JavaScript 语言标准的一部分。
**[zone.js](https://github.com/angular/zone.js)**: Angular relies on zone.js to run Angular's change detection processes when native JavaScript operations raise events. Zone.js is an implementation of a [specification](https://gist.github.com/mhevery/63fdcdf7c65886051d55) currently before the
[TC39](http://www.ecma-international.org/memento/TC39.htm) committee that determines standards for the JavaScript language.
**[zone.js](https://github.com/angular/zone.js)**Angular 依赖 zone.js以便在原生 JavaScript 操作触发事件时运行 Angular 的变更检测过程。Zone.js 是对 [这个规范](https://gist.github.com/mhevery/63fdcdf7c65886051d55) 的当前实现。[TC39](http://www.ecma-international.org/memento/TC39.htm)委员会将来会决定它是否成为 JavaScript 语言标准的一部分。
{@a dev-dependencies}
## *DevDependencies*
## DevDependencies
The packages listed in the *devDependencies* section of the `package.json` help you develop the application on your local machine.
The packages listed in the `devDependencies` section of `package.json` help you develop the application on your local machine. You don't deploy them with the production application.
`package.json`*devDependencies* 区列出的这些包可以帮助你在本机开发应用。
你不必把它们部署到生产环境中。
You don't deploy them with the production application although there is no harm in doing so.
To add a new `devDependency`, use either one of the following commands:
你不必在生产环境的应用中部署它们,当然,就算部署了也没什么坏处。
要想添加新的 `devDependency`,请使用下列命令之一:
**[@angular/cli](https://github.com/angular/angular-cli/)**: The Angular CLI tools.
<code-example language="sh" class="code-shell">
npm install --dev &lt;package-name&gt;
</code-example>
**[@angular/cli](https://github.com/angular/angular-cli/)**Angular 的命令行工具。
<code-example language="sh" class="code-shell">
yarn add --dev &lt;package-name&gt;
</code-example>
**[@angular/compiler-cli](https://github.com/angular/angular/blob/master/packages/compiler-cli/README.md)**: The Angular compiler, which is invoked by the Angular CLI's `build` and `serve` commands.
The following `devDependencies` are provided in the default `package.json` file for a new Angular workspace.
**[@angular/compiler-cli](https://github.com/angular/angular/blob/master/packages/compiler-cli/README.md)**Angular 的编译器,它会被 Angular CLI 的 `build``serve` 命令调用。
新 Angular 工作空间的默认 `package.json` 中包含下列 `devDependencies`
**[@angular/language-service](https://github.com/angular/angular-cli/)**: The Angular language service analyzes component templates and provides type and error information that TypeScript-aware editors can use to improve the developer's experience.
For example, see the [Angular language service extension for VS Code](https://marketplace.visualstudio.com/items?itemName=Angular.ng-template)
Package name | Description
---------------------------------------- | -----------------------------------
[**@angular&#8209;devkit/<br />build&#8209;angular**](https://github.com/angular/angular-cli/) | The Angular build tools.
[**@angular/cli**](https://github.com/angular/angular-cli/) | The Angular CLI tools.
**@angular/<br />compiler&#8209;cli** | The Angular compiler, which is invoked by the Angular CLI's `ng build` and `ng serve` commands.
**@angular/<br />language&#8209;service** | The [Angular language service](guide/language-service) analyzes component templates and provides type and error information that TypeScript-aware editors can use to improve the developer's experience. For example, see the [Angular language service extension for VS Code](https://marketplace.visualstudio.com/items?itemName=Angular.ng-template).
**@types/... ** | TypeScript definition files for 3rd party libraries such as Jasmine and Node.js.
[**codelyzer**](https://www.npmjs.com/package/codelyzer) | A linter for Angular apps whose rules conform to the Angular [style guide](guide/styleguide).
**jasmine/... ** | Packages to support the [Jasmine](https://jasmine.github.io/) test library.
**karma/... ** | Packages to support the [karma](https://www.npmjs.com/package/karma) test runner.
[**protractor**](https://www.npmjs.com/package/protractor) | An end-to-end (e2e) framework for Angular apps. Built on top of [WebDriverJS](https://github.com/SeleniumHQ/selenium/wiki/WebDriverJs).
[**ts-node**](https://www.npmjs.com/package/ts-node) | TypeScript execution environment and REPL for Node.js.
[**tslint**](https://www.npmjs.com/package/tslint) | A static analysis tool that checks TypeScript code for readability, maintainability, and functionality errors.
[**typescript**](https://www.npmjs.com/package/typescript) | The TypeScript language server, including the *tsc* TypeScript compiler.
**[@angular/language-service](https://github.com/angular/angular-cli/)**Angular 的语言服务会分析组件模板,并且提供类型信息和错误信息,那些支持 TypeScript 的编辑机器可以使用它们来提升开发体验。比如这个:[VS Code 的 Angular 语言服务扩展包](https://marketplace.visualstudio.com/items?itemName=Angular.ng-template)
## Related information
**@types/... **: TypeScript definition files for 3rd party libraries such as Jasmine and Node.js.
## 相关信息
**@types/... **:第三方库(比如 Jasmine 和 Node.js的 TypeScript 类型定义文件。
For information about how the Angular CLI handles packages see the following guides:
要了解 Angular CLI 如何处理包的更多信息,请参见下列章节:
* [Building and serving](guide/build) describes how packages come together to create a development build.
[Building and serving](guide/build) 描述了这些包如何协作,以进行开发期构建。
* [Deployment](guide/deployment) describes how packages come together to create a production build.
**[codelyzer](https://www.npmjs.com/package/codelyzer)**: A linter for Angular apps whose rules conform to the Angular [style guide](guide/styleguide).
**[codelyzer](https://www.npmjs.com/package/codelyzer)**:专用于 Angular 应用的 linter它的规则适用于 Angular 的[风格指南](guide/styleguide)。
**jasmine/... **: packages to support the [Jasmine](https://jasmine.github.io/) test library.
**jasmine/... **[Jasmine](https://jasmine.github.io/) 测试库的支持包。
**karma/... **: packages to support the [karma](https://www.npmjs.com/package/karma) test runner.
**karma/... **[karma](https://www.npmjs.com/package/karma) 测试运行器的支持包。
**[protractor](https://www.npmjs.com/package/protractor)**: an end-to-end (e2e) framework for Angular apps.
Built on top of [WebDriverJS](https://github.com/SeleniumHQ/selenium/wiki/WebDriverJs).
**[protractor](https://www.npmjs.com/package/protractor)**:适用于 Angular 应用的端到端e2e框架。基于 [WebDriverJS](https://github.com/SeleniumHQ/selenium/wiki/WebDriverJs) 构建。
**[ts-node](https://www.npmjs.com/package/ts-node)**: TypeScript execution environment and REPL for Node.js.
**[ts-node](https://www.npmjs.com/package/ts-node)**TypeScript 的运行环境以及在 Node.js 环境下用的 REPL。
**[tslint](https://www.npmjs.com/package/tslint)**: a static analysis tool that checks TypeScript code for readability, maintainability, and functionality errors.
**[tslint](https://www.npmjs.com/package/tslint)**:一个静态分析器,用来检查 TypeScript 代码的可读性、可维护性和功能方面的错误。
**[typescript](https://www.npmjs.com/package/typescript)**:
the TypeScript language server, including the *tsc* TypeScript compiler.
**[typescript](https://www.npmjs.com/package/typescript)**TypeScript 语言服务,包括 TypeScript 编译器 *tsc*
## So many packages! So many files!
## 那么多包!那么多文件!
The default `package.json` installs more packages than you'll need for your project.
默认的 `package.json` 所安装的包比项目实际需要的多。
A given package may contain tens, hundreds, even thousands of files,
all of them in your local machine's `node_modules` directory.
The sheer volume of files is intimidating,
某个指定的包可能包含十个、上百个甚至上千个文件,它们都位于本机的 `node_modules` 目录下。简直令人生畏。
You can remove packages that you don't need but how can you be sure that you won't need it?
As a practical matter, it's better to install a package you don't need than worry about it.
Extra packages and package files on your local development machine are harmless.
你可以移除这些不需要的包,不过你怎么知道哪些是不需要的呢?
实际上,安装不需要的包好过担心缺少某个包。
在你本机开发环境下存在无用的包和文件并没有害处。
By default the Angular CLI build process bundles into a single file just the few "vendor" library files that your application actually needs.
The browser downloads this bundle, not the original package files.
默认情况下Angular CLI 的构建过程只会把应用程序中实际用到的那些第三方库文件打包到结果中。
浏览器要下载的是这个包,而不是原始的包文件。
See the [Deployment](guide/deployment) to learn more.
参见[部署](guide/deployment)一章了解详情。
[Deployment](guide/deployment) 中描述了这些包如何协作,以创建一个生产环境构建。

View File

@ -121,9 +121,9 @@ The following table contains our current target release dates for the next two m
下表中包含下面两个 Angular 主版本的目标发布日期:
<t>Date</t><t>日期</t> | <t>Stable Release</t><t>稳定版</t> | <t>Compatibility</t><t>兼容性</t>
---------------------- | -------------- | ----------------
<t>September/October 2018</t><t>2018-09/10</t> | 7.0.0 | ^6.0.0
<t>March/April 2019</t><t>2019-03/04</t> | 8.0.0 | ^7.0.0
---------------------- | -------------- | -------------
March/April 2019 | 8.0.0 | ^7.0.0
September/October 2019 | 9.0.0 | ^8.0.0
Compatibility note: The primary goal of the backward compatibility promise is to ensure that changes in the core framework and tooling don't break the existing ecosystem of components and applications and don't put undue upgrade/migration burden on Angular application and component authors.
@ -131,7 +131,7 @@ The following table contains our current target release dates for the next two m
{@a lts}
{@a support}
## Support policy
## Support policy and schedule
## 支持策略
@ -139,61 +139,27 @@ All of our major releases are supported for 18 months.
所有主版本的支持周期都是 18 个月。
* 6 months of active support, during which regularly-scheduled updates and patches are released, as described above in [Release frequency](#frequency "Release frequency").
* 6 months of *active support*, during which regularly-scheduled updates and patches are released.
6 个月的活跃支持,在此期间我们会定期发布更新和补丁,正如前面的[发布频率](#frequency "Release frequency")中所说的。
6 个月的*活跃支持*,在此期间我们会定期发布更新和补丁
* 12 months of long-term support(LTS). During the LTS period, only critical fixes and security patches will be released.
* 12 months of *long-term support (LTS)*, during which only critical fixes and security patches are released.
12 个月的长期支持LTS在 LTS 期间,只会发布关键性修复和安全补丁。
12 个月的*长期支持LTS*在 LTS 期间,只会发布关键性修复和安全补丁。
The following table provides the support status and key dates for Angular version 4.0.0 and higher.
The following table provides the support status and key dates for Angular version 5.0.0 and higher.
下表中提供了 Angular 4.0.0 以上的支持状态和一些关键时间点。
下表中提供了 Angular 5.0.0 以上的支持状态和一些关键时间点。
<style>
td, th {vertical-align: top}
</style>
<table>
<tr>
<th><t>Version</t><t>版本</t></th>
<th><t>Status</t><t>状态</t></th>
<th><t>Release Date</t><t>发布日期</t></th>
<th><t>LTS Start Date</t><t>LTS 起始日期</t></th>
<th><t>LTS End Date</t><t>LTS 结束日期</t></th>
</tr>
<tr>
<td>^4.0.0</td>
<td>LTS</td>
<td><t>March 23, 2017</t><t>2017-03-23</t></td>
<td><t>September 23, 2017</t><t>2017-09-23</t></td>
<td><t>September 23, 2018</t><t>2018-09-23</t></td>
</tr>
<tr>
<td>^5.0.0</td>
<td>LTS</td>
<td><t>November 1, 2017</t><t>2017-11-01</t></td>
<td><t>May 1, 2018</t><t>2018-05-01</t></td>
<td><t>May 1, 2019</t><t>2019-05-01</t></td>
</tr>
<tr>
<td>^6.0.0</td>
<td>Active</td>
<td><t>May 3, 2018</t><t>2018-05-03</t></td>
<td><t>November 3, 2018</t><t>2018-11-03</t></td>
<td><t>November 3, 2019</t><t>2019-11-03</t></td>
</tr>
</table>
Version | Status | Released | Active Ends | LTS Ends
------- | ------ | ------------ | ------------ | ------------
^7.0.0 | Active | Oct 18, 2018 | Apr 18, 2019 | Apr 18, 2020
^6.0.0 | LTS | May 3, 2018 | Nov 3, 2018 | Nov 3, 2019
^5.0.0 | LTS | Nov 1, 2017 | May 1, 2018 | May 1, 2019
LTS for Angular version ^4.0.0 ended on September 23, 2018.
Angular ^4.0.0 版本的 LTS 支持将结束于 2018-09-23。
{@a deprecation}

View File

@ -4251,12 +4251,14 @@ A guard's return value controls the router's behavior:
如果它返回 `true`,导航过程会继续
* If it returns `false`, the navigation process stops and the user stays put.
* If it returns a `UrlTree`, the current navigation cancels and a new navigation is initiated to the `UrlTree` returned.
如果它返回 `false`,导航过程会终止,且用户会留在原地。
<div class="alert is-helpful">
**Note:**The guard can also tell the router to navigate elsewhere, effectively canceling the current navigation.
**Note:**The guard can also tell the router to navigate elsewhere, effectively canceling the current navigation. When
doing so inside a guard, the guard should return `false`;
**注意**:守卫还可以告诉路由器导航到别处,这样也取消当前的导航。

View File

@ -169,7 +169,7 @@ vulnerability. For example, code contained in a `<script>` tag is executed:
</code-example>
Angular recognizes the value as unsafe and automatically sanitizes it, which removes the `<script>`
tag but keeps safe content such as the text content of the `<script>` tag and the `<b>` element.
tag but keeps safe content such as the `<b>` element.
Angular 认为这些值是不安全的,并自动进行无害化处理。它会移除 `<script>` 标签,但保留安全的内容,比如该片段中的文本内容或 `<b>` 元素。

View File

@ -306,7 +306,15 @@ For example, the string `3d12h` will cache content for up to three and a half da
#### `timeout`
This duration string specifies the network timeout. The network timeout is how long the Angular service worker will wait for the network to respond before using a cached response, if configured to do so.
This duration string specifies the network timeout. The network timeout is how long the Angular service worker will wait for the network to respond before using a cached response, if configured to do so. `timeout` is a duration string, using the following unit suffixes:
* `d`: days
* `h`: hours
* `m`: minutes
* `s`: seconds
* `u`: milliseconds
For example, the string `5s30u` will translate to five seconds and 30 milliseconds of network timeout.
这个表示持续时间的字符串用于指定网络超时时间。
如果配置了它Angular Service Worker 在开始使用缓存之前就会先等待网络给出响应,这个等待时间就是网络超时时间。

View File

@ -83,7 +83,7 @@ Installing the Angular service worker is as simple as including an `NgModule`. I
## 前提条件
Your application must run in a web browser that supports service workers. Currently, the latest versions of Chrome and Firefox are supported. To learn about other browsers that are service worker ready, see the [Can I Use](http://caniuse.com/#feat=serviceworkers) page.
Your application must run in a web browser that supports service workers. Currently, service workers are supported in the latest versions of Chrome, Firefox, Edge, Safari, Opera, UC Browser (Android version) and Samsung Internet. Browsers like IE and Opera Mini do not provide the support. To learn more about other browsers that are service worker ready, see the [Can I Use](https://caniuse.com/#feat=serviceworkers) page and [MDN docs](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API).
你的应用必须运行在支持 Service Worker 的 Web 浏览器中。目前Chrome 和 Firefox 的最新版本 都已经支持了。
要想知道其它浏览器是否支持,参见 [Can I Use](http://caniuse.com/#feat=serviceworkers) 页。

View File

@ -210,8 +210,8 @@ jobs:
key: my-project-{{ .Branch }}-{{ checksum "package-lock.json" }}
paths:
- "node_modules"
- run: npm run test -- --single-run --no-progress --browser=ChromeHeadlessCI
- run: npm run e2e -- --no-progress --config=protractor-ci.conf.js
- run: npm run test -- --no-watch --no-progress --browsers=ChromeHeadlessCI
- run: npm run e2e -- --protractor-config=e2e/protractor-ci.conf.js
```
This configuration caches `node_modules/` and uses [`npm run`](https://docs.npmjs.com/cli/run-script) to run CLI commands, because `@angular/cli` is not installed globally.
@ -264,8 +264,8 @@ install:
- npm install
script:
- npm run test -- --single-run --no-progress --browser=ChromeHeadlessCI
- npm run e2e -- --no-progress --config=protractor-ci.conf.js
- npm run test -- --no-watch --no-progress --browsers=ChromeHeadlessCI
- npm run e2e -- --protractor-config=e2e/protractor-ci.conf.js
```
This does the same things as the Circle CI configuration, except that Travis doesn't come with Chrome, so we use Chromium instead.
@ -304,10 +304,9 @@ We'll be using [Headless Chrome](https://developers.google.com/web/updates/2017/
这个例子中我们将使用[无头 Chrome](https://developers.google.com/web/updates/2017/04/headless-chrome#cli)。
* In the Karma configuration file, `karma.conf.js`, add a custom launcher called ChromeNoSandbox below browsers:
* In the Karma configuration file, `karma.conf.js`, add a custom launcher called ChromeHeadlessCI below browsers:
在 Karma 配置文件 `karma.conf.js` 中,浏览器的紧下方,添加自定义的启动器,名叫 ChromeNoSandbox。
```
browsers: ['Chrome'],
customLaunchers: {
@ -318,9 +317,9 @@ customLaunchers: {
},
```
* Create a new file, `protractor-ci.conf.js`, in the root folder of your project, which extends the original `protractor.conf.js`:
* In the root folder of your e2e tests project, create a new file named `protractor-ci.conf.js`. This new file extends the original `protractor.conf.js`.
位于项目的根目录下创建一个新文件 `protractor-ci.conf.js`,它扩展了原始的 `protractor.conf.js`
e2e 测试项目的根目录下创建一个新文件 `protractor-ci.conf.js`,它扩展了原始的 `protractor.conf.js`
```
const config = require('./protractor.conf').config;
@ -340,8 +339,8 @@ Now you can run the following commands to use the `--no-sandbox` flag:
现在你可以运行下列带有 `--no-sandbox` 标志的命令了:
<code-example language="sh" class="code-shell">
ng test --single-run --no-progress --browser=ChromeHeadlessCI
ng e2e --no-progress --config=protractor-ci.conf.js
ng test -- --no-watch --no-progress --browsers=ChromeHeadlessCI
ng e2e -- --protractor-config=e2e/protractor-ci.conf.js
</code-example>
<div class="alert is-helpful">
@ -369,7 +368,7 @@ To generate a coverage report run the following command in the root of your proj
要生成覆盖率报告,请在项目的根目录下运行下列命令。
<code-example language="sh" class="code-shell">
ng test --watch=false --code-coverage
ng test --no-watch --code-coverage
</code-example>
When the tests are complete, the command creates a new `/coverage` folder in the project. Open the `index.html` file to see a report with your source code and code coverage values.
@ -1034,7 +1033,7 @@ Do not re-configure `TestBed` after calling `createComponent`.
在调用了 `createComponent` 之后就不能再重新配置 `TestBed` 了。
The `createComponent` method freezes the current `TestBed`definition,
The `createComponent` method freezes the current `TestBed` definition,
closing it to further configuration.
`createComponent` 方法冻结了当前的 `TestBed` 定义,关闭它才能再进行后续配置。

View File

@ -121,7 +121,7 @@ Your app may have to launch faster to engage these users before they decide to d
With Angular Universal, you can generate landing pages for the app that look like the complete app.
The pages are pure HTML, and can display even if JavaScript is disabled.
The pages don't handle browser events, but they _do_ support navigation through the site using `[routerLink](guide/router#router-link)`.
The pages don't handle browser events, but they _do_ support navigation through the site using [`routerLink`](guide/router#router-link).
使用 Angular Universal你可以为应用生成“着陆页”它们看起来就和完整的应用一样。
这些着陆页是纯 HTML并且即使 JavaScript 被禁用了也能显示。

View File

@ -411,9 +411,12 @@ See [Upgrading from AngularJS](guide/upgrade) to learn about:
`downgradeModule()``UpgradeModule` 之间的区别就是这些。
其余的 `upgrade/static` API 和概念的工作方式在不同的混合式应用中都完全一样了。
- [Using Angular Components from AngularJS Code](guide/upgrade#using-angular-components-from-angularjs-code).
- [Using Angular Components from AngularJS Code](guide/upgrade#using-angular-components-from-angularjs-code).<br />
_NOTE: If you are downgrading multiple modules, you need to specify the name of the downgraded
module each component belongs to, when calling `downgradeComponent()`._
[从 AngularJS 代码中使用 Angular 组件](guide/upgrade#using-angular-components-from-angularjs-code)。
[从 AngularJS 代码中使用 Angular 组件](guide/upgrade#using-angular-components-from-angularjs-code)。<br />
*注意:如果你要降级多个模块,就要在调用 `downgradeComponent()` 时为每个组件所属的降级后模块指定一个模块名。*
- [Using AngularJS Component Directives from Angular Code](guide/upgrade#using-angularjs-component-directives-from-angular-code).
@ -431,22 +434,26 @@ See [Upgrading from AngularJS](guide/upgrade) to learn about:
[让 AngularJS 的依赖可注入到 Angular 中](guide/upgrade#making-angularjs-dependencies-injectable-to-angular)。
- [Making Angular Dependencies Injectable to AngularJS](guide/upgrade#making-angular-dependencies-injectable-to-angularjs).
- [Making Angular Dependencies Injectable to AngularJS](guide/upgrade#making-angular-dependencies-injectable-to-angularjs).<br />
_NOTE: If you are downgrading multiple modules, you need to specify the name of the downgraded
module each injectable belongs to, when calling `downgradeInjectable()`._
[让 Angular 的依赖可注入到 AngularJS 中](guide/upgrade#making-angular-dependencies-injectable-to-angularjs)。
<div class="alert is-important">
While it is possible to downgrade injectables, downgraded injectables will not be available until
the Angular module is instantiated. In order to be safe, you need to ensure that the downgraded
injectables are not used anywhere _outside_ the part of the app that is controlled by Angular.
the Angular module that provides them is instantiated. In order to be safe, you need to ensure
that the downgraded injectables are not used anywhere _outside_ the part of the app where it is
guaranteed that their module has been instantiated.
虽然可以降级可注入对象,但在实例化 Angular 模块之前,无法使用降级后的可注入对象。
安全起见,你需要确保降级后的可注入对象不会用于应用中*不受* Angular 控制的任何地方。
For example, it is _OK_ to use a downgraded service in an upgraded component that is only used
from Angular components, but it is _not OK_ to use it in an AngularJS component that may be used
independently of Angular.
from a downgraded Angular component provided by the same Angular module as the injectable, but it
is _not OK_ to use it in an AngularJS component that may be used independently of Angular or use
it in a downgraded Angular component from a different module.
比如,在只使用 Angular 组件的升级过的组件中*可以*使用降级后的服务,但是,*不能*在那些不依赖 Angular 就能用的 AngularJS 组件中使用。

View File

@ -0,0 +1,135 @@
# Angular Workspace Configuration
A file named `angular.json` at the root level of an Angular [workspace](guide/glossary#workspace) provides workspace-wide and project-specific configuration defaults for build and development tools provided by the Angular CLI.
Path values given in the configuration are relative to the root workspace folder.
## Overall JSON structure
At the top level of `angular.json`, a few properties configure the workspace, and a `projects` section contains the remaining per-project configuration options.
* `version`: The configuration-file version.
* `newProjectRoot`: Path where new projects are created. Absolute or relative to the workspace folder.
* `defaultProject`: Default project name to use in commands, where not provided as an argument. When you use `ng new` to create a new app in a new workspace, that app is the default project for the workspace until you change it here.
* `projects` : Contains a subsection for each project (library, app, e2e test app) in the workspace, with the per-project configuration options.
The initial app that you create with `ng new app_name` is listed under "projects", along with its corresponding end-to-end test app:
<code-example format="." language="none" linenums="false">
projects
app_name
...
app_name-e2e
...
</code-example>
Each additional app that you create with `ng generate application` has a corresponding end-to-end test project, with its own configuration section.
When you create a library project with `ng generate library`, the library project is also added to the `projects` section.
<div class="alert is-helpful">
Note that the `projects` section of the configuration file does not correspond exactly to the workspace file structure.
* The initial app created by `ng new` is at the top level of the workspace file structure, along with its e2e app.
* Additional apps, e2e apps, and libraries go into a `projects` folder in the workspace.
For more information, see [Workspace and project file structure](guide/file-structure).
</div>
## Project configuration options
The following top-level configuration properties are available for each project, under `projects:<project_name>`.
<code-example format="." language="json" linenums="false">
"my-v7-app": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {},
"architect": {}
}
</code-example>
| PROPERTY | DESCRIPTION |
| :-------------- | :---------------------------- |
| `root` | The root folder for this project's files, relative to the workspace folder. Empty for the initial app, which resides at the top level of the workspace. |
| `sourceRoot` | The root folder for this project's source files. |
| `projectType` | One of "application" or "library". An application can run independently in a browser, while a library cannot. Both an app and its e2e test app are of type "application".|
| `prefix` | A string that Angular prepends to generated selectors. Can be customized to identify an app or feature area. |
| `schematics` | An object containing schematics that customize CLI commands for this project. |
| `architect` | An object containing configuration defaults for Architect builder targets for this project. |
## Project tool configuration options
Architect is the tool that the CLI uses to perform complex tasks such as compilation and test running, according to provided configurations. The `architect` section contains a set of Architect *targets*. Many of the targets correspond to the CLI commands that run them. Some additional predefined targets can be run using the `ng run` command, and you can define your own targets.
Each target object specifies the `builder` for that target, which is the npm package for the tool that Architect runs. In addition, each target has an `options` section that configure default options for the target, and a `configurations` section that names and specifies alternative configurations for the target. See the example in [Build target](#build-target) below.
<code-example format="." language="json" linenums="false">
"architect": {
"build": { },
"serve": { },
"e2e" : { },
"test": { },
"lint": { },
"extract-i18n": { },
"server": { },
"app-shell": { }
}
</code-example>
* The `architect/build` section configures defaults for options of the `ng build` command. See [Build target](#build-target) below for more information.
* The `architect/serve` section overrides build defaults and supplies additional serve defaults for the `ng serve` command. In addition to the options available for the `ng build` command, it adds options related to serving the app.
* The `architect/e2e` section overrides build-option defaults for building end-to-end testing apps using the `ng e2e` command.
* The `architect/test` section overrides build-option defaults for test builds and supplies additional test-running defaults for the `ng test` command.
* The `architect/lint` section configures defaults for options of the `ng lint` command, which performs code analysis on project source files. The default linting tool for Angular is [TSLint](https://palantir.github.io/tslint/).
* The `architect/extract-i18n` section configures defaults for options of the `ng-xi18n` tool used by the `ng xi18n` command, which extracts marked message strings from source code and outputs translation files.
* The `architect/server` section configures defaults for creating a Universal app with server-side rendering, using the `ng run <project>:server` command.
* The `architect/app-shell` section configures defaults for creating an app shell for a progressive web app (PWA), using the `ng run <project>:app-shell` command.
In general, the options for which you can configure defaults correspond to the command options listed in the [CLI reference page](cli) for each command.
Note that all options in the configuration file must use [camelCase](guide/glossary#case-conventions), rather than dash-case.
{@a build-target}
## Build target
The `architect/build` section configures defaults for options of the `ng build` command. It has the following top-level properties.
| PROPERTY | DESCRIPTION |
| :-------------- | :---------------------------- |
| `builder` | The npm package for the build tool used to create this target. The default is `@angular-devkit/build-angular:browser`, which uses the [webpack](https://webpack.js.org/) package bundler. |
| `options` | This section contains defaults for build options, used when no named alternative configuration is specified. See [Default build options](#build-props) below. |
| `configurations`| This section defines and names alternative configurations for different intended destinations. It contains a section for each named configuration, which sets the default options for that intended environment. See [Alternate build configurations](#build-configs) below. |
{@a build-configs}
### Alternate build configurations
By default, a `production` configuration is defined, and the `ng build` command has `--prod` option that builds using this configuration. The `production` configuration sets defaults that optimize the app in a number of ways, such bundling files, minimizing excess whitespace, removing comments and dead code, and rewriting code to use short, cryptic names ("minification").
You can define and name additional alternate configurations (such as `stage`, for instance) appropriate to your development process. Some examples of different build configurations are `stable`, `archive` and `next` used by AIO itself, and the individual locale-specific configurations required for building localized versions of an app. For details, see [Internationalization (i18n)](guide/i18n#merge-aot).
{@a build-props}
### Additional build and test options
The configurable options for a default or targeted build generally correspond to the options available for the [`ng build`](cli/build), [`ng serve`](cli/serve), and [`ng test`](cli/test) commands. For details of those options and their possible values, see the [CLI Reference](cli).
Some additional options (listed below) can only be set through the configuration file, either by direct editing or with the `ng config` command.
| OPTIONS PROPERTIES | DESCRIPTION |
| :------------------------- | :---------------------------- |
| `fileReplacements` | An object containing files and their compile-time replacements. |
| `stylePreprocessorOptions` | An object containing option-value pairs to pass to style preprocessors. |
| `assets` | An object containing paths to static assets to add to the global context of the project. The default paths point to the project's icon file and its `assets` folder. |
| `styles` | An object containing style files to add to the global context of the project. Angular CLI supports CSS imports and all major CSS preprocessors: [sass/scss](http://sass-lang.com/), [less](http://lesscss.org/), and [stylus](http://stylus-lang.com/). |
| `scripts` | An object containing JavaScript script files to add to the global context of the project. The scripts are loaded exactly as if you had added them in a `<script>` tag inside `index.html`. |
| `budgets` | Default size-budget type and threshholds for all or parts of your app. You can configure the builder to report a warning or an error when the output reaches or exceeds a threshold size. See [Configure size budgets](guide/build#configure-size-budgets). (Not available in `test` section.) |

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

View File

Before

Width:  |  Height:  |  Size: 851 KiB

After

Width:  |  Height:  |  Size: 851 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 27 KiB

File diff suppressed because it is too large Load Diff

View File

@ -13,23 +13,11 @@
</tr>
</thead>
<tbody>
<!-- AngularMix -->
<!-- ngAtlanta 2019 -->
<tr>
<th><a href="https://angularmix.com/" title="AngularMix">AngularMix</a></th>
<td>Orlando, Florida</td>
<td>October 10-12, 2018</td>
</tr>
<!-- ReactiveConf -->
<tr>
<th><a href="https://reactiveconf.com/" title="ReactiveConf">ReactiveConf</a></th>
<td>Prague, Czech Republic</td>
<td>October 29-31, 2018</td>
</tr>
<!-- AngularConnect-->
<tr>
<th><a href="http://angularconnect.com" title="AngularConnect">AngularConnect</a></th>
<td>London, United Kingdom</td>
<td>November 5-7, 2018</td>
<th><a href="https://ng-atl.org/" title="ngAtlanta">ngAtlanta</a></th>
<td>Atlanta, Georgia</td>
<td>January 9 - 12, 2019</td>
</tr>
</tbody>
</table>
@ -44,41 +32,23 @@
</tr>
</thead>
<tbody>
<!-- AngularConnect-->
<tr>
<th><a href="http://angularconnect.com" title="AngularConnect">AngularConnect</a></th>
<td>London, United Kingdom</td>
<td>November 7-8, 2017</td>
</tr>
<!-- ngAtlanta-->
<tr>
<th><a href="http://ng-atl.org/" title="ngAtlanta">ngAtlanta</a></th>
<td>Atlanta, Georgia</td>
<td>January 30, 2018</td>
</tr>
<!-- ngVikings-->
<tr>
<th><a href="https://ngvikings.org/" title="ngVikings">ngVikings</a></th>
<td>Helsinki, Finland</td>
<td>March 1-2, 2018</td>
</tr>
<!-- ngconf 2018-->
<tr>
<th><a href="https://www.ng-conf.org/" title="ng-conf">ng-conf</a></th>
<td>Salt Lake City, Utah</td>
<td>April 18-20, 2018</td>
</tr>
<!-- WeRDevs-->
<tr>
<th><a href="https://www.wearedevelopers.com/" title="WeAreDevs">WeAreDevelopers</a></th>
<td>Vienna, Austria</td>
<td>May 16-18, 2018</td>
</tr>
<!-- ngJapan-->
<tr>
<th><a href="https://ngjapan.org/en.html" title="ng-japan">ng-japan</a></th>
<td>Tokyo, Japan</td>
<td>Jun 16, 2018</td>
<!-- ReactiveConf -->
<tr>
<th><a href="https://reactiveconf.com/" title="ReactiveConf">ReactiveConf</a></th>
<td>Prague, Czech Republic</td>
<td>October 29-31, 2018</td>
</tr>
<!-- AngularConnect-->
<tr>
<th><a href="http://angularconnect.com" title="AngularConnect">AngularConnect</a></th>
<td>London, United Kingdom</td>
<td>November 5-7, 2018</td>
</tr>
<!-- AngularMix -->
<tr>
<th><a href="https://angularmix.com/" title="AngularMix">AngularMix</a></th>
<td>Orlando, Florida</td>
<td>October 10-12, 2018</td>
</tr>
<!-- Angular Conf Australia-->
<tr>
@ -86,6 +56,36 @@
<td>Melbourne, Australia</td>
<td>Jun 22, 2018</td>
</tr>
<!-- ngJapan-->
<tr>
<th><a href="https://ngjapan.org/en.html" title="ng-japan">ng-japan</a></th>
<td>Tokyo, Japan</td>
<td>Jun 16, 2018</td>
</tr>
<!-- WeRDevs-->
<tr>
<th><a href="https://www.wearedevelopers.com/" title="WeAreDevs">WeAreDevelopers</a></th>
<td>Vienna, Austria</td>
<td>May 16-18, 2018</td>
</tr>
<!-- ngconf 2018-->
<tr>
<th><a href="https://www.ng-conf.org/" title="ng-conf">ng-conf</a></th>
<td>Salt Lake City, Utah</td>
<td>April 18-20, 2018</td>
</tr>
<!-- ngVikings-->
<tr>
<th><a href="https://ngvikings.org/" title="ngVikings">ngVikings</a></th>
<td>Helsinki, Finland</td>
<td>March 1-2, 2018</td>
</tr>
<!-- ngAtlanta-->
<tr>
<th><a href="http://ng-atl.org/" title="ngAtlanta">ngAtlanta</a></th>
<td>Atlanta, Georgia</td>
<td>January 30, 2018</td>
</tr>
</tbody>
</table>
</article>

View File

@ -22,6 +22,12 @@
"rev": true,
"title": "Made with Angular",
"url": "https://www.madewithangular.com/"
},
"angular-subreddit": {
"desc": "An Angular-dedicated subreddit.",
"rev": true,
"title": "Angular Subreddit",
"url": "https://www.reddit.com/r/Angular2/"
}
}
},
@ -149,6 +155,13 @@
"rev": true,
"title": "AngularCommerce",
"url": "https://github.com/NodeArt/angular-commerce"
},
"ngx-api-utils": {
"desc": "ngx-api-utils is a lean library of utilities and helpers to quickly integrate any HTTP API (REST, Ajax, and any other) with Angular.",
"logo": "",
"rev": true,
"title": "ngx-api-utils",
"url": "https://github.com/ngx-api-utils/ngx-api-utils"
}
}
},
@ -211,7 +224,7 @@
"logo": "https://cloud.githubusercontent.com/assets/1016365/10639063/138338bc-7806-11e5-8057-d34c75f3cafc.png",
"rev": true,
"title": "Angular Universal",
"url": "https://github.com/angular/universal"
"url": "https://angular.io/guide/universal"
},
"c1": {
"desc": "Lightweight development only Node.js® server",
@ -273,6 +286,13 @@
"rev": true,
"title": "UI-jar - Test Driven Style Guide Development",
"url": "https://github.com/ui-jar/ui-jar"
},
"protactor": {
"desc": "The official end to end testing framework for Angular apps",
"logo": "",
"rev": true,
"title": "Protractor",
"url": "https://protractor.angular.io/"
}
}
},
@ -362,7 +382,7 @@
"logo": "",
"rev": true,
"title": "Angular Material",
"url": "https://github.com/angular/material2"
"url": "https://material.angular.io/"
},
"mcc": {
"desc": "Material components made by the community",
@ -377,6 +397,12 @@
"title": "Ant Design of Angular (ng-zorro-antd)",
"url": "https://ng.ant.design/docs/introduce/en"
},
"ngzorromobile": {
"desc": "A set of enterprise-class mobile UI components based on Ant Design Mobile and Angular",
"rev": true,
"title": "Ant Design Mobile of Angular (ng-zorro-antd-mobile)",
"url": "http://ng.mobile.ant.design/#/docs/introduce/en"
},
"aggrid": {
"desc": "A datagrid for Angular with enterprise style features such as sorting, filtering, custom rendering, editing, grouping, aggregation and pivoting.",
"rev": true,
@ -427,6 +453,12 @@
"rev": true,
"title": "Simple Quality UI",
"url": "https://sq-ui.github.io/ng-sq-ui/#/"
},
"smart": {
"desc": "Web Components for Angular. Dependency-free Angular components for building modern and mobile-friendly web apps",
"rev": true,
"title": "Smart Web Components",
"url": "https://www.htmlelements.com/angular/"
}
}
}
@ -674,6 +706,12 @@
"工作室 & 现场培训": {
"order": 2,
"resources": {
"webucator": {
"desc": "Customized in-person instructor-led Angular training for private groups and public online instructor-led Angular classes.",
"rev": true,
"title": "Webucator",
"url": "https://www.webucator.com/webdev-training/angular-training"
},
"-acceleb": {
"desc": "Customized, Instructor-Led Angular Training",
"rev": true,
@ -762,6 +800,12 @@
"title": "SFEIR School (French)",
"url": "https://school.sfeir.com/project/sa200/"
},
"zenika-angular": {
"desc": "Angular trainings delivered by Zenika (FRANCE)",
"rev": true,
"title": "Angular Trainings (French)",
"url": "https://training.zenika.com/fr/training/angular2/description"
},
"formationjs": {
"desc": "Angular onsite training in Paris (France). Monthly Angular workshops and custom onsite classes. We are focused on Angular, so we are always up to date.",
"rev": true,

View File

@ -1,7 +1,5 @@
<h1>Test Code Page</h1>
<p>Current location is <current-location></current-location></p>
<h2>&lt;code-tabs&gt;</h2>
<p>No linenums at code-tabs level</p>
@ -120,3 +118,20 @@ Try this <live-example></live-example>.
<live-example embedded name="testy" stackblitz="super-stackblitz"></live-example>
<p>More text follows ...</p>
<p>Getting Started Widgets</p>
<p>Interpolation</p>
<aio-gs-interpolation></aio-gs-interpolation>
<p>Property Binding</p>
<aio-gs-property-binding></aio-gs-property-binding>
<p>Event Binding</p>
<aio-gs-event-binding></aio-gs-event-binding>
<p>NgIf</p>
<aio-gs-ng-if></aio-gs-ng-if>
<p>NgFor</p>
<aio-gs-ng-for></aio-gs-ng-for>

View File

@ -602,10 +602,16 @@
"title": "项目文件结构",
"tooltip": "Angular 工作空间在文件系统中是怎样的。"
},
{
"url": "guide/workspace-config",
"title": "Workspace Configuration",
"tooltip": "The \"angular.json\" file contains workspace and project configuration defaults for Angular CLI commands."
},
{
"url": "guide/npm-packages",
"title": "npm 包",
"tooltip": "会默认安装到项目中的 npm 包的说明。"
"tooltip": "开发期间和运行期间所需的 npm 包的说明。"
},
{
"url": "guide/typescript-configuration",
@ -663,31 +669,15 @@
"title": "发布信息",
"tooltip": "Angular 的版本发布实践、更新与升级。",
"children": [
{
"url": "guide/updating",
"title": "保持最新",
"tooltip": "如何把 Angular 应用和库升级到最新版本。"
},
{
"url": "guide/releases",
"title": "Angular 发布策略与实践",
"tooltip": "Angular 的版本、发布、支持、弃用策略与实践。"
},
{
"url": "guide/updating",
"title": "保持最新",
"tooltip": "如何把 Angular 应用和库升级到最新版本。"
},
{
"title": "从 AngularJS 升级",
"tooltip": "逐渐把 AngularJS 应用升级成 Angular。",
"children": [
{
"url": "guide/upgrade",
"title": "升级指南",
"tooltip": "逐渐把 AngularJS 应用升级成 Angular。"
},
{
"url": "guide/ajs-quick-reference",
"title": "AngularJS 与 Angular 的概念对照",
"tooltip": "学习如何把 AngularJS 的概念映射到 Angular 中。"
}
]
}
]
},
@ -850,11 +840,7 @@
"docVersions": [
{ "title": "v6", "url": "https://v6.angular.io" },
{ "title": "v5", "url": "https://v5.angular.io" },
{ "title": "v4 ", "url": "https://v4.angular.io"
},
{ "title": "v2", "url": "https://v2.angular.cn"
},
{
"title": "AngularDart", "url": "https://webdev.dartlang.org/angular" }
{ "title": "v4", "url": "https://v4.angular.io" },
{ "title": "v2", "url": "https://v2.angular.io" }
]
}

View File

@ -45,10 +45,9 @@ To set up your development environment, follow these instructions in [Getting St
<div class="alert is-helpful">
**Note:**: You do not need to complete the entire Getting Started. After you complete the above two sections of Getting Started, your environment is set up. Continue below to create the Tour of Heroes workspace and an initial app project.
**Note:** You do not need to complete the entire Getting Started. After you complete the above two sections of Getting Started, your environment is set up. Continue below to create the Tour of Heroes workspace and an initial app project.
**注意:**你不用做完整个快速上手。只要完成了上面这两个部分,你的环境就已经设置好了。然后继续下面的步骤来创建一个《英雄指南》的工作空间和一个初始应用项目。
</div>

View File

@ -36,10 +36,10 @@ When youre done, users will be able to navigate the app like this:
## 添加 `AppRoutingModule`
An Angular best practice is to load and configure the router in a separate, top-level module
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`.
Angular 的最佳实践之一就是在一个独立的顶级模块中加载和配置路由器,它专注于路由功能,然后由根模块 `AppModule` 导入它。
在 Angular 中,最好在一个独立的顶级模块中加载和配置路由器,它专注于路由功能,然后由根模块 `AppModule` 导入它。
By convention, the module class name is `AppRoutingModule` and it belongs in the `app-routing.module.ts` in the `src/app` folder.

View File

@ -126,8 +126,13 @@ that primes the in-memory database.
`forRoot()` 配置方法接受一个 `InMemoryDataService` 类(初期的内存数据库)作为参数。
The _Tour of Heroes_ sample creates such a class
`src/app/in-memory-data.service.ts` which has the following content:
The class `src/app/in-memory-data.service.ts` is generated by the following command:
<code-example language="sh" class="code-shell">
ng generate service InMemoryData
</code-example>
This class has the following content:
在*英雄指南*范例中创建一个类 `src/app/in-memory-data.service.ts`,内容如下:
@ -387,7 +392,7 @@ Most web APIs support a _get by id_ request in the form `:baseURL/:id`.
大多数的 Web API 都支持以 `:baseURL/:id` 的形式根据 id 进行获取。
Here, the _base URL_ is the `heroesURL` defined in the [Heroes and HTTP](http://localhost:4800/tutorial/toh-pt6#heroes-and-http) section (`api/heroes`) and _id_ is
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`.
Add a `HeroService.getHero()` method to make that request:
@ -752,7 +757,7 @@ as listed in the [final code review](#herosearchcomponent) below.
从下面的 [最终代码](#herosearchcomponent) 中把私有 CSS 样式添加到 `hero-search.component.css` 中。
As the user types in the search box, a *keyup* event binding calls the component's `search()`
As the user types in the search box, an *input* event binding calls the component's `search()`
method with the new search box value.
当用户在搜索框中输入时,一个 *keyup* 事件绑定会调用该组件的 `search()` 方法,并传入新的搜索框的值。
@ -833,7 +838,7 @@ as the `search()` method does.
你还可以通过调用它的 `next(value)` 方法往 `Observable` 中推送一些值,就像 `search()` 方法中一样。
The `search()` method is called via an _event binding_ to the
textbox's `keystroke` event.
textbox's `input` event.
`search()` 是通过对文本框的 `keystroke` 事件的*事件绑定*来调用的。

View File

@ -12,13 +12,13 @@
"/app/search/search-worker.js",
"/assets/images/favicons/favicon.ico",
"/assets/js/*.js",
"/generated/lunr.min.js",
"/*.css",
"/*.js"
],
"urls": [
"https://fonts.googleapis.com/**",
"https://fonts.gstatic.com/s/**",
"https://maxcdn.bootstrapcdn.com/**"
"https://fonts.gstatic.com/s/**"
]
}
}, {

Some files were not shown because too many files have changed in this diff Show More