Compare commits

..

793 Commits

Author SHA1 Message Date
Jose Luis Campos Bautista
80073944a1
docs: traducir guide/schematics.md (#365)
Co-authored-by: Daniel Díaz <36966980+dalejodc@users.noreply.github.com>
Co-authored-by: Michael Prentice <splaktar@gmail.com>
2021-05-07 04:45:23 -04:00
Clara
a2aa45d3c7
docs: traducir guide/testing-utility-apis.md (#237)
Co-authored-by: Michael Prentice <splaktar@gmail.com>
Co-authored-by: Gustavo Rodríguez <47954465+gustavguez@users.noreply.github.com>

Fix #231
2021-04-27 22:31:40 -04:00
Kaleb Alves
0731c7f634
docs: traducir compartiendo módulos al español (#235)
Co-authored-by: Daniel Díaz <36966980+dalejodc@users.noreply.github.com>

Fixes #165
2021-04-27 12:13:30 -04:00
Gustavo Rodríguez
cf2d40e359
docs: traducción de npm-packages.md (#340)
Co-authored-by: Julio Lagos <julio.lagos.carrera@gmail.com>
Co-authored-by: Daniel Díaz <36966980+dalejodc@users.noreply.github.com>
Co-authored-by: Michael Prentice <splaktar@gmail.com>

Fixes #213
2021-04-27 09:52:15 -04:00
Cristobal Vega
0c47b7184c
docs: translate rx-library.md (#346)
Fixes #144
2021-04-27 09:39:49 -04:00
Francisco Javier Suarez Verdugo
752100487b
docs: traducción archivo route-animations (#349)
Co-authored-by: Daniel Díaz <36966980+dalejodc@users.noreply.github.com>
2021-04-27 08:21:25 -04:00
Stalin
7a183c9920
docs: translate-first-revision content\guide\binding-syntax.md (#328)
Co-authored-by: Daniel Díaz <36966980+dalejodc@users.noreply.github.com>
2021-04-27 08:18:10 -04:00
JeMeister
eac35a64e1
docs: translate migration-solution-style-tsconfig.md (#327)
Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>
2021-04-12 00:40:01 -04:00
Michael Prentice
0348f47f62 docs: fix presskit layout 2021-04-06 23:20:44 -04:00
Antonio Cardenas
79da3e8cd2
docs: traducir marketing/resources.json (#323)
Co-authored-by: Michael Prentice <splaktar@gmail.com>
Co-authored-by: Daniel Díaz <36966980+dalejodc@users.noreply.github.com>
2021-04-06 20:33:13 -04:00
Nicolas Molina Monroy
67b431603a docs: translate libraries.md 2021-04-06 20:00:46 -04:00
Antonio Cardenas
604bd6e1cb
docs: traducido marketing/README (#283)
Co-authored-by: Michael Prentice <splaktar@gmail.com>
Co-authored-by: Gustavo Rodríguez <47954465+gustavguez@users.noreply.github.com>
2021-04-06 19:54:43 -04:00
Antonio Cardenas
fdf572b3c5
docs: presskit-doc traducido (#282)
Co-authored-by: Michael Prentice <splaktar@gmail.com>
Co-authored-by: Gustavo Rodríguez <47954465+gustavguez@users.noreply.github.com>
2021-04-06 19:51:11 -04:00
Antonio Cardenas
f6936406ca
docs: translate tutorial/toh-pt2.md (#280) 2021-04-06 19:40:39 -04:00
Daniel
a4909d6aa0 docs: corrige y cambia forma de expresión en el archivo top-ph5.md 2021-03-21 04:42:05 -04:00
Daniel
600af0a5f6 docs: cambia forma de expresión en tutorial de héroes index.md 2021-02-06 20:45:58 -05:00
Gustavo Rodríguez
a0fcc0b839
docs: traducir: template-syntax.md (#320)
Co-authored-by: Alvaro Torrente <alvarotorrenteperez98@gmail.com>
Co-authored-by: Daniel Díaz <36966980+dalejodc@users.noreply.github.com>
2021-02-06 20:25:39 -05:00
Gustavo Rodríguez
cf6efd91ae Update aio/content/guide/template-statements.md
Co-authored-by: Daniel Díaz <36966980+dalejodc@users.noreply.github.com>
2021-02-06 20:21:31 -05:00
Gustavo Rodriguez
ee02855bd5 docs: change quotes 2021-02-06 20:21:31 -05:00
Daniel
53fd049d12 docs: corrige formas de expresion y traducciones del archivo glosary.md 2021-01-30 14:56:49 -05:00
Daniel
a025e98ede docs: cambia forma de expresión de algunas oraciones 2021-01-30 14:55:02 -05:00
Matt Hooper
768f81627e
docs: traducir feature-modules (#255)
Co-authored-by: Gustavo Rodríguez <47954465+gustavguez@users.noreply.github.com>
Co-authored-by: Michael Prentice <splaktar@gmail.com>
2021-01-28 22:07:25 -05:00
Maxwell Ferreiras
c2924a10e7
docs: start-routing Traducido al Español (#236)
Co-authored-by: Daniel Díaz <36966980+dalejodc@users.noreply.github.com>
2021-01-20 01:23:24 -05:00
jordivx
5af3281103
Traducir: guide/migration-update-module-and-target-compiler-options.md (#251)
* fix broken link

Co-authored-by: Michael Prentice <splaktar@gmail.com>
2021-01-20 00:48:57 -05:00
Clara
0496e59a10
docs: traducir guide/test-debugging (#262) 2021-01-20 00:42:21 -05:00
Julio Lagos
6f07ef5236 docs(docs-infra): add testing-code-coverage.md.en.md for the english version and translate testing-code-coverage.md for spanish
Fixes #226
2021-01-20 00:40:19 -05:00
Julio Lagos
0f9ed1d7d6 docs(docs-infra): add testing-attribute-directives.en.md for the english version and translate testing-attribute-directives.md for spanish
Fixes #225
2021-01-20 00:39:09 -05:00
Daniel Díaz
3aa0ca984c
docs: corrige typos y agrega tildes (#316)
- Se agregan tildes a algunas palabras.
- Se corrigen algunos typos y se cambia la forma de expresión de "usted" a "tu".
2021-01-08 00:53:59 -05:00
Pato
77832458c9
docs: web worker translations (#313)
Co-authored-by: Alejandro Lora <alejandrofpo@gmail.com>
Co-authored-by: Michael Prentice <splaktar@gmail.com>
2021-01-08 00:33:38 -05:00
Pato
e10a578603
docs: service-worker translation (#315)
* arreglos sugeridos por Alejandro
* gramática sugerido por Alejandro en PR
2021-01-08 00:15:05 -05:00
Daniel
b142d33bbe docs: remplaza simbolo "&" por letra "y"
Se remplaza el símbolo "&" por la letra "y". Se cambia de la forma de expresión "usted" a "tu".
2021-01-07 23:48:24 -05:00
Gustavo Rodríguez
bcabf710d0
docs: fix space in subtitle (#310) 2021-01-06 00:07:12 -05:00
Nicolas Molina Monroy
a725fe261a
docs: traducir AOT compiler (#277)
* translate guide/aot-compiler
* fix error in creating libs
* fix error w/ anchor link
2020-12-24 22:39:26 -05:00
Antonio Cardenas
ebee38994f
docs: translate tutorial/toh-pt5.md (#281)
- Se agrego la versión en ingles .en.md

Fixes #78
2020-11-27 04:05:57 -05:00
Nicolas Molina Monroy
6ebb0246ab docs: fix error in e2e tests in /tutorial 2020-11-27 03:47:58 -05:00
Antonio Cardenas
c7a054fa31 fixing github lost repo 2020-11-01 03:35:59 -05:00
Antonio Cardenas
6ff6acbb21
docs: translate tutorial/toh-pt1.md (#278)
Closes #74
2020-11-01 03:34:26 -05:00
Michael Prentice
8a09cb9794 test: fix aio e2e
- check for translated /features page content and title

Fixes #296
2020-10-22 21:12:06 -04:00
Antonio Cardenas
eeb59b4f4d
fix: master/toh-pt3 (#295)
Co-authored-by: Pato <11162114+devpato@users.noreply.github.com>
Co-authored-by: Michael Prentice <splaktar@gmail.com>
2020-10-22 19:24:06 -04:00
Antonio Cardenas
7afbc3a1c1
docs: update PULL_REQUEST_TEMPLATE.md (#240)
Co-authored-by: Michael Prentice <splaktar@gmail.com>
2020-10-22 19:00:26 -04:00
Pato
3da8ebf27e
feat(termino): nuevo de cross platform (#294) 2020-10-22 15:15:00 -05:00
Clara
7e33d531ae
docs: traducir practical observable usage (#288)
Closes #263
2020-10-22 15:28:06 -04:00
Antonio Cardenas
32577820f4
docs: translate two way binding (#287)
* cambios de sintaxicos
* translate: two ways data binding
* archivo en ingles agregado

Closes #233
2020-10-22 15:25:48 -04:00
Pato
3686c640d6
Traducir: marketing/features.html (#292)
Closes #100

Co-authored-by: Antonio Cardenas  <antonioalx66@gmail.com>
Co-authored-by: Gustavo Rodríguez <47954465+gustavguez@users.noreply.github.com>
2020-10-22 15:24:19 -04:00
Antonio Cardenas
cbe53247fa
docs: translate tutorial/toh-pt3.md (#279)
Closes #76

Co-authored-by: Pato <11162114+devpato@users.noreply.github.com>
2020-10-22 15:22:14 -04:00
Michael Prentice
bbbae1065a docs: traducir nombre de Collaborators group
- solucione el problema con el tamaño del botón que causa que se elimine el relleno
2020-10-22 12:23:52 -04:00
Antonio Cardenas
b5c3bb998d
Marketing test docs (#286)
* cambios de sintaxicos, traducido: marketing-test-docs y typo
2020-10-22 09:46:07 -05:00
Michael Prentice
4ff7aeadbb
ci: fix broken documentation links (#289)
Relates to #273. Relates to #276.
2020-10-22 09:35:46 -05:00
Gustavo Rodríguez
86eaf57d53
docs: agregar archivo: aio/diccionario-de-términos.md (#274)
Closes #9

Co-authored-by: Pato <11162114+devpato@users.noreply.github.com>
Co-authored-by: Michael Prentice <splaktar@gmail.com>
2020-10-22 09:41:30 -04:00
Jorge Yañez
ff7b7a9c2f
docs: transalate testing-services from English to Spanish (#271)
Fixes #230

Co-authored-by: José de Jesús Amaya <impepedev@gmail.com>
Co-authored-by: Pato <11162114+devpato@users.noreply.github.com>
2020-10-22 09:31:46 -04:00
Alfredo Benassi
dea267e5c8
docs: traducción de architecture-next-steps.md al español (#273)
Resolves #22

Co-authored-by: Pato <11162114+devpato@users.noreply.github.com>
2020-10-22 09:29:25 -04:00
Clara
07200be358
docs: traducir ngmodules (#276)
Co-authored-by: Pato <11162114+devpato@users.noreply.github.com>
2020-10-22 09:27:06 -04:00
Antonio Cardenas
45e6bb4a74
docs: translate tutorial/toh-pt4.md (#86)
* Toh pt4

- Se agrego la versión en ingles .en.md
- Se Probo previamente

* corrección ortografica y de enlaces colgantes
2020-10-21 10:19:21 -05:00
Jorge Yañez
b44f7b1a5c
docs: Translate setup-local.md from English to Spanish (#238)
Co-authored-by: Gustavo Rodríguez <47954465+gustavguez@users.noreply.github.com>
2020-10-16 03:49:13 -04:00
Antonio Cardenas
3c9c40c4b7 marketing-resources-docs traducido 2020-10-16 03:43:20 -04:00
Roberto Ortega
15bb08eea6
Traducir: guide/set-document-title.md #215 (#259)
Co-authored-by: Daniel Díaz <36966980+dalejodc@users.noreply.github.com>
2020-10-16 03:42:11 -04:00
Clara
10953bddcb
docs: traducir guide/Svg in templates (#270)
Co-authored-by: Gustavo Rodríguez <47954465+gustavguez@users.noreply.github.com>
2020-10-16 03:38:13 -04:00
Antonio Cardenas
7b87a797ed
docs: translate tutorial/toh-pt0.md (#82)
- Se agrego la versión en ingles .en.md
- Se Probo previamente

Fixes #73
2020-10-06 15:07:55 -04:00
Gustavo Rodríguez
4ea5a19a10
docs: translate guide/bootstrapping.md to spanish (#64)
Co-authored-by: Alejandro Lora <alejandrofpo@gmail.com>
2020-10-05 14:55:06 -04:00
Jorge Yañez
ee263f3b97
docs: Translate template-statement.md from English to Spanish (#257)
Co-authored-by: Daniel Díaz <36966980+dalejodc@users.noreply.github.com>
2020-10-05 14:49:56 -04:00
Alejandro Lora
f73846cd6b
docs: translate complex animation sequences (#81)
Co-authored-by: José de Jesús Amaya <impepedev@gmail.com>
2020-10-04 16:54:39 -04:00
Julio Lagos
b2fd28d2b0 docs(docs-infra): add testing-pipes.en.md for the english version of the translation and translate testing-pipes.md for spanish
Fixes #229
2020-10-04 02:41:02 -04:00
Antonio Cardenas
05535d985b contribute.hmtl traducido 2020-10-02 00:54:32 -04:00
Antonio Cardenas
4dc8aa2a27
docs: analytics.md traducido (#112)
* se agrego archivo en ingles para analytics

Fixes #96
2020-10-02 00:53:32 -04:00
Antonio Cardenas
3d084ac910
traducción marketing/events.html (#115) 2020-10-01 08:42:52 -05:00
Antonio Cardenas
f8678d7513 docs: translate marketing/about.html to spanish #7 2020-09-30 02:41:40 -04:00
Michael Prentice
c50136e2cb ci: arreglar más tareas
- reducir CI_AIO_MIN_PWA_SCORE
- se desconoce por qué la puntuación es 62 en CircleCI y 3/3, 3/3, 7/8 en Chrome
- comience a agregar IDs de proyectos y URLs de Angular Hispano
- elimine `test_docs_examples` ya que consume demasiados recursos
  y no necesitamos verificar que los ejemplos pasen las pruebas

Relates to #3
2020-09-29 15:06:57 -04:00
Michael Prentice
c3b4e0f37e ci: deshabilitar las pruebas de viewengine
- no necesitamos verificar que viewengine funciona
2020-09-29 15:06:57 -04:00
Michael Prentice
4d33c41e92 test: arreglar pruebas
- eliminar las pruebas que son específicas de ga
- arreglar pruebas e2e
- arreglar `deploy-to-firebase.test.sh`
- actualizar ``@angular/fire`
2020-09-29 15:06:57 -04:00
Michael Prentice
eff4e3e3c2 ci: eliminar las tareas que no sean relevantes para Angular Hispano
- nosotros no necesitamos probar el framework

Relates to #3
2020-09-29 15:06:57 -04:00
Michael Prentice
e6c7536d62 ci: eliminar todas las clases de recursos pagadas
- las pruebas están bloqueadas por clases de recursos no disponibles

Relates to #3
2020-09-29 15:06:57 -04:00
Michael Prentice
5f4a06039e docs: actualización del código de conducta de Angular Hispano 2020-09-29 13:51:19 -04:00
Michael Prentice
05b9bb71b1
docs: agregar sitio en inglés y traducir nombres de idiomas (#110)
* docs: agregar sitio en inglés y traducir nombres de idiomas

- Contribuyentes -> Colaboradores
- agregar `navigation.en.json`

Co-authored-by: Daniel Díaz <36966980+dalejodc@users.noreply.github.com>
2020-09-29 02:05:45 -04:00
José de Jesús Amaya
c7cae616e0
docs: architecture-modules.md traducido al español (#95)
Se traduce Introducción a los módulos

Co-authored-by: Alejandro Lora <alejandrofpo@gmail.com>
2020-09-29 02:01:26 -04:00
Antonio Cardenas
14daffecc5 Cambios en el template
Para mi es mas descriptivo si lo tomamos en pasado como por ejemplo que el usuario diga que probo todo antes de subirlo
2020-09-29 01:47:34 -04:00
Michael Prentice
f6ae7d4f49 docs: arreglar enlaces colgantes en toh-pt6 2020-09-28 20:46:27 -04:00
gelopfalcon
316d9d5c34 docs: Implementa feedback al archivo architecture-services 2020-09-27 21:27:24 -04:00
gelopfalcon
ba99c7792a docs: Implementa feedback al archivo architecture-services 2020-09-27 21:27:24 -04:00
gelopfalcon
66a2af0c77 docs: Implementa feedback al archivo architecture-services 2020-09-27 21:27:24 -04:00
gelopfalcon
ab87527e1d docs: traduce el archivo architecture-services 2020-09-27 21:27:24 -04:00
Daniel
a0486577a8 docs: actualiza el archivo docs.md 2020-09-25 10:19:03 -04:00
Antonio Cardenas
6f4c65c029 Cambios sugeridos 2020-09-25 10:08:09 -04:00
Antonio Cardenas
295f3796c6 Correciones 2020-09-25 10:08:09 -04:00
Antonio Cardenas
6362ec46d5 Se tradujo el index de Tour of Heroes
- Se agrego la version en ingles .en.md
- Se Probo previamente
2020-09-25 10:08:09 -04:00
Antonio Cardenas
de2b1c4bb4 correcciones sugeridas 2020-09-25 10:05:16 -04:00
Antonio Cardenas
6aad16e11f Cambios conforme a comentarios 2020-09-25 10:05:16 -04:00
Antonio Cardenas
78b657e8f3 Cambios en typos 2020-09-25 10:05:16 -04:00
Antonio Cardenas
ee9e65ecb1 traducción completa de navigation.json 2020-09-25 10:05:16 -04:00
José de Jesús Amaya
5341121fde Update aio/content/guide/architecture.md
Co-authored-by: Daniel Díaz <36966980+dalejodc@users.noreply.github.com>
2020-09-25 10:03:06 -04:00
José de Jesús Amaya
265581e525 Update aio/content/guide/architecture.md
Co-authored-by: Daniel Díaz <36966980+dalejodc@users.noreply.github.com>
2020-09-25 10:03:06 -04:00
José de Jesús Amaya
06da025393 Update aio/content/guide/architecture.md
Co-authored-by: Daniel Díaz <36966980+dalejodc@users.noreply.github.com>
2020-09-25 10:03:06 -04:00
José de Jesús Amaya
317bbd8f46 Update aio/content/guide/architecture.md
Co-authored-by: Daniel Díaz <36966980+dalejodc@users.noreply.github.com>
2020-09-25 10:03:06 -04:00
José de Jesús Amaya
9cb99bbaa8 Update aio/content/guide/architecture.md
Co-authored-by: Daniel Díaz <36966980+dalejodc@users.noreply.github.com>
2020-09-25 10:03:06 -04:00
José de Jesús Amaya
8a70ac0950 Update aio/content/guide/architecture.md
Co-authored-by: Daniel Díaz <36966980+dalejodc@users.noreply.github.com>
2020-09-25 10:03:06 -04:00
José de Jesús Amaya
9956446ad7 Update aio/content/guide/architecture.md
Co-authored-by: Daniel Díaz <36966980+dalejodc@users.noreply.github.com>
2020-09-25 10:03:06 -04:00
josedejesusAmaya
f0865de125 docs: architecture.md traducido al español
Se traduce Introducción a los conceptos de Angular.
2020-09-25 10:03:06 -04:00
Antonio Cardenas
5cb6779305 Arreglos sugeridos 2020-09-25 10:01:31 -04:00
Antonio Cardenas
1e2e9201b2 docs: translate tutorial/toh-pt6.md
- Se agrego la versión en ingles .en.md
- Se Probo previamente
2020-09-25 10:01:31 -04:00
Nicolas Molina Monroy
6062e658db
docs: translate guide/creating-libraries (#89)
* docs: translate guide/creating-libraries

* Update aio/content/guide/creating-libraries.es.md

Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>

* Update aio/content/guide/creating-libraries.es.md

Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>

* Update aio/content/guide/creating-libraries.es.md

Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>

* Update aio/content/guide/creating-libraries.es.md

Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>

* Update aio/content/guide/creating-libraries.es.md

Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>

* Update aio/content/guide/creating-libraries.es.md

Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>

* Update aio/content/guide/creating-libraries.es.md

Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>

* Update aio/content/guide/creating-libraries.es.md

Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>

* Update aio/content/guide/creating-libraries.es.md

Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>

* Update aio/content/guide/creating-libraries.es.md

Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>

* Update aio/content/guide/creating-libraries.es.md

Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>

* Update aio/content/guide/creating-libraries.es.md

Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>

* Update aio/content/guide/creating-libraries.es.md

Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>

* Update aio/content/guide/creating-libraries.es.md

Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>

* Update aio/content/guide/creating-libraries.es.md

Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>

* Update aio/content/guide/creating-libraries.es.md

Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>

* Update aio/content/guide/creating-libraries.es.md

Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>

* Update aio/content/guide/creating-libraries.es.md

Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>

* Update aio/content/guide/creating-libraries.es.md

Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>

* Update aio/content/guide/creating-libraries.es.md

Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>

* Update aio/content/guide/creating-libraries.es.md

Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>

* Update aio/content/guide/creating-libraries.es.md

Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>

* docs: translate guide/creating-libraries

* docs: translate guide/creating-libraries

Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>
2020-09-06 17:55:14 -04:00
Gustavo Rodríguez
eca92ea193
docs: translate guide/roadmap.md (#66)
* docs: translate guide/roadmap.md

* docs: change librería to biblioteca like glossary

* Update aio/content/guide/roadmap.md

Co-authored-by: Daniel Díaz <36966980+dalejodc@users.noreply.github.com>
2020-09-06 17:54:17 -04:00
Gustavo Rodríguez
3177ce1f35
docs: glossary.md change biblioteca to librería (#91) 2020-09-06 17:53:21 -04:00
Michael Prentice
faa17f8959 feat(docs-infra): switch from GA to Firebase Analytics
- enable Firebase Performance

Fixes #6
2020-08-25 02:55:34 -04:00
Daniel
d42a09e9b6 docs: actualiza el archivo CONTRUBUTING.md
Actualiza el archivo CONTRIBUTING.md basado en las observaciones de la revisión de código.
2020-08-24 13:48:28 -04:00
Gustavo Rodríguez
408d38b223
docs: translate guide/attribute-binding.md file to Spanish (#53)
Co-authored-by: Alejandro Lora <alejandrofpo@gmail.com>
Co-authored-by: Pato <11162114+devpato@users.noreply.github.com>
Co-authored-by: José de Jesús Amaya <impepedev@gmail.com>

Closes #25
2020-08-24 13:46:47 -04:00
Joel Rivera
333a1266cc
build: translate readme.md to spanish (#54)
Fixes #44
2020-08-24 13:43:22 -04:00
Michael Prentice
a4912ff297 docs: hacer que el archivo README.md sea más aplicable a este repositorio
- aclarar que el trabajo de bugs / características debe realizarse upstream
- cambiar los enlaces para que apunten dentro del repositorio en lugar de a la web
2020-08-23 22:39:41 -04:00
Michael Prentice
a9920d6776 docs: enlace a las guías de MDN en español
- use el enlace CoC correcto
2020-08-17 23:19:48 -04:00
Gustavo Rodríguez
71b1f1ad88
docs: translate guide/glossary.md file to Spanish (#49)
* docs: change angular to Angular
* docs: change Consultá to consulta
* docs: change CLI Angular to Angular CLI
* docs: fix typo
* docs: change puede to puedes
* docs: add glossary.en.md file

Co-authored-by: Michael Prentice <splaktar@gmail.com>
2020-08-15 22:53:03 -04:00
Alejandro Lora
a198e2984c
docs: translate comparing-observables.md (#57)
* docs: keep the english version of comparing-observables.md file as *.en.md file
2020-08-15 21:58:19 -04:00
Michael Prentice
e160d8466c
Merge pull request #62 from angular-hispano/merge-upstream
Merge 10.0.8 y 10.1.0-next.4
2020-08-15 20:51:35 -04:00
Michael Prentice
575479a6a1
upstream: Merge remote-tracking branch 'upstream/master' into merge-upstream
# Conflicts:
#	CHANGELOG.md
#	aio/content/examples/testing/src/app/app.component.router.spec.ts
#	aio/content/examples/testing/src/app/dashboard/dashboard-hero.component.spec.ts
#	aio/content/examples/testing/src/app/dashboard/dashboard.component.spec.ts
#	aio/content/examples/testing/src/app/hero/hero-detail.component.spec.ts
#	aio/content/examples/testing/src/app/hero/hero-list.component.spec.ts
#	aio/content/examples/testing/src/app/twain/twain.component.spec.ts
#	goldens/public-api/core/testing/testing.d.ts
#	goldens/size-tracking/aio-payloads.json
#	package.json
#	packages/core/test/bundling/forms/bundle.golden_symbols.json
#	packages/forms/test/form_group_spec.ts
2020-08-15 20:48:38 -04:00
Michael Prentice
8b97de61f5
fix(dev-infra): add an upstream commit message type
- don't require a commit body for it
2020-08-15 20:46:39 -04:00
Daniel Díaz
d870e5c309
docs: translate CONTRIBUTING.md to spanish (#58)
* docs: translate CONTRIBUTING.md to spanish

Translate CONTRIBUTING.md to spanish

Fix #48

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

Co-authored-by: Pato <11162114+devpato@users.noreply.github.com>
2020-08-15 20:27:22 -04:00
Christian Morante
2da56a70a2
docs: traducida la guia Intro (#60)
* docs: traducida la guia Intro

Se traduce la guia de Introduccion a la documentacion de Angular

* docs: Correecciones de la 1era revisión
2020-08-15 19:31:09 -04:00
Joey Perrott
0b2f134680 fix(compiler): update unparsable character reference entity error messages (#38319)
Within an angular template, when a character entity is unable to be parsed, previously a generic
unexpected character error was thrown.  This does not properly express the issue that was discovered
as the issue is actually caused by the discovered character making the whole of the entity unparsable.
The compiler will now instead inform via the error message what string was attempted to be parsed
and what it was attempted to be parsed as.

Example, for this template:
```
<p>
  &#x123p
</p>
```
Before this change:
`Unexpected character "p"`

After this change:
`Unable to parse entity "&#x123p" - hexadecimal character reference entities must end with ";"`

Fixes #26067

PR Close #38319
2020-08-07 22:10:55 -04:00
George Kalpakas
5d32a199a9 refactor(docs-infra): update docs examples tslint.json to match CLI and fix failures (#38143)
This commit updates the `tslint.json` configuration file, that is used
to lint the docs examples, to match the one generated for new Angular
CLI apps. There are some minimal differences (marked with `TODO`
comments) for things, such as component selector prefix, that would
require extensive and/or difficult to validate changes in guides.

This commit also includes the final adjustments to make the docs
examples code compatible with the new tslint rules. (The bulk of the
work has been done in previous commits.)

PR Close #38143
2020-08-07 22:10:55 -04:00
George Kalpakas
f677c22fba refactor(docs-infra): fix docs examples for Angular-specific tslint rules (#38143)
This commit updates the docs examples to be compatible with the
following Angular-specific tslint rules:
- `component-selector`
- `directive-selector`
- `no-conflicting-lifecycle`
- `no-host-metadata-property`
- `no-input-rename`
- `no-output-native`
- `no-output-rename`

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-08-07 22:10:55 -04:00
George Kalpakas
97ae2d3b9b refactor(docs-infra): fix docs examples for tslint rule prefer-const (#38143)
This commit updates the docs examples to be compatible with the
`prefer-const` tslint rule.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-08-07 22:10:55 -04:00
George Kalpakas
a3fe2de883 refactor(docs-infra): fix docs examples for tslint rules related to underscores in variable names (#38143)
This commit updates the docs examples to be compatible with the
`variable-name` tslint rule without requiring the
`allow-leading-underscore` and `allow-trailing-underscore` options.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-08-07 22:10:55 -04:00
George Kalpakas
7f6c3b3fc1 refactor(docs-infra): fix docs examples for tslint rules related to variable names (#38143)
This commit updates the docs examples to be compatible with the
`no-shadowed-variable` and `variable-name` tslint rules.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-08-07 22:10:55 -04:00
George Kalpakas
ab4ab682e5 refactor(docs-infra): fix docs examples for tslint rule member-ordering (#38143)
This commit updates the docs examples to be compatible with the
`member-ordering` tslint rule.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-08-07 22:10:55 -04:00
George Kalpakas
a69cb738a8 refactor(docs-infra): fix docs examples for tslint rule no-angle-bracket-type-assertion (#38143)
This commit updates the docs examples to be compatible with the
`no-angle-bracket-type-assertion` tslint rule.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-08-07 22:10:55 -04:00
George Kalpakas
e9eeee5608 refactor(docs-infra): fix docs examples for tslint rules related to object properties (#38143)
This commit updates the docs examples to be compatible with the
`no-string-literal`, `object-literal-key-quotes` and
`object-literal-shorthand` tslint rules.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-08-07 22:10:55 -04:00
George Kalpakas
d89ab70036 refactor(docs-infra): fix docs examples for tslint rule only-arrow-functions (#38143)
This commit updates the docs examples to be compatible with the
`only-arrow-functions` tslint rule.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-08-07 22:10:55 -04:00
George Kalpakas
fa82a82a07 style(docs-infra): fix docs examples for tslint rule jsdoc-format (#38143)
This commit updates the docs examples to be compatible with the
`jsdoc-format` tslint rule.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-08-07 22:10:55 -04:00
George Kalpakas
39f92d985b style(docs-infra): fix docs examples for tslint rule semicolon (#38143)
This commit updates the docs examples to be compatible with the
`semicolon` tslint rule.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-08-07 22:10:55 -04:00
George Kalpakas
da0129b83e style(docs-infra): fix docs examples for tslint rules related to whitespace (#38143)
This commit updates the docs examples to be compatible with the `align`,
`space-before-function-paren` and `typedef-whitespace` tslint rules.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-08-07 22:10:55 -04:00
George Kalpakas
c980caecac style(docs-infra): fix docs examples for tslint rule import-spacing (#38143)
This commit updates the docs examples to be compatible with the
`import-spacing` tslint rule.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-08-07 22:10:55 -04:00
George Kalpakas
b88abd81c8 refactor(docs-infra): remove unnecessary use strict from docs examples TS files (#38143)
By default, TypeScript will emit `"use strict"` directives, so it is not
necessary to include `'use strict'` in `.ts` files:
https://www.typescriptlang.org/docs/handbook/compiler-options.html#:~:text=--noImplicitUseStrict

PR Close #38143
2020-08-07 22:10:55 -04:00
George Kalpakas
201c38e407 refactor(docs-infra): remove unused styleguide examples (#38143)
The `03-*` code style rule have been removed from the style guide in
be0bc799f3fa99582238f29cb575e0705ce0c10f.

This commit removes the corresponding files and related unused code from
the`styleguide` example project.

PR Close #38143
2020-08-07 22:10:55 -04:00
Keen Yee Liau
31c53670e7 fix(language-service): [ivy] do not retrieve ts.Program at startup (#38120)
This commit removes compiler instantiation at startup.
This is because the constructor is invoked during the plugin loading phase,
in which the project has not been completely loaded.

Retrieving `ts.Program` at startup will trigger an `updateGraph` operation,
which could only be called after the Project has loaded completely.
Without this change, the Ivy LS cannot be loaded as a tsserver plugin.

Note that the whole `Compiler` class is temporary, so changes made there are
only for development. Once we have proper integration with ngtsc the
`Compiler` class would be removed.

PR Close #38120
2020-08-07 22:10:55 -04:00
Charles Lyding
e169f00193 fix(compiler): add PURE annotation to getInheritedFactory calls (#38291)
Currently the `getInheritedFactory` function is implemented to allow
closure to remove the call if the base factory is unused.  However, this
method does not work with terser.  By adding the PURE annotation,
terser will also be able to remove the call when unused.

PR Close #38291
2020-08-07 22:10:55 -04:00
Alex Rickabaugh
e1ee231993 docs: release notes for the v10.0.7 release 2020-08-07 22:10:55 -04:00
Keen Yee Liau
7d4aebd603 fix(compiler): Metadata should not include methods on Object.prototype (#38292)
This commit fixes a bug in View Engine whereby the compiler errorneously
thinks that a method of a component has decorator metadata when that
method is one of those in `Object.prototype`, for example `toString`.

This bug is discovered in v10.0.4 of `@angular/language-service` after
the default bundle format was switched from ES5 to ES2015.

ES5 output:
```js
if (propMetadata[propName]) {
    decorators.push.apply(decorators, __spread(propMetadata[propName]));
}
```

ES2015 output:
```js
if (propMetadata[propName]) {
    decorators.push(...propMetadata[propName]);
}
```

The bug was not discovered in ES5 because the polyfill for the spread
operator happily accepts parameters that do not have the `iterable`
symbol:

```js
function __spread() {
    for (var ar = [], i = 0; i < arguments.length; i++)
        ar = ar.concat(__read(arguments[i]));
    return ar;
}
```

whereas in es2015 it’ll fail since the iterable symbol is not present in
`propMetadata['toString']` which evaluates to a function.

Fixes https://github.com/angular/vscode-ng-language-service/issues/859

PR Close #38292
2020-08-07 22:10:55 -04:00
Alex Rickabaugh
2cde8da71c Revert "fix(compiler): mark NgModuleFactory construction as not side effectful (#38147)" (#38303)
This reverts commit 7f8c2225f2cba3dfcf3ec23e0fe08b7d2e3497e8.

This commit caused test failures internally, which were traced back to the
optimizer removing NgModuleFactory constructor calls when those calls caused
side-effectful registration of NgModules by their ids.

PR Close #38303
2020-08-07 22:10:55 -04:00
Andrew Kushnir
6f54c28c87 test(compiler-cli): disable one TypeChecker test on Windows due to path sensitivity issue (#38294)
This commit disables one TypeChecker test (added as a part of
https://github.com/angular/angular/pull/38105) which make assertions about the filename while
running on Windows.

Such assertions are currently suffering from a case sensitivity issue.

PR Close #38294
2020-08-07 22:10:55 -04:00
Andrew Scott
17841959f5 docs(router): clarify how base href is used to construct targets (#38123)
The documentation is not clear on how the base href and APP_BASE_HREF are used. This commit
should help clarify more complicated use-cases beyond the most common one of just a '/'

PR Close #38123
2020-08-07 22:10:55 -04:00
Doug Parker
cfe5fadb3a fix(compiler): mark NgModuleFactory construction as not side effectful (#38147)
This allows Closure compiler to tree shake unused constructor calls to `NgModuleFactory`, which is otherwise considered
side-effectful. The Angular compiler generates factory objects which are exported but typically not used, as they are
only needed for compatibility with View Engine. This results in top-level constructor calls, such as:

```typescript
export const FooNgFactory = new NgModuleFactory(Foo);
```

`NgModuleFactory` has a side-effecting constructor, so this statement cannot be tree shaken, even if `FooNgFactory` is
never imported. The `NgModuleFactory` continues to reference its associated `NgModule` and prevents the module and all
its unused dependencies from being tree shaken. This effectively prevents all components from being tree shaken, making
Closure builds significantly larger than they should be.

The fix here is to wrap `NgModuleFactory` constructor with `noSideEffects(() => /* ... */)`, which tricks the Closure
compiler into assuming that the invoked function has no side effects. This allows it to tree-shake unused
`NgModuleFactory()` constructors when they aren't imported. Since the factory can be removed, the module can also be
removed (if nothing else references it), thus tree shaking unused components as expected.

PR Close #38147
2020-08-07 22:10:55 -04:00
Doug Parker
3cd4a5ded5 refactor(compiler): wrap large strings in function (#38253)
Large strings constants are now wrapped in a function which is called whenever used. This works around a unique
limitation of Closure, where it will **always** inline string literals at **every** usage, regardless of how large the
string literal is or how many times it is used.The workaround is to use a function rather than a string literal.
Closure has differently inlining semantics for functions, where it will check the length of the function and the number
of times it is used before choosing to inline it. By using a function, `ngtsc` makes Closure more conservative about
inlining large strings, and avoids blowing up the bundle size.This optimization is only used if the constant is a large
string. A wrapping function is not included for other use cases, since it would just increase the bundle size and add
unnecessary runtime performance overhead.

PR Close #38253
2020-08-07 22:10:55 -04:00
crisbeto
36156244a1 docs: update bio picture (#38272)
Updates my profile picture which was quite old.

PR Close #38272
2020-08-07 22:10:55 -04:00
Sonu Kapoor
a66a804082 refactor(docs-infra): Lazy-loads SVG icons (#38268)
Prior to this commit, SVG icons were all loaded in the constructor
of the `CustomIconRegistry`. This commit avoids that, and loads SVG
icons on demand.

PR Close #38268
2020-08-07 22:10:55 -04:00
George Kalpakas
d2524eef7f refactor(docs-infra): simplify/improve CopierService hidden textarea creation (#38244)
This commit simplifies the creation of the temporary, hidden
`<textarea>` element used by `CopierService` by switching from absolute
to fixed positioning and not requiring page's scroll offset.

It also makes the following minor improvements:
- Make the element invisible (via `opacity: 0`).
- Instruct screen-readers to ignore the element (via
  `aria-hidden: true`).

NOTE: These improvements are based on Angular CDK's [PendingCopy][1]
      class and the changes proposed in PR angular/components#20073.

[1]: https://github.com/angular/components/blob/89b5fa89d1437c3054c5/src/cdk/clipboard/pending-copy.ts

PR Close #38244
2020-08-07 22:10:55 -04:00
George Kalpakas
f6d2af17fc fix(docs-infra): preserve focus on copy (and prevent scrolling to bottom on IE11) (#38244)
The `CopierService` is used for copying text to the user's clipboard. It
is, for example, used in `CodeComponent` to copy example code snippets.
This is implemented by creating a temporary, hidden `<textarea>`
elements, setting its value to the text that needs to be copied,
executing the `copy` command and finally removing the element from the
DOM.

Previously, as a result of `CopierService`'s implementation, the focused
element would lose focus, while the temporary `<textarea>` element would
implicitly gain focus when selecting its contents. This had an even
worse side-effect on IE11, which seems to scroll to the bottom of the
containing element (here `<body>`) when the focused element is removed.

This commit fixes these issues by keeping track of the previously
focused element and restoring its focus after the copy operation.

NOTE: This fix is inspired by Angular CDK's [PendingCopy][1] class.

[1]: https://github.com/angular/components/blob/89b5fa89d1437c3054c5/src/cdk/clipboard/pending-copy.ts

Fixes #37796

PR Close #38244
2020-08-07 22:10:55 -04:00
George Kalpakas
a86754b4c4 refactor(docs-infra): improve code readability of CopierService (#38244)
This commit improves the code readability of the `CopierService` by:
- Adding/Improving JSDoc comments for methods.
- Avoiding unnecessary instance-wide properties.
- Fixing indentation to be consistent (at two spaces).
- Clearly separating the logic for creating and populating a
  `<textarea>` from the logic for selecting and copying its contents.

PR Close #38244
2020-08-07 22:10:55 -04:00
Alex Rickabaugh
2968435f81 refactor(compiler-cli): support type-checking a single component (#38105)
This commit adds a method `getDiagnosticsForComponent` to the
`TemplateTypeChecker`, which does the minimum amount of work to retrieve
diagnostics for a single component.

With the normal `ReusedProgramStrategy` this offers virtually no improvement
over the standard `getDiagnosticsForFile` operation, but if the
`TypeCheckingProgramStrategy` supports separate shims for each component,
this operation can yield a faster turnaround for components that are
declared in files with many other components.

PR Close #38105
2020-08-07 22:10:55 -04:00
Alex Rickabaugh
4096bbfeee refactor(compiler-cli): add TemplateId to template diagnostics (#38105)
Previously, a stable template id was implemented for each component in a
file. This commit adds this id to each `TemplateDiagnostic` generated from
the template type-checker, so it can potentially be used for filtration.

PR Close #38105
2020-08-07 22:10:55 -04:00
Alex Rickabaugh
0314fd4b6e refactor(compiler-cli): allow overriding templates in the type checker (#38105)
This commit adds an `overrideComponentTemplate` operation to the template
type-checker. This operation changes the template used during template
type-checking operations.

Overriding a template causes any previous work for it to be discarded, and
the template type-checking engine will regenerate the TCB for that template
on the next request.

This operation can be used by a consumer such as the language service to
get rapid feedback or diagnostics as the user is editing a template file,
without the need for a full incremental build iteration.

Closes #38058

PR Close #38105
2020-08-07 22:10:55 -04:00
Alex Rickabaugh
3f2257f209 refactor(compiler-cli): efficient single-file type checking diagnostics (#38105)
Previously, the `TemplateTypeChecker` abstraction allowed fetching
diagnostics for a single file, but under the hood would generate type
checking code for the entire program to satisfy the request.

With this commit, an `OptimizeFor` hint is passed to `getDiagnosticsForFile`
which indicates whether the user intends to request diagnostics for the
whole program or is truly interested in just the single file. If the latter,
the `TemplateTypeChecker` can perform only the work needed to produce
diagnostics for just that file, thus returning answers more efficiently.

PR Close #38105
2020-08-07 22:10:55 -04:00
Alex Rickabaugh
271e0f9896 refactor(compiler-cli): allow program strategies to opt out of inlining (#38105)
The template type-checking engine relies on the abstraction interface
`TypeCheckingProgramStrategy` to create updated `ts.Program`s for
template type-checking. The basic API is that the type-checking engine
requests changes to certain files in the program, and the strategy provides
an updated `ts.Program`.

Typically, such changes are made to 'ngtypecheck' shim files, but certain
conditions can cause template type-checking to require "inline" operations,
which change user .ts files instead. The strategy used by 'ngc' (the
`ReusedProgramStrategy`) supports these kinds of updates, but other clients
such as the language service might not always support modifying user files.

To accommodate this, the `TypeCheckingProgramStrategy` interface was
modified to include a `supportsInlineOperations` flag. If an implementation
specifies `false` for inline support, the template type-checking system will
return diagnostics on components which would otherwise require inline
operations.

Closes #38059

PR Close #38105
2020-08-07 22:10:55 -04:00
Alex Rickabaugh
79b5e1891d refactor(compiler-cli): introduce the TemplateTypeChecker abstraction (#38105)
This commit significantly refactors the 'typecheck' package to introduce a
new abstraction, the `TemplateTypeChecker`. To achieve this:

* a 'typecheck:api' package is introduced, containing common interfaces that
  consumers of the template type-checking infrastructure can depend on
  without incurring a dependency on the template type-checking machinery as
  a whole.
* interfaces for `TemplateTypeChecker` and `TypeCheckContext` are introduced
  which contain the abstract operations supported by the implementation
  classes `TemplateTypeCheckerImpl` and `TypeCheckContextImpl` respectively.
* the `TemplateTypeChecker` interface supports diagnostics on a whole
  program basis to start with, but the implementation is purposefully
  designed to support incremental diagnostics at a per-file or per-component
  level.
* `TemplateTypeChecker` supports direct access to the type check block of a
  component.
* the testing utility is refactored to be a lot more useful, and new tests
  are added for the new abstraction.

PR Close #38105
2020-08-07 22:10:55 -04:00
Alex Rickabaugh
b4b453d6de refactor(compiler-cli): make file/shim split 1:n instead of 1:1 (#38105)
Previously in the template type-checking engine, it was assumed that every
input file would have an associated type-checking shim. The type check block
code for all components in the input file would be generated into this shim.

This is fine for whole-program type checking operations, but to support the
language service's requirements for low latency, it would be ideal to be
able to check a single component in isolation, especially if the component
is declared along with many others in a single file.

This commit removes the assumption that the file/shim mapping is 1:1, and
introduces the concept of component-to-shim mapping. Any
`TypeCheckingProgramStrategy` must provide such a mapping.

To achieve this:

 * type checking record information is now split into file-level data as
   well as per-shim data.
 * components are now assigned a stable `TemplateId` which is unique to the
   file in which they're declared.

PR Close #38105
2020-08-07 22:10:55 -04:00
Andrea Canciani
06f085560c fix(common): narrow NgIf context variables in template type checker (#36627)
When the `NgIf` directive is used in a template, its context variables
can be used to capture the bound value. This is sometimes used in
complex expressions, where the resulting value is captured in a
context variable. There's two syntax forms available:

1. Binding to `NgIfContext.ngIf` using the `as` syntax:
```html
<span *ngIf="enabled && user as u">{{u.name}}</span>
```

2. Binding to `NgIfContext.$implicit` using the `let` syntax:
```html
<span *ngIf="enabled && user; let u">{{u.name}}</span>
```

Because of the semantics of `ngIf`, it is known that the captured
context variable is truthy, however the template type checker
would not consider them as such and still report errors when
`strict` is enabled.

This commit updates `NgIf`'s context guard to make the types of the
context variables truthy, avoiding the issue.

Based on https://github.com/angular/angular/pull/35125

PR Close #36627
2020-08-07 22:10:55 -04:00
Misko Hevery
38fb735551 Revert "refactor(platform-browser): specify return type of parseEventName (#38089)"
This reverts commit 174aac68f7cfb9760430c42a4f53b91f8a48c738.
2020-08-07 22:10:55 -04:00
Misko Hevery
b0ecee8155 release: cut the v10.1.0-next.3 release 2020-08-07 22:10:55 -04:00
Misko Hevery
ba46a0c05b docs: release notes for the v10.0.6 release 2020-08-07 22:10:55 -04:00
Misko Hevery
0112164c34 build: fix broken build (#38274)
```
export const __core_private_testing_placeholder__ = '';
```
This API should be removed. But doing so seems to break `google3` and
so it requires a bit of investigation. A work around is to mark it as
`@codeGenApi` for now and investigate later.

PR Close #38274
2020-08-07 22:10:55 -04:00
Joey Perrott
f60fafbb2e Revert "ci: roll back phased review conditions" (#38259)
This reverts commit ca8eafc2983f983803cd03e4a08bf732672712dd.

PR Close #38259
2020-08-07 22:10:55 -04:00
Joey Perrott
004079b07a ci: only check active groups for the no-groups-above-this-* checks (#38259)
Since PullApprove starts all inactive groups as a pending state, to properly
assess if any groups we care about are pending we must only check the active
groups.  We additionally do this with rejected because the intention of the
reusable checks is around checking active rules only.

PR Close #38259
2020-08-07 22:10:55 -04:00
Judy Bogart
523a1a71d7 docs(elements): update api doc for custom elements (#38252)
by adding cross-references to Angular Elements Overview guide.

PR Close #38252
2020-08-07 22:10:55 -04:00
Ajit Singh
d3999d904a fix(core): Attribute decorator attributeName is mandatory (#38131)
`Attribute` decorator has defined `attributeName` as optional but actually its
 mandatory and compiler throws an error if `attributeName` is undefined. Made
`attributeName` mandatory in the `Attribute` decorator to reflect this functionality

Fixes #32658

PR Close #38131
2020-08-07 22:10:55 -04:00
Ahn
63894062d4 docs(core): correct SomeService to SomeComponent (#38264)
PR Close #38264
2020-08-07 22:10:55 -04:00
Judy Bogart
5c60a65eaf docs: update api reference doc for router-link-active directive (#38247)
Edits and organizes the usage information for the directive.

PR Close #38247
2020-08-07 22:10:55 -04:00
Andrew Scott
c387933d3c ci: roll back phased review conditions (#38257)
It was determined that the list of 'pending' groups also included inactive groups.
That means that the 'no-groups-above-this-pending' would generally fail because
there's almost always some inactive group above it.

This commit removes the conditions for phased review while we
investigate if the inactive groups can be excluded.

PR Close #38257
2020-08-07 22:10:55 -04:00
Tony Bove
882336e0e6 docs: Refactor module-types.md to make it easier to understand (#38206)
Project DOCS-736 to rewrite headings to focus on user tasks,
verify that the content is up-to-date and complete, and
add relevant links to other NgModule topics to improve readability.
Also addresses one of many issues in GitHub issue 21531.

PR Close #38206
2020-08-07 22:10:55 -04:00
Jeremy Elbourn
e91aa6db32 ci: add more owners for limited categories (#38170)
* Add alxhub, atscott, and AndrewKushnir to code owners
* Add atscott & AndrewKushnir to public-api and size-tracking

Follow-up to #37994

PR Close #38170
2020-08-07 22:10:55 -04:00
Tony Bove
325b3fd0db docs: Refactor ngmodule-vs-jsmodule.md to make it easier to understand (#38148)
Project DOCS-734 to rewrite headings to focus on user tasks,
verify that the content is up-to-date and complete, and
add relevant links to other NgModule topics to improve readability.
Also addresses one of many issues in GitHub issue 21531.

PR Close #38148
2020-08-07 22:10:55 -04:00
JiaLiPassion
84348299b3 fix(core): unify the signature between ngZone and noopZone (#37581)
Now we have two implementations of Zone in Angular, one is NgZone, the other is NoopZone.
They should have the same signatures, includes
1. properties
2. methods

In this PR, unify the signatures of the two implementations, and remove the unnecessary cast.

PR Close #37581
2020-08-07 22:10:55 -04:00
Misko Hevery
e934864a90 Revert "refactor(core): remove unused export (#38224)"
This reverts commit fbe1a9cbaaec91bb5ca8d1b47ebd7b6363ae6568.
2020-08-07 22:10:55 -04:00
Andrew Scott
920205bc61 fix(compiler-cli): Add support for string literal class members (#38226)
The current implementation of the TypeScriptReflectionHost does not account for members that
are string literals, i.e. `class A { 'string-literal-prop': string; }`

PR Close #38226
2020-08-07 22:10:55 -04:00
Judy Bogart
0dcc34837e docs: update api reference doc for router link directive (#38181)
Edits and organizes the usage information for the directive.

PR Close #38181
2020-08-07 22:10:55 -04:00
Sonu Kapoor
57d8d7fcd4 refactor(platform-browser): specify return type of parseEventName (#38089)
This commit refactors the argument of the `parseEventName` function
to use an object with named properties instead of using an object indexer.

PR Close #38089
2020-08-07 22:10:55 -04:00
Igor Minar
f26f014ffc test: update ts-api-guardian's strip_export_pattern to exclude Ivy instructions (#38224)
Previously the instructions were included in the golden files to monitor the frequency and rate of
the instruction API changes for the purpose of understanding the stability of this API (as it was
considered for becoming a public API and deployed to npm via generated code).

This experiment has confirmed that the instruction API is not stable enough to be used as public
API. We've since also came up with an alternative plan to compile libraries with the Ivy compiler
for npm deployment and this plan does not rely on making Ivy instructions public.

For these reasons, I'm removing the instructions from the golden files as it's no longer important
to track them.

The are three instructions that are still being included: `ɵɵdefineInjectable`, `ɵɵinject`, and
`ɵɵInjectableDef`.

These instructions are already generated by the VE compiler to support tree-shakable providers, and
code depending on these instructions is already deployed to npm. For this reason we need to treat
them as public api.

This change also reduces the code review overhead, because changes to public api golden files now
require multiple approvals.

PR Close #38224
2020-08-07 22:10:55 -04:00
Igor Minar
134aa72467 refactor(core): remove unused export (#38224)
This export used to be here to turn this file into an ES Module - this is no longer needed
because the file contains imports.

PR Close #38224
2020-08-07 22:10:55 -04:00
Igor Minar
a7a8938291 refactor: correct @publicApi and @codeGenApi markers in various files (#38224)
The markers were previously incorrectly assigned. I noticed the issues when reviewing
the golden files and this change corrects them.

PR Close #38224
2020-08-07 22:10:55 -04:00
JiaLiPassion
9338556872 fix(zone.js): zone patch rxjs should return null _unsubscribe correctly. (#37091)
Close #31684.

In some rxjs operator, such as `retryWhen`, rxjs internally will set
`Subscription._unsubscribe` method to null, and the current zone.js monkey patch
didn't handle this case correctly, even rxjs set _unsubscribe to null, zone.js
still return a function by finding the prototype chain.

This PR fix this issue and the following test will pass.

```
const errorGenerator = () => {
  return throwError(new Error('error emit'));
};

const genericRetryStrategy = (finalizer: () => void) => (attempts: Observable<any>) =>
    attempts.pipe(
      mergeMap((error, i) => {
        const retryAttempt = i + 1;
        if (retryAttempt > 3) {
          return throwError(error);
        }
        return timer(retryAttempt * 1);
      }),
      finalize(() => finalizer()));

errorGenerator()
  .pipe(
    retryWhen(genericRetryStrategy(() => {
      expect(log.length).toBe(3);
      done();
    })),
    catchError(error => of(error)))
  .subscribe()
```

PR Close #37091
2020-08-07 22:10:55 -04:00
Kapunahele Wong
28ef4bc441 docs: add template ref var to glossary (#36743)
There is not an entry in the glossary for template
reference variable. To clarify for site visitors,
we are adding one here.

PR Close #36743
2020-08-07 22:10:55 -04:00
Omar Hasan
686f9ae4b2 docs: fix breaking URL for RxJS marble testing (#38209)
When checking this URL for the `RxJS marble testing` Ive found it pointing to `Page not found`

PR Close #38209
2020-08-07 22:10:55 -04:00
Changyu Geng
a57119761b docs: clarify the description of pipes (#37950)
This commit clarifies some of the language regarding pipes in the pipes guide.
This commit also specifies the term transforming rather than formatting.

PR Close #37950
2020-08-07 22:10:55 -04:00
Andrew Kushnir
6881149540 fix(compiler): share identical stylesheets between components in the same file (#38213)
Prior to this commit, duplicated styles defined in multiple components in the same file were not
shared between components, thus causing extra payload size. This commit updates compiler logic to
use `ConstantPool` for the styles (while generating the `styles` array on component def), which
enables styles sharing when needed (when duplicates styles are present).

Resolves #38204.

PR Close #38213
2020-08-07 22:10:55 -04:00
Andrew Kushnir
4f842e23df refactor(compiler): allow strings with certain length to be included into ConstantPool (#38213)
Prior to this commit, the `ConstantPool` ignored all primitive values. It turned out that it's
beneficial to include strings above certain length to the pool as well. This commit updates the
`ConstantPool` logic to allow such strings to be shared across multiple instances if needed.
For instance, this is helpful for component styles that might be reused across multiple components
in the same file.

PR Close #38213
2020-08-07 22:10:55 -04:00
Andrew Kushnir
47873a339a refactor(compiler): separate compilation and transform phases (#38213)
This commit splits the transformation into 2 separate steps: Ivy compilation and actual transformation
of corresponding TS nodes. This is needed to have all `o.Expression`s generated before any TS transforms
happen. This allows `ConstantPool` to properly identify expressions that can be shared across multiple
components declared in the same file.

Resolves #38203.

PR Close #38213
2020-08-07 22:10:55 -04:00
Tim Deschryver
03e02185d9 docs: add ng-add save option (#38198)
PR Close #38198
2020-08-07 22:10:55 -04:00
Andrew Kushnir
e565d97bc8 refactor(router): extract Router config utils to a separate file (#38229)
This commit refactors Router package to move config utils to a separate file for better
organization and to resolve the problem with circular dependency issue.

Resolves #38212.

PR Close #38229
2020-08-07 22:10:55 -04:00
Andrew Scott
6bf8d2b356 fix(dev-infra): Ensure conditions with groups do not fail verification (#37798)
There are a few changes in this PR to ensure conditions that are based
on groups (i.e. `- groups.pending.length == 0`) do not fail the verify
task:

* Remove the warning when a condition is encountered that depends on the
`groups` state. The warning will otherwise be printed once for every
file that triggers the execution of the condition (400,000+ times)
* Add an `unverifiable` flag to `GroupCondition` interface and set it to
true when an error is encountered due to attempting to get the state of
`groups` in a condition
* Ignore any unverifiable conditions when gathering unmatched
conditions. These should not be considered `unmatched` for verification
purposes.
* Print the unverifiable conditions by group in the results

Sample output:
```

┌──────────────────────────────────────────────────────────────────────────────┐
│                         PullApprove results by group                         │
└──────────────────────────────────────────────────────────────────────────────┘
Groups skipped (4 groups)
Matched conditions by Group (37 groups)
Unmatched conditions by Group (0 groups)
Unverifiable conditions by Group (3 groups)
  [public-api]
    len(groups.pending.exclude("required-minimum-review")...
    len(groups.rejected.exclude("required-minimum-review")...
  [size-tracking]
    len(groups.pending.exclude("required-minimum-review")...
    len(groups.rejected.exclude("required-minimum-review")...
  [circular-dependencies]
    len(groups.pending.exclude("required-minimum-review")...
    len(groups.rejected.exclude("required-minimum-review")...

```

PR Close #37798
2020-08-07 22:10:55 -04:00
Andrew Scott
2981656ebe feat(dev-infra): add phased review to groups requiring final sign-off after initial review (#37798)
The size-tracking, public-api, and circular-dependencies groups can get a lot of
PRs to review. In addition, the members of these groups do not always
have the necessary context to fully review the PR in question. This
change ensures that the owners in the groups where the changes are being
made have approve the changes (ie, the aren't pending or rejected)
before requesting final sign-off from these three critical groups.

PR Close #37798
2020-08-07 22:10:55 -04:00
Andrew Scott
5ec0ba72cd refactor(dev-infra): create anchors/aliases for excluded always active groups (#37798)
global-approvers, global-docs-approvers, and required-minimum-review groups are always active. It's useful
to have aliases for getting groups that are active/pending/rejected while excluding these few.

PR Close #37798
2020-08-07 22:10:55 -04:00
JiaLiPassion
f020941629 docs(zone.js): update zone.js bundle doc since the APF change (#37919)
Since the PR #36540 change the zone.js bundles to Angular Package Format, the
bundle name/location are changed, so this PR updated the `README.md` doc for the
zone bundles.
Also add the recent added new bundles `zone-patch-message-port` doc.

PR Close #37919
2020-08-07 22:10:55 -04:00
JiaLiPassion
f1a92872a4 fix(zone.js): patch nodejs EventEmtter.prototype.off (#37863)
Close #35473

zone.js nodejs patch should also patch `EventEmitter.prototype.off` as `removeListener`.
So `off` can correctly remove the listeners added by `EventEmitter.prototype.addListener`

PR Close #37863
2020-08-07 22:10:55 -04:00
JiaLiPassion
9e7ce2c916 fix(zone.js): clearTimeout/clearInterval should call on object global (#37858)
Close #37333

`clearTimeout` is patched by `zone.js`, and it finally calls the native delegate of `clearTimeout`,
the current implemention only call `clearNative(id)`, but it should call on object `global` like
`clearNative.call(global, id)`. Otherwise in some env, it will throw error
`clearTimeout called on an object that does not implement interface Window`

PR Close #37858
2020-08-07 22:10:55 -04:00
JiaLiPassion
788532dc99 feat(zone.js): move MutationObserver/FileReader to different module (#31657)
Separate `EventTarget`, `FileReader`, `MutationObserver` and `IntersectionObserver` patches into different module.
So the user can disable those modules separately.

PR Close #31657
2020-08-07 22:10:55 -04:00
Andrii
54679ea9cc docs: Fix link by removing a space (#38214)
PR Close #38214
2020-08-07 22:10:55 -04:00
Andrew Scott
cb0aeaf708 docs(core): Fix incorrectly rendered code example in structural directives guide (#38207)
The code example was missing a close brace and also incorrectly rendered
the template div as an actual div in the page DOM.

PR Close #38207
2020-08-07 22:10:55 -04:00
k-ta-yamada
8de04115ec docs: fixed that class attribute is not closed (#38219)
PR Close #38219
2020-08-07 22:10:55 -04:00
George Kalpakas
e65e5ea9d0 build(docs-infra): simplify ExampleZipper by removing PackageJsonCustomizer (#38192)
Previously, `ExampleZipper` (the tool used for creating ZIP archives
from our docs examples) used the `PackageJsonCustomizer` to generate
`package.json` files for each example type. This had the following
drawbacks:
- The generated files had to be kept up-to-date with the corresponding
  boilerplate files in `aio/tools/examples/shared/boilerplate/` and
  there was no easy way to find out when the files got out-of-sync.
- The `PackageJsonCustomizer` logic was non-trivial and difficult to
  reason about.
- The same information was duplicated in the boilerplate files and the
  customizer configuration files.

This setup was useful when we used a single `package.json` file for all
docs examples. Now, however, each example type can have its own
boilerplate `package.json` file, including scripts and dependencies
relevant to the example type. Therefore, it is no longer necessary to
generate `package.json` files for ZIP archives.

This commit eliminates the drawbacks mentioned above and simplifies the
`ExampleZipper` tool by removing `PackageJsonCustomizer` and re-using
the boilerplate `package.json` files for ZIP archives.

The changes in this commit also fix some ZIP archives that were
previously broken (for example due to missing dependencies).

PR Close #38192
2020-08-07 22:10:55 -04:00
Saif
19b577bf66 fix(docs-infra): correctly display copy button in IE11 (#38186)
Fix button top portion was clipped in IE11 by setting overflow to visible

Fixes #37816

PR Close #38186
2020-08-07 22:10:55 -04:00
George Kalpakas
ccb0b42ffb build(docs-infra): upgrade cli command docs sources to b0b27361d (#38182)
Updating [angular#master](https://github.com/angular/angular/tree/master) from
[cli-builds#master](https://github.com/angular/cli-builds/tree/master).

##
Relevant changes in
[commit range](b76099083...b0b27361d):

**Modified**
- help/update.json

PR Close #38182
2020-08-07 22:10:55 -04:00
Andrew Scott
1d46ef38d2 refactor(dev-infra): Add support for groups in the conditions evaluator (#38164)
Conditions can refer to the groups array that is a list of the preceding groups.
This commit adds support to the verification for those conditions.

This commit also adds some tests to the parsing and condition matching
to ensure everything works as expected.

PR Close #38164
2020-08-07 22:10:55 -04:00
Sonu Kapoor
06356d806a build(forms): create sample forms app (#38044)
This commit creates a sample forms test application to introduce the symbol
tests. It serves as a guard to ensure that any future work on the
forms package does not unintentionally increase the payload size.

PR Close #38044
2020-08-07 22:10:55 -04:00
kreuzerk
45847c62ce docs: add Kevin Kreuzer to GDE page (#37929)
This commit adds Kevin Kreuzer to the Angular GDE page along with a biography, his contributions, and a photograph.

PR Close #37929
2020-08-07 22:10:55 -04:00
Bogdan Bogdanov
9cb6bb8535 docs: update dynamic-component loading guide (#36959)
The 'entryComponents' array is no longer a special case for dynamic component loading because of the Ivy compiler.

PR Close #36959
2020-08-07 22:10:55 -04:00
Sonu Kapoor
e9b25a1e98 docs: remove duplicate https:// (#38199)
This doc contained a duplicate `http://` before the domain name leading to an invalid link.
This commit fixes this issue.
PR Close #38199
2020-08-07 22:10:55 -04:00
Judy Bogart
ad51b996a2 docs: update api reference for router outlet directive (#38166)
Incorporate more specific information about multiple outlets and how to target them, with link to tutorial example.

PR Close #38166
2020-08-07 22:10:55 -04:00
Oussama Ben Brahim
8a05f311b9 refactor(forms): refactor common validators used in unit tests (#38020)
A util file is added to forms test package:
- it exposes simpleAsyncValidator, asyncValidator and asyncValidatorReturningObservable validators
- it refactors simpleAsyncValidator and asyncValidator to use common promise creation code
- it exposes currentStateOf allowing to get the validation state of a list of AbstractControl

Closes #37831

PR Close #38020
2020-08-07 22:10:55 -04:00
remackgeek
e72267bc00 fix(elements): run strategy methods in correct zone (#37814)
Default change detection fails in some cases for @angular/elements where
component events are called from the wrong zone.

This fixes the issue by running all ComponentNgElementStrategy methods
in the same zone it was created in.

Fixes #24181

PR Close #37814
2020-08-07 22:10:55 -04:00
Jeremy Elbourn
2e0973a814 docs: create coding standards doc (#37700)
Create initial document for Angular framework coding standards. This
document will evolve over time. This version contains all
non-controversial rules as discussed in a recent team meeting. Some text
and examples were copied from angular/components.

PR Close #37700
2020-08-07 22:10:55 -04:00
George Kalpakas
27092a822a build(docs-infra): remove boilerplate file listings in example-boilerplate.js (#38173)
To avoid unnecessary code duplication in docs examples, we have some
boilerplate files for various example types (in
`aio/tools/examples/shared/boilerplate/`). These files are copied to
each example project in `aio/content/examples/` (according to the
example's type, as specified in its `example-config.json` file).

Previously, the `example-boilerplate.js`, which is responsible for
copying the boilerplate files, had lists for files to be copied for each
project type and only copied the listed files from the boilerplate
directory to the example directory. This approach had some drawbacks:
- Files need to be updated in two separate locations: in the boilerplate
  directory that includes the files and the file list in
  `example-boilerplate.js`.
- It is easy to add a file in the boilerplate directory but forget to
  add it in `example-boilerplate.js` and not realize that it is not
  being included in the example project (including the generated
  StackBlitz project and ZIP archive).

This commit changes the approach by removing the boilerplate file
listings from `example-boilerplate.js` and copying all files from a
boilerplate directory to example directories. This addresses the above
drawbacks and simplifies the `example-boilerplate.js` script.

I have verified that the resulting code example doc regions as well as
the generated StackBlitz projects and ZIP archives are identical to the
ones generated before this commit.

PR Close #38173
2020-08-07 22:10:55 -04:00
George Kalpakas
0cd8e48c36 fix(docs-infra): include .gitignore file in CLI-based docs examples (#38173)
Previously, the `.gitignore` file that is part of the boilerplate files
for CLI-based docs examples (located in
`aio/tools/examples/shared/boilerplate/cli/`) was not added to the
example projects, because it was not included in the boilerplate file
list in `example-boilerplate.js`.

This commit fixes it by adding the `.gitignore` file to the list. This
ensures that docs examples more closely match CLI-generated projects.

PR Close #38173
2020-08-07 22:10:55 -04:00
George Kalpakas
2b95289ee2 fix(docs-infra): correctly add polyfills.ts file as boilerplate for i18n docs examples (#38173)
Docs examples of type `i18n` need a slightly modified version of
`polyfills.ts` that imports `@angular/localize/init`. Previously, this
file was not included in `i18n` example projects for two reasons:

- While the file was included in the `i18n` boilerplate files (at
  `aio/tools/examples/shared/boilerplate/i18n/`), it was not included in
  the boilerplate file list in `example-boilerplate.js`.
- The file was in the wrong location: It was located at the project root
  instead of inside the `src/` directory.

This commit addresses the above issues (i.e. adds the file to the
boilerplate file list for `i18n` projects and moves the file inside the
`src/` directory).

PR Close #38173
2020-08-07 22:10:55 -04:00
George Kalpakas
5df5ce6463 build(docs-infra): remove obsolete systemjs.config.web[.build].js files from docs examples (#38173)
There were some `systemjs.config.web[.build].js` files in the `systemjs`
boilerplate directory that are not used any more. In the past, these
files were used in the Plunker-based live examples, but we no longer use
Plunker for live examples.

This commit removes these obsolete files.

PR Close #38173
2020-08-07 22:10:55 -04:00
George Kalpakas
04ad0077f4 build(docs-infra): remove obsolete typings.d.ts files from angular.io and docs examples (#38173)
There were two `typings.d.ts` files with SystemJS module definitions in
`aio/src/` and `aio/tools/examples/shared/boilerplate/cli/`. These are
remnants from old CLI versions that used SystemJS and are no longer
needed. For docs examples specifically, these files were never copied
over to example projects and thus not included in StackBlitz projects
and ZIP archives.

This commit removes these obsolete files.

PR Close #38173
2020-08-07 22:10:55 -04:00
Georgi K
1bf2f118c7 docs: fix typo in ng_control.ts (#38157)
PR Close #38157
2020-08-07 22:10:55 -04:00
Doug Parker
2119abf954 docs: add Ivy and View Engine test scripts (#38149)
Developer docs previously stated to use `yarn bazel test //packages/...` which attempts to test all packages with View
Engine (the default), even though not all support View Engine. This updates the doc to use `yarn test-ivy-aot` and
`yarn test-non-ivy` which tests both Ivy and View Engine while filtering out tests which are not compatible with each
renderer.

PR Close #38149
2020-08-07 22:10:55 -04:00
Boaz Rymland
fc728d0cfb docs: fix typo from singular to plural spelling (#36586)
This commit fixes the spelling of the singular form
of the word function to the plural spelling in
packages/core/src/application_init.ts

PR Close #36586
2020-08-07 22:10:55 -04:00
Andrew Kushnir
dd01edd168 release: cut the v10.1.0-next.2 release 2020-08-07 22:10:55 -04:00
Andrew Kushnir
7c3edad3d4 docs: release notes for the v10.0.5 release 2020-08-07 22:10:55 -04:00
Shmuela Jacobs
445ac15a78 docs: fix purpose description of "builders.json" (#36830)
PR Close #36830
2020-08-07 15:04:56 -07:00
Andrew Kushnir
856db56cca refactor(forms): get rid of duplicate functions (#38371)
This commit performs minor refactoring in Forms package to get rid of duplicate functions.
It looks like the functions were duplicated due to a slightly different type signatures, but
their logic is completely identical. The logic in retained functions remains the same and now
these function also accept a generic type to achieve the same level of type safety.

PR Close #38371
2020-08-07 11:40:04 -07:00
Alessandro
354e66efad refactor(common): use getElementById in ViewportScroller.scrollToAnchor (#30143)
This commit uses getElementById and getElementsByName when an anchor scroll happens,
to avoid escaping the anchor and wrapping the code in a try/catch block.

Related to #28960

PR Close #30143
2020-08-07 11:14:31 -07:00
Misko Hevery
702958e968 refactor(core): add debug ranges to LViewDebug with matchers (#38359)
This change provides better typing for the `LView.debug` property which
is intended to be used by humans while debugging the application with
`ngDevMode` turned on.

In addition this chang also adds jasmine matchers for better asserting
that `LView` is in the correct state.

PR Close #38359
2020-08-06 16:58:11 -07:00
Sonu Kapoor
df7f3b04b5 fix(service-worker): fix the chrome debugger syntax highlighter (#38332)
The Chrome debugger is not able to render the syntax properly when the
code contains backticks. This is a known issue in Chrome and they have an
open [issue](https://bugs.chromium.org/p/chromium/issues/detail?id=659515) for that.
This commit adds the work-around to use double backslash with one
backtick ``\\` `` at the end of the line.

This can be reproduced by running the following command:

`yarn bazel test //packages/forms/test --config=debug`

When opening the chrome debugger tools, you should see the correct
code highlighting syntax.

PR Close #38332
2020-08-06 15:22:57 -07:00
JoostK
7525f3afc1 fix(compiler-cli): type-check inputs that include undefined when there's coercion members (#38273)
For attribute bindings that target a directive's input, the template
type checker is able to verify that the type of the input expression is
compatible with the directive's declaration for said input. This
checking adheres to the `strictNullChecks` flag as configured in the
TypeScript compilation, such that errors are reported for expressions
that include `undefined` or `null` in their type if the input's
declaration does not include those types.

There was a bug with this level of type-checking for directives that
also declare coercion members, where binding an expression that includes
the `undefined` type to a directive's input that does not include the
`undefined` type would not be reported as error.

This commit fixes the bug by changing the type-constructor in type-check
code to use an intersection type of regular inputs and coerced inputs,
instead of a union type. The union type would inadvertently allow
`undefined` types to be assigned into the regular inputs, as that would
still satisfy the characteristics of a union type.

As a result of this change, you may start to see build failures if
`strictTemplates` is enabled and `strictInputTypes` is not disabled.
These errors are legitimate and some action is required to achieve a
successful build:

1. Update the templates for which an error is reported and introduce the
   non-null assertion operator at the end of the expression. This
   removes the `undefined` type from the expression's type, making it
   appear as a valid assignment.
2. Disable `strictNullInputTypes` in the compiler options. This will
   implicitly add the non-null assertion operators similar to option 1,
   but all templates in the compilation are affected.
3. Update the directive's input declaration to include the `undefined`
   type, if the directive is not implemented in an external library.

PR Close #38273
2020-08-06 15:21:02 -07:00
JoostK
570d156ce4 test: update components repo to test against recent revision (#38273)
The changes in angular/components#20136 are required to allow the
framework tests to succeed.

PR Close #38273
2020-08-06 15:21:02 -07:00
Misko Hevery
26be5b4994 refactor(core): extract icuSwitchCase, icuUpdateCase, removeNestedIcu (#38154)
Extract `icuSwitchCase`, `icuUpdateCase`, `removeNestedIcu` into
separate functions to align them with the `.debug` property text.

PR Close #38154
2020-08-06 15:20:17 -07:00
Misko Hevery
3821dc5f6c refactor(core): add human readable debug for i18n (#38154)
I18n code breaks up internationalization into opCodes which are then stored
in arrays. To make it easier to debug the codebase this PR adds `debug`
property to the arrays which presents the data in human readable format.

PR Close #38154
2020-08-06 15:20:17 -07:00
George Kalpakas
18cd1a9937 docs(service-worker): describe how asset-/data-group order affects request handling (#38364)
The order of asset- and data-groups in `ngsw-config.json` affects how a
request is handled by the ServiceWorker. Previously, this was not
clearly documented.

This commit describes how the order of asset-/data-groups affects
request handling.

Closes #21189

PR Close #38364
2020-08-06 11:41:58 -07:00
George Kalpakas
0551fbdf88 fix(docs-infra): correctly generate CLI commands docs when the overview page moves (#38365)
Previously, the [processCliCommands][1] dgeni processor, which is used
to generate the docs pages for the CLI commands, expected the CLI
commands overview page (with a URL of `cli`) to exist as a child of a
top-level navigation section (`CLI Commands`). If one tried to move the
`CLI Commands` section inside another section, `processCliCommnads`
would fail to find it and thus fail to generate the CLI commands docs.
This problem came up in #38353.

This commit updates the `processCliCommands` processor to be able to
find it regardless of the position of the `CLI Commands` section inside
the navigation doc.

[1]:
dca4443a8e/aio/tools/transforms/cli-docs-package/processors/processCliCommands.js (L7-L9)

PR Close #38365
2020-08-06 11:41:05 -07:00
Doug Parker
dca4443a8e fix(compiler-cli): mark eager NgModuleFactory construction as not side effectful (#38320)
Roll forward of #38147.

This allows Closure compiler to tree shake unused constructor calls to `NgModuleFactory`, which is otherwise considered
side-effectful. The Angular compiler generates factory objects which are exported but typically not used, as they are
only needed for compatibility with View Engine. This results in top-level constructor calls, such as:

```typescript
export const FooNgFactory = new NgModuleFactory(Foo);
```

`NgModuleFactory` has a side-effecting constructor, so this statement cannot be tree shaken, even if `FooNgFactory` is
never imported. The `NgModuleFactory` continues to reference its associated `NgModule` and prevents the module and all
its unused dependencies from being tree shaken, making Closure builds significantly larger than necessary.

The fix here is to wrap `NgModuleFactory` constructor with `noSideEffects(() => /* ... */)`, which tricks the Closure
compiler into assuming that the invoked function has no side effects. This allows it to tree-shake unused
`NgModuleFactory()` constructors when they aren't imported. Since the factory can be removed, the module can also be
removed (if nothing else references it), thus tree shaking unused dependencies as expected.

The one notable edge case is for lazy loaded modules. Internally, lazy loading is done as a side effect when the lazy
script is evaluated. For Angular, this side effect is registering the `NgModule`. In Ivy this is done by the
`NgModuleFactory` constructor, so lazy loaded modules **cannot** have their top-level `NgModuleFactory` constructor
call tree shaken. We handle this case by looking for the `id` field on `@NgModule` annotations. All lazy loaded modules
include an `id`. When this `id` is found, the `NgModuleFactory` is generated **without** with `noSideEffects()` call,
so Closure will not tree shake it and the module will lazy-load correctly.

PR Close #38320
2020-08-06 09:02:16 -07:00
Doug Parker
2a745c8df8 refactor(compiler): add ModuleInfo interface (#38320)
This introduces a new `ModuleInfo` interface to represent some of the statically analyzed data from an `NgModule`. This
gets passed into transforms to give them more context around a given `NgModule` in the compilation.

PR Close #38320
2020-08-06 09:02:16 -07:00
Doug Parker
a18f82b458 refactor(core): add noSideEffects() as private export (#38320)
This is to enable the compiler to generate `noSideEffects()` calls. This is a private export, gated by `ɵ`.

PR Close #38320
2020-08-06 09:02:16 -07:00
Ajit Singh
696a9b01ef docs: remove https://angular.io from internal links (#38360)
PR #36601 introduces icons on all links if the link contains
https:// or http:// but there were some internal links left
which contained https://angular.io. Removed https://angular.io
from all these links.

PR Close #38360
2020-08-06 09:01:34 -07:00
mgechev
d7c043ba35 docs: add a page with the Angular roadmap (#38358)
PR Close #38358
2020-08-05 18:35:02 -07:00
Sonu Kapoor
0c2490368e refactor(platform-browser): specify return type of parseEventName (#38089)
This commit refactors the argument of the `parseEventName` function
to use an object with named properties instead of using an object indexer.

PR Close #38089
2020-08-05 17:06:28 -07:00
marcvincenti
bb88c9fa3d fix(common): ensure scrollRestoration is writable (#30630)
Some specialised browsers that do not support scroll restoration
(e.g. some web crawlers) do not allow `scrollRestoration` to be
writable.

We already sniff the browser to see if it has the `window.scrollTo`
method, so now we also check whether `window.history.scrollRestoration`
is writable too.

Fixes #30629

PR Close #30630
2020-08-05 16:13:15 -07:00
Pete Bacon Darwin
8227b56f9e style(docs-infra): reformat ScrollService file (#30630)
Pre-empting code formatting changes when the
code is updated in a subsequent commit.

PR Close #30630
2020-08-05 16:13:15 -07:00
Dmitrij Kuba
1609815743 feat(router): better warning message when a router outlet has not been instantiated (#30246)
It is confusing when routes are successfully activated but a component
is not present on a page, with this message it's more clear.

PR Close #30246
2020-08-05 12:55:35 -07:00
Luis José Sánchez
c4d76a65da
Traducido: accessibility.md (#50)
* Traducido

Traducido el apartado "Accesibilidad en Angular". Pendiente de revisión.

* Update aio/content/guide/accessibility.md

Co-authored-by: Pato <11162114+devpato@users.noreply.github.com>

* Update aio/content/guide/accessibility.md

Co-authored-by: Pato <11162114+devpato@users.noreply.github.com>

* Update aio/content/guide/accessibility.md

Co-authored-by: Pato <11162114+devpato@users.noreply.github.com>

* Update aio/content/guide/accessibility.md

Co-authored-by: Pato <11162114+devpato@users.noreply.github.com>

Co-authored-by: Pato <11162114+devpato@users.noreply.github.com>
2020-08-05 15:40:54 -04:00
Joey Perrott
763023472b fix(router): prevent calling unsubscribe on undefined subscription in RouterPreloader (#38344)
Previously, the `ngOnDestroy` method called `unsubscribe` regardless of if `subscription` had
been initialized.  This can lead to an error attempting to call `unsubscribe` of undefined.
This change prevents this error, and instead only attempts `unsubscribe` when the subscription
has been defined.

PR Close #38344
2020-08-05 10:54:41 -07:00
Charles Lyding
ba175be41f fix(compiler-cli): match wrapHost parameter types within plugin interface (#38004)
The `TscPlugin` interface using a type of `ts.CompilerHost&Partial<UnifiedModulesHost>` for the `host` parameter
of the `wrapHost` method. However, prior to this change, the interface implementing `NgTscPlugin` class used a
type of `ts.CompilerHost&UnifiedModulesHost` for the parameter. This change corrects the inconsistency and
allows `UnifiedModulesHost` members to be optional when using the `NgtscPlugin`.

PR Close #38004
2020-08-05 10:54:07 -07:00
Paul Gschwendtner
f0766a4474 feat(dev-infra): provide organization-wide merge-tool label configuration (#38223)
Previously, each Angular repository had its own strategy/configuration
for merging pull requests and cherry-picking. We worked out a new
strategy for labeling/branching/versioning that should be the canonical
strategy for all actively maintained projects in the Angular organization.

This PR provides a `ng-dev` merge configuration that implements the
labeling/branching/merging as per the approved proposal.

See the following document for the proposal this commit is based on
for the merge script labeling/branching: https://docs.google.com/document/d/197kVillDwx-RZtSVOBtPb4BBIAw0E9RT3q3v6DZkykU

The merge tool label configuration can be conveniently accesed
within each `.ng-dev` configuration, and can also be extended
if there are special labels on individual projects. This is one
of the reasons why the labels are not directly built into the
merge script. The script should remain unopinionated and flexible.

The configuration is conceptually powerful enough to achieve the
procedures as outlined in the versioning/branching/labeling proposal.

PR Close #38223
2020-08-05 10:53:17 -07:00
Paul Gschwendtner
6f0f0d3ea2 feat(dev-infra): support user-failures when computing branches for target label (#38223)
The merge tool provides a way for configurations to determine the branches
for a label lazily. This is supported because it allows labels to respect
the currently selected base branch through the Github UI. e.g. if `target: label`
is applied on a PR and the PR is based on the patch branch, then the change
could only go into the selected target branch, while if it would be based on
`master`, the change would be cherry-picked to `master` too. This allows for
convenient back-porting of changes if they did not apply cleanly to the primary
development branch (`master`).

We want to expand this function so that it is possible to report failures if an
invalid target label is appplied (e.g. `target: major` not allowed in
some situations), or if the Github base branch is not valid for the given target
label (e.g. if `target: lts` is used, but it's not based on a LTS branch).

PR Close #38223
2020-08-05 10:53:17 -07:00
Paul Gschwendtner
576e329f33 feat(dev-infra): provide github API instance to lazy merge configuration (#38223)
The merge script currently accepts a configuration function that will
be invoked _only_ when the `ng-dev merge` command is executed. This
has been done that way because the merge tooling usually relies on
external requests to Git or NPM for constructing the branch configurations.

We do not want to perform these slow external queries on any `ng-dev` command
though, so this became a lazily invoked function.

This commit adds support for these configuration functions to run
asynchronously (by returning a Promise that will be awaited), so that
requests could also be made to the Github API. This is benefical as it
could avoid dependence on the local Git state and the HTTP requests
are more powerful/faster.

Additionally, in order to be able to perform Github API requests
with an authenticated instance, the merge tool will pass through
a `GithubClient` instance that uses the specified `--github-token`
(or from the environment). This ensures that all API requests use
the same `GithubClient` instance and can be authenticated (mitigating
potential rate limits).

PR Close #38223
2020-08-05 10:53:17 -07:00
Zara Cooper
585ef2bdd7 docs: fix typo in glossary (#38318)
Add missing comma  in structural directive section that made dash display incorrectly.

PR Close #38318
2020-08-05 10:52:27 -07:00
Alex Rickabaugh
2fcabe1557 release: cut the v10.1.0-next.4 release 2020-08-04 16:13:39 -07:00
Alex Rickabaugh
192ef42304 docs: release notes for the v10.0.8 release 2020-08-04 16:07:27 -07:00
JiaLiPassion
8fbf40bf40 feat(core): update reference and doc to change async to waitAsync. (#37583)
The last commit change `async` to `waitForAsync`.
This commit update all usages in the code and also update aio doc.

PR Close #37583
2020-08-03 12:54:13 -07:00
JiaLiPassion
8f074296c2 feat(core): rename async to waitForAsync to avoid confusing (#37583)
@angular/core/testing provide `async` test utility, but the name `async` is
confusing with the javascript keyword `async`. And in some test case, if you
want to use both the `async` from `@angular/core/testing` and `async/await`,
you may have to write the code like this.

```typescript
it('test async operations', async(async() => {
  const result = await asyncMethod();
  expect(result).toEqual('expected');
}));
```

So in this PR, the `async` is renamed to `waitForAsync` and also deprecate `async`.

PR Close #37583
2020-08-03 12:54:13 -07:00
Alex Eagle
e49b053dac build: cleanup .bazelrc file to no longer set unused flags (#38124)
This option is no longer needed in Bazel and will be an error in the future

PR Close #38124
2020-08-03 12:53:11 -07:00
Zara Cooper
87baa06cc6 revert: docs(core): correct SomeService to SomeComponent (#38325)
This reverts commit b4449e35bfd04c5858ded17c0ce56248d680e8d4.

The example given from the previous change was for a component selector and not a provider selector.

This change fixes it.

Fixes #38323.

PR Close #38325
2020-08-03 12:52:19 -07:00
Alejandro
db394e2b81 docs: Fix a typo for cheatsheet translation 2020-08-03 07:43:29 -04:00
Joey Perrott
ff9f4de4f1 fix(compiler): update unparsable character reference entity error messages (#38319)
Within an angular template, when a character entity is unable to be parsed, previously a generic
unexpected character error was thrown.  This does not properly express the issue that was discovered
as the issue is actually caused by the discovered character making the whole of the entity unparsable.
The compiler will now instead inform via the error message what string was attempted to be parsed
and what it was attempted to be parsed as.

Example, for this template:
```
<p>
  &#x123p
</p>
```
Before this change:
`Unexpected character "p"`

After this change:
`Unable to parse entity "&#x123p" - hexadecimal character reference entities must end with ";"`

Fixes #26067

PR Close #38319
2020-07-31 15:32:53 -07:00
George Kalpakas
3a46c2da7c refactor(docs-infra): update docs examples tslint.json to match CLI and fix failures (#38143)
This commit updates the `tslint.json` configuration file, that is used
to lint the docs examples, to match the one generated for new Angular
CLI apps. There are some minimal differences (marked with `TODO`
comments) for things, such as component selector prefix, that would
require extensive and/or difficult to validate changes in guides.

This commit also includes the final adjustments to make the docs
examples code compatible with the new tslint rules. (The bulk of the
work has been done in previous commits.)

PR Close #38143
2020-07-31 11:00:06 -07:00
George Kalpakas
bfd13c06e1 refactor(docs-infra): fix docs examples for Angular-specific tslint rules (#38143)
This commit updates the docs examples to be compatible with the
following Angular-specific tslint rules:
- `component-selector`
- `directive-selector`
- `no-conflicting-lifecycle`
- `no-host-metadata-property`
- `no-input-rename`
- `no-output-native`
- `no-output-rename`

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-07-31 11:00:06 -07:00
George Kalpakas
5303773daf refactor(docs-infra): fix docs examples for tslint rule prefer-const (#38143)
This commit updates the docs examples to be compatible with the
`prefer-const` tslint rule.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-07-31 11:00:06 -07:00
George Kalpakas
ba11f7b90b refactor(docs-infra): fix docs examples for tslint rules related to underscores in variable names (#38143)
This commit updates the docs examples to be compatible with the
`variable-name` tslint rule without requiring the
`allow-leading-underscore` and `allow-trailing-underscore` options.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-07-31 11:00:06 -07:00
George Kalpakas
1db4f508e6 refactor(docs-infra): fix docs examples for tslint rules related to variable names (#38143)
This commit updates the docs examples to be compatible with the
`no-shadowed-variable` and `variable-name` tslint rules.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-07-31 11:00:06 -07:00
George Kalpakas
6334749d2c refactor(docs-infra): fix docs examples for tslint rule member-ordering (#38143)
This commit updates the docs examples to be compatible with the
`member-ordering` tslint rule.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-07-31 11:00:06 -07:00
George Kalpakas
3c7359f026 refactor(docs-infra): fix docs examples for tslint rule no-angle-bracket-type-assertion (#38143)
This commit updates the docs examples to be compatible with the
`no-angle-bracket-type-assertion` tslint rule.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-07-31 11:00:06 -07:00
George Kalpakas
8aa29438ac refactor(docs-infra): fix docs examples for tslint rules related to object properties (#38143)
This commit updates the docs examples to be compatible with the
`no-string-literal`, `object-literal-key-quotes` and
`object-literal-shorthand` tslint rules.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-07-31 11:00:06 -07:00
George Kalpakas
fc709423f2 refactor(docs-infra): fix docs examples for tslint rule only-arrow-functions (#38143)
This commit updates the docs examples to be compatible with the
`only-arrow-functions` tslint rule.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-07-31 11:00:06 -07:00
George Kalpakas
3012a8e71c style(docs-infra): fix docs examples for tslint rule jsdoc-format (#38143)
This commit updates the docs examples to be compatible with the
`jsdoc-format` tslint rule.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-07-31 11:00:05 -07:00
George Kalpakas
77f38d3be1 style(docs-infra): fix docs examples for tslint rule semicolon (#38143)
This commit updates the docs examples to be compatible with the
`semicolon` tslint rule.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-07-31 11:00:05 -07:00
George Kalpakas
7c0f11789b style(docs-infra): fix docs examples for tslint rules related to whitespace (#38143)
This commit updates the docs examples to be compatible with the `align`,
`space-before-function-paren` and `typedef-whitespace` tslint rules.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-07-31 11:00:05 -07:00
George Kalpakas
0a791e4a50 style(docs-infra): fix docs examples for tslint rule import-spacing (#38143)
This commit updates the docs examples to be compatible with the
`import-spacing` tslint rule.

This is in preparation of updating the docs examples `tslint.json` to
match the one generated for new Angular CLI apps in a future commit.

PR Close #38143
2020-07-31 11:00:05 -07:00
George Kalpakas
d89200ad24 refactor(docs-infra): remove unnecessary use strict from docs examples TS files (#38143)
By default, TypeScript will emit `"use strict"` directives, so it is not
necessary to include `'use strict'` in `.ts` files:
https://www.typescriptlang.org/docs/handbook/compiler-options.html#:~:text=--noImplicitUseStrict

PR Close #38143
2020-07-31 11:00:05 -07:00
George Kalpakas
00b7186cb2 refactor(docs-infra): remove unused styleguide examples (#38143)
The `03-*` code style rule have been removed from the style guide in
be0bc799f3fa99582238f29cb575e0705ce0c10f.

This commit removes the corresponding files and related unused code from
the`styleguide` example project.

PR Close #38143
2020-07-31 11:00:05 -07:00
Keen Yee Liau
e8896b9de3 fix(language-service): [ivy] do not retrieve ts.Program at startup (#38120)
This commit removes compiler instantiation at startup.
This is because the constructor is invoked during the plugin loading phase,
in which the project has not been completely loaded.

Retrieving `ts.Program` at startup will trigger an `updateGraph` operation,
which could only be called after the Project has loaded completely.
Without this change, the Ivy LS cannot be loaded as a tsserver plugin.

Note that the whole `Compiler` class is temporary, so changes made there are
only for development. Once we have proper integration with ngtsc the
`Compiler` class would be removed.

PR Close #38120
2020-07-30 16:54:19 -07:00
Charles Lyding
6f6102d8ad fix(compiler): add PURE annotation to getInheritedFactory calls (#38291)
Currently the `getInheritedFactory` function is implemented to allow
closure to remove the call if the base factory is unused.  However, this
method does not work with terser.  By adding the PURE annotation,
terser will also be able to remove the call when unused.

PR Close #38291
2020-07-30 16:53:52 -07:00
Alex Rickabaugh
4c7f233fa8 docs: release notes for the v10.0.7 release 2020-07-30 16:51:40 -07:00
Keen Yee Liau
fd51e01335 fix(compiler): Metadata should not include methods on Object.prototype (#38292)
This commit fixes a bug in View Engine whereby the compiler errorneously
thinks that a method of a component has decorator metadata when that
method is one of those in `Object.prototype`, for example `toString`.

This bug is discovered in v10.0.4 of `@angular/language-service` after
the default bundle format was switched from ES5 to ES2015.

ES5 output:
```js
if (propMetadata[propName]) {
    decorators.push.apply(decorators, __spread(propMetadata[propName]));
}
```

ES2015 output:
```js
if (propMetadata[propName]) {
    decorators.push(...propMetadata[propName]);
}
```

The bug was not discovered in ES5 because the polyfill for the spread
operator happily accepts parameters that do not have the `iterable`
symbol:

```js
function __spread() {
    for (var ar = [], i = 0; i < arguments.length; i++)
        ar = ar.concat(__read(arguments[i]));
    return ar;
}
```

whereas in es2015 it’ll fail since the iterable symbol is not present in
`propMetadata['toString']` which evaluates to a function.

Fixes https://github.com/angular/vscode-ng-language-service/issues/859

PR Close #38292
2020-07-30 15:18:28 -07:00
Alex Rickabaugh
3a525d196b Revert "fix(compiler): mark NgModuleFactory construction as not side effectful (#38147)" (#38303)
This reverts commit 7f8c2225f2cba3dfcf3ec23e0fe08b7d2e3497e8.

This commit caused test failures internally, which were traced back to the
optimizer removing NgModuleFactory constructor calls when those calls caused
side-effectful registration of NgModules by their ids.

PR Close #38303
2020-07-30 12:19:35 -07:00
Pato
92c7145139
fix(pr): template (#47)
Co-authored-by: Alejandro Lora <alejandrofpo@gmail.com>
Co-authored-by: Andrés Villanueva <andresvillanuevab@gmail.com>
Co-authored-by: Michael Prentice <splaktar@gmail.com>
2020-07-30 03:57:48 -04:00
Andrew Kushnir
1eebb7f189 test(compiler-cli): disable one TypeChecker test on Windows due to path sensitivity issue (#38294)
This commit disables one TypeChecker test (added as a part of
https://github.com/angular/angular/pull/38105) which make assertions about the filename while
running on Windows.

Such assertions are currently suffering from a case sensitivity issue.

PR Close #38294
2020-07-29 17:49:45 -07:00
Andrew Scott
8effc83b92 docs(router): clarify how base href is used to construct targets (#38123)
The documentation is not clear on how the base href and APP_BASE_HREF are used. This commit
should help clarify more complicated use-cases beyond the most common one of just a '/'

PR Close #38123
2020-07-29 13:34:02 -07:00
Doug Parker
7f8c2225f2 fix(compiler): mark NgModuleFactory construction as not side effectful (#38147)
This allows Closure compiler to tree shake unused constructor calls to `NgModuleFactory`, which is otherwise considered
side-effectful. The Angular compiler generates factory objects which are exported but typically not used, as they are
only needed for compatibility with View Engine. This results in top-level constructor calls, such as:

```typescript
export const FooNgFactory = new NgModuleFactory(Foo);
```

`NgModuleFactory` has a side-effecting constructor, so this statement cannot be tree shaken, even if `FooNgFactory` is
never imported. The `NgModuleFactory` continues to reference its associated `NgModule` and prevents the module and all
its unused dependencies from being tree shaken. This effectively prevents all components from being tree shaken, making
Closure builds significantly larger than they should be.

The fix here is to wrap `NgModuleFactory` constructor with `noSideEffects(() => /* ... */)`, which tricks the Closure
compiler into assuming that the invoked function has no side effects. This allows it to tree-shake unused
`NgModuleFactory()` constructors when they aren't imported. Since the factory can be removed, the module can also be
removed (if nothing else references it), thus tree shaking unused components as expected.

PR Close #38147
2020-07-29 13:32:08 -07:00
Doug Parker
887c350f9d refactor(compiler): wrap large strings in function (#38253)
Large strings constants are now wrapped in a function which is called whenever used. This works around a unique
limitation of Closure, where it will **always** inline string literals at **every** usage, regardless of how large the
string literal is or how many times it is used.The workaround is to use a function rather than a string literal.
Closure has differently inlining semantics for functions, where it will check the length of the function and the number
of times it is used before choosing to inline it. By using a function, `ngtsc` makes Closure more conservative about
inlining large strings, and avoids blowing up the bundle size.This optimization is only used if the constant is a large
string. A wrapping function is not included for other use cases, since it would just increase the bundle size and add
unnecessary runtime performance overhead.

PR Close #38253
2020-07-29 13:31:03 -07:00
crisbeto
103a95c182 docs: update bio picture (#38272)
Updates my profile picture which was quite old.

PR Close #38272
2020-07-29 10:33:36 -07:00
Sonu Kapoor
1b17722091 refactor(docs-infra): Lazy-loads SVG icons (#38268)
Prior to this commit, SVG icons were all loaded in the constructor
of the `CustomIconRegistry`. This commit avoids that, and loads SVG
icons on demand.

PR Close #38268
2020-07-29 10:32:54 -07:00
George Kalpakas
b280d54470 refactor(docs-infra): simplify/improve CopierService hidden textarea creation (#38244)
This commit simplifies the creation of the temporary, hidden
`<textarea>` element used by `CopierService` by switching from absolute
to fixed positioning and not requiring page's scroll offset.

It also makes the following minor improvements:
- Make the element invisible (via `opacity: 0`).
- Instruct screen-readers to ignore the element (via
  `aria-hidden: true`).

NOTE: These improvements are based on Angular CDK's [PendingCopy][1]
      class and the changes proposed in PR angular/components#20073.

[1]: https://github.com/angular/components/blob/89b5fa89d1437c3054c5/src/cdk/clipboard/pending-copy.ts

PR Close #38244
2020-07-29 10:32:05 -07:00
George Kalpakas
d96824acdb fix(docs-infra): preserve focus on copy (and prevent scrolling to bottom on IE11) (#38244)
The `CopierService` is used for copying text to the user's clipboard. It
is, for example, used in `CodeComponent` to copy example code snippets.
This is implemented by creating a temporary, hidden `<textarea>`
elements, setting its value to the text that needs to be copied,
executing the `copy` command and finally removing the element from the
DOM.

Previously, as a result of `CopierService`'s implementation, the focused
element would lose focus, while the temporary `<textarea>` element would
implicitly gain focus when selecting its contents. This had an even
worse side-effect on IE11, which seems to scroll to the bottom of the
containing element (here `<body>`) when the focused element is removed.

This commit fixes these issues by keeping track of the previously
focused element and restoring its focus after the copy operation.

NOTE: This fix is inspired by Angular CDK's [PendingCopy][1] class.

[1]: https://github.com/angular/components/blob/89b5fa89d1437c3054c5/src/cdk/clipboard/pending-copy.ts

Fixes #37796

PR Close #38244
2020-07-29 10:32:05 -07:00
George Kalpakas
9ebd461a22 refactor(docs-infra): improve code readability of CopierService (#38244)
This commit improves the code readability of the `CopierService` by:
- Adding/Improving JSDoc comments for methods.
- Avoiding unnecessary instance-wide properties.
- Fixing indentation to be consistent (at two spaces).
- Clearly separating the logic for creating and populating a
  `<textarea>` from the logic for selecting and copying its contents.

PR Close #38244
2020-07-29 10:32:05 -07:00
Alex Rickabaugh
d8c07b83c3 refactor(compiler-cli): support type-checking a single component (#38105)
This commit adds a method `getDiagnosticsForComponent` to the
`TemplateTypeChecker`, which does the minimum amount of work to retrieve
diagnostics for a single component.

With the normal `ReusedProgramStrategy` this offers virtually no improvement
over the standard `getDiagnosticsForFile` operation, but if the
`TypeCheckingProgramStrategy` supports separate shims for each component,
this operation can yield a faster turnaround for components that are
declared in files with many other components.

PR Close #38105
2020-07-29 10:31:21 -07:00
Alex Rickabaugh
8f73169979 refactor(compiler-cli): add TemplateId to template diagnostics (#38105)
Previously, a stable template id was implemented for each component in a
file. This commit adds this id to each `TemplateDiagnostic` generated from
the template type-checker, so it can potentially be used for filtration.

PR Close #38105
2020-07-29 10:31:20 -07:00
Alex Rickabaugh
3c0424e7e0 refactor(compiler-cli): allow overriding templates in the type checker (#38105)
This commit adds an `overrideComponentTemplate` operation to the template
type-checker. This operation changes the template used during template
type-checking operations.

Overriding a template causes any previous work for it to be discarded, and
the template type-checking engine will regenerate the TCB for that template
on the next request.

This operation can be used by a consumer such as the language service to
get rapid feedback or diagnostics as the user is editing a template file,
without the need for a full incremental build iteration.

Closes #38058

PR Close #38105
2020-07-29 10:31:20 -07:00
Alex Rickabaugh
de14b2c670 refactor(compiler-cli): efficient single-file type checking diagnostics (#38105)
Previously, the `TemplateTypeChecker` abstraction allowed fetching
diagnostics for a single file, but under the hood would generate type
checking code for the entire program to satisfy the request.

With this commit, an `OptimizeFor` hint is passed to `getDiagnosticsForFile`
which indicates whether the user intends to request diagnostics for the
whole program or is truly interested in just the single file. If the latter,
the `TemplateTypeChecker` can perform only the work needed to produce
diagnostics for just that file, thus returning answers more efficiently.

PR Close #38105
2020-07-29 10:31:20 -07:00
Alex Rickabaugh
c573d91285 refactor(compiler-cli): allow program strategies to opt out of inlining (#38105)
The template type-checking engine relies on the abstraction interface
`TypeCheckingProgramStrategy` to create updated `ts.Program`s for
template type-checking. The basic API is that the type-checking engine
requests changes to certain files in the program, and the strategy provides
an updated `ts.Program`.

Typically, such changes are made to 'ngtypecheck' shim files, but certain
conditions can cause template type-checking to require "inline" operations,
which change user .ts files instead. The strategy used by 'ngc' (the
`ReusedProgramStrategy`) supports these kinds of updates, but other clients
such as the language service might not always support modifying user files.

To accommodate this, the `TypeCheckingProgramStrategy` interface was
modified to include a `supportsInlineOperations` flag. If an implementation
specifies `false` for inline support, the template type-checking system will
return diagnostics on components which would otherwise require inline
operations.

Closes #38059

PR Close #38105
2020-07-29 10:31:20 -07:00
Alex Rickabaugh
16c7441c2f refactor(compiler-cli): introduce the TemplateTypeChecker abstraction (#38105)
This commit significantly refactors the 'typecheck' package to introduce a
new abstraction, the `TemplateTypeChecker`. To achieve this:

* a 'typecheck:api' package is introduced, containing common interfaces that
  consumers of the template type-checking infrastructure can depend on
  without incurring a dependency on the template type-checking machinery as
  a whole.
* interfaces for `TemplateTypeChecker` and `TypeCheckContext` are introduced
  which contain the abstract operations supported by the implementation
  classes `TemplateTypeCheckerImpl` and `TypeCheckContextImpl` respectively.
* the `TemplateTypeChecker` interface supports diagnostics on a whole
  program basis to start with, but the implementation is purposefully
  designed to support incremental diagnostics at a per-file or per-component
  level.
* `TemplateTypeChecker` supports direct access to the type check block of a
  component.
* the testing utility is refactored to be a lot more useful, and new tests
  are added for the new abstraction.

PR Close #38105
2020-07-29 10:31:20 -07:00
Alex Rickabaugh
736f6337b2 refactor(compiler-cli): make file/shim split 1:n instead of 1:1 (#38105)
Previously in the template type-checking engine, it was assumed that every
input file would have an associated type-checking shim. The type check block
code for all components in the input file would be generated into this shim.

This is fine for whole-program type checking operations, but to support the
language service's requirements for low latency, it would be ideal to be
able to check a single component in isolation, especially if the component
is declared along with many others in a single file.

This commit removes the assumption that the file/shim mapping is 1:1, and
introduces the concept of component-to-shim mapping. Any
`TypeCheckingProgramStrategy` must provide such a mapping.

To achieve this:

 * type checking record information is now split into file-level data as
   well as per-shim data.
 * components are now assigned a stable `TemplateId` which is unique to the
   file in which they're declared.

PR Close #38105
2020-07-29 10:31:20 -07:00
Andrea Canciani
9c8bc4a239 fix(common): narrow NgIf context variables in template type checker (#36627)
When the `NgIf` directive is used in a template, its context variables
can be used to capture the bound value. This is sometimes used in
complex expressions, where the resulting value is captured in a
context variable. There's two syntax forms available:

1. Binding to `NgIfContext.ngIf` using the `as` syntax:
```html
<span *ngIf="enabled && user as u">{{u.name}}</span>
```

2. Binding to `NgIfContext.$implicit` using the `let` syntax:
```html
<span *ngIf="enabled && user; let u">{{u.name}}</span>
```

Because of the semantics of `ngIf`, it is known that the captured
context variable is truthy, however the template type checker
would not consider them as such and still report errors when
`strict` is enabled.

This commit updates `NgIf`'s context guard to make the types of the
context variables truthy, avoiding the issue.

Based on https://github.com/angular/angular/pull/35125

PR Close #36627
2020-07-29 10:30:44 -07:00
Misko Hevery
cf4da82ac3 Revert "refactor(platform-browser): specify return type of parseEventName (#38089)"
This reverts commit 174aac68f7cfb9760430c42a4f53b91f8a48c738.
2020-07-29 09:30:11 -07:00
Alejandro
d133525502 docs: update typo for bootstraping word 2020-07-28 23:43:28 -04:00
Alejandro Lora
cd1817bf6d Update aio/content/guide/cheatsheet.md
Co-authored-by: Pato <11162114+devpato@users.noreply.github.com>
2020-07-28 23:43:28 -04:00
Alejandro
0d1491b1a6 docs: implement feedback PR 2020-07-28 23:43:28 -04:00
Alejandro Lora
f67774d84b Update aio/content/guide/cheatsheet.md
Co-authored-by: Pato <11162114+devpato@users.noreply.github.com>
2020-07-28 23:43:28 -04:00
Alejandro
37668d159e docs: translat cheatsheet.md file to Spanish 2020-07-28 23:43:28 -04:00
Michael Prentice
38554288f5 docs(readme): aplicar sugerencias de revisión de código 2020-07-28 23:23:46 -04:00
Luis José Sánchez
04dcc3bceb Update README.md
Traducción del README.md al español.
2020-07-28 23:23:46 -04:00
devpato
0910a2fc0d fix(file): based on pr comments 2020-07-28 23:18:53 -04:00
devpato
3325cb2f86 fix(code): based on comments from PR reviewrs 2020-07-28 23:18:53 -04:00
devpato
a1e8443bfb fix(files): removed unecessary files 2020-07-28 23:18:53 -04:00
devpato
599d34b41e fix(comment): based on PR 2020-07-28 23:18:53 -04:00
devpato
7fd1733882 fix(pr): comments 2020-07-28 23:18:53 -04:00
devpato
2e42123870 fix(merge): conflict 2020-07-28 23:18:53 -04:00
devpato
4cbb90daf7 feat(github): traduccion de templates para issues 2020-07-28 23:18:53 -04:00
Misko Hevery
57575e379f release: cut the v10.1.0-next.3 release 2020-07-28 15:17:32 -07:00
Misko Hevery
28c3e2d15d docs: release notes for the v10.0.6 release 2020-07-28 15:07:19 -07:00
Misko Hevery
2a45b932e2 build: fix broken build (#38274)
```
export const __core_private_testing_placeholder__ = '';
```
This API should be removed. But doing so seems to break `google3` and
so it requires a bit of investigation. A work around is to mark it as
`@codeGenApi` for now and investigate later.

PR Close #38274
2020-07-28 12:30:59 -07:00
Joey Perrott
5a12ab4a13 Revert "ci: roll back phased review conditions" (#38259)
This reverts commit ca8eafc2983f983803cd03e4a08bf732672712dd.

PR Close #38259
2020-07-28 11:26:27 -07:00
Joey Perrott
8a543d8b50 ci: only check active groups for the no-groups-above-this-* checks (#38259)
Since PullApprove starts all inactive groups as a pending state, to properly
assess if any groups we care about are pending we must only check the active
groups.  We additionally do this with rejected because the intention of the
reusable checks is around checking active rules only.

PR Close #38259
2020-07-28 11:26:27 -07:00
Judy Bogart
9893576ef0 docs(elements): update api doc for custom elements (#38252)
by adding cross-references to Angular Elements Overview guide.

PR Close #38252
2020-07-28 11:19:03 -07:00
Ajit Singh
af80bdb470 fix(core): Attribute decorator attributeName is mandatory (#38131)
`Attribute` decorator has defined `attributeName` as optional but actually its
 mandatory and compiler throws an error if `attributeName` is undefined. Made
`attributeName` mandatory in the `Attribute` decorator to reflect this functionality

Fixes #32658

PR Close #38131
2020-07-28 11:17:24 -07:00
Ahn
b4449e35bf docs(core): correct SomeService to SomeComponent (#38264)
PR Close #38264
2020-07-28 11:10:58 -07:00
Judy Bogart
3d0be5213e docs: update api reference doc for router-link-active directive (#38247)
Edits and organizes the usage information for the directive.

PR Close #38247
2020-07-28 11:09:44 -07:00
Andrew Scott
be3e7050d5 ci: roll back phased review conditions (#38257)
It was determined that the list of 'pending' groups also included inactive groups.
That means that the 'no-groups-above-this-pending' would generally fail because
there's almost always some inactive group above it.

This commit removes the conditions for phased review while we
investigate if the inactive groups can be excluded.

PR Close #38257
2020-07-28 10:02:14 -07:00
Tony Bove
cf98db28d5 docs: Refactor module-types.md to make it easier to understand (#38206)
Project DOCS-736 to rewrite headings to focus on user tasks,
verify that the content is up-to-date and complete, and
add relevant links to other NgModule topics to improve readability.
Also addresses one of many issues in GitHub issue 21531.

PR Close #38206
2020-07-28 10:01:37 -07:00
Jeremy Elbourn
5621452ff0 ci: add more owners for limited categories (#38170)
* Add alxhub, atscott, and AndrewKushnir to code owners
* Add atscott & AndrewKushnir to public-api and size-tracking

Follow-up to #37994

PR Close #38170
2020-07-28 10:01:04 -07:00
Tony Bove
b0676e8fab docs: Refactor ngmodule-vs-jsmodule.md to make it easier to understand (#38148)
Project DOCS-734 to rewrite headings to focus on user tasks,
verify that the content is up-to-date and complete, and
add relevant links to other NgModule topics to improve readability.
Also addresses one of many issues in GitHub issue 21531.

PR Close #38148
2020-07-28 10:00:28 -07:00
JiaLiPassion
b142283ba2 fix(core): unify the signature between ngZone and noopZone (#37581)
Now we have two implementations of Zone in Angular, one is NgZone, the other is NoopZone.
They should have the same signatures, includes
1. properties
2. methods

In this PR, unify the signatures of the two implementations, and remove the unnecessary cast.

PR Close #37581
2020-07-28 09:59:49 -07:00
Misko Hevery
e79b6c31f9 Revert "refactor(core): remove unused export (#38224)"
This reverts commit fbe1a9cbaaec91bb5ca8d1b47ebd7b6363ae6568.
2020-07-28 09:54:25 -07:00
Andrew Scott
65cc0c8bd6 fix(compiler-cli): Add support for string literal class members (#38226)
The current implementation of the TypeScriptReflectionHost does not account for members that
are string literals, i.e. `class A { 'string-literal-prop': string; }`

PR Close #38226
2020-07-27 15:26:27 -07:00
Judy Bogart
03a6252123 docs: update api reference doc for router link directive (#38181)
Edits and organizes the usage information for the directive.

PR Close #38181
2020-07-27 15:25:44 -07:00
Sonu Kapoor
174aac68f7 refactor(platform-browser): specify return type of parseEventName (#38089)
This commit refactors the argument of the `parseEventName` function
to use an object with named properties instead of using an object indexer.

PR Close #38089
2020-07-27 15:24:59 -07:00
Igor Minar
5d3ba8dec7 test: update ts-api-guardian's strip_export_pattern to exclude Ivy instructions (#38224)
Previously the instructions were included in the golden files to monitor the frequency and rate of
the instruction API changes for the purpose of understanding the stability of this API (as it was
considered for becoming a public API and deployed to npm via generated code).

This experiment has confirmed that the instruction API is not stable enough to be used as public
API. We've since also came up with an alternative plan to compile libraries with the Ivy compiler
for npm deployment and this plan does not rely on making Ivy instructions public.

For these reasons, I'm removing the instructions from the golden files as it's no longer important
to track them.

The are three instructions that are still being included: `ɵɵdefineInjectable`, `ɵɵinject`, and
`ɵɵInjectableDef`.

These instructions are already generated by the VE compiler to support tree-shakable providers, and
code depending on these instructions is already deployed to npm. For this reason we need to treat
them as public api.

This change also reduces the code review overhead, because changes to public api golden files now
require multiple approvals.

PR Close #38224
2020-07-27 14:37:41 -07:00
Igor Minar
fbe1a9cbaa refactor(core): remove unused export (#38224)
This export used to be here to turn this file into an ES Module - this is no longer needed
because the file contains imports.

PR Close #38224
2020-07-27 14:37:41 -07:00
Igor Minar
8f7d89436f refactor: correct @publicApi and @codeGenApi markers in various files (#38224)
The markers were previously incorrectly assigned. I noticed the issues when reviewing
the golden files and this change corrects them.

PR Close #38224
2020-07-27 14:37:41 -07:00
Alejandro Lora
cf2663b034
docs: translate the app-shell.md file (#41)
* docs: translate the app-shell.md file

* Update aio/content/guide/app-shell.md

Co-authored-by: Christian Morante <christianmorante@outlook.com>

* Update aio/content/guide/app-shell.md

Co-authored-by: Christian Morante <christianmorante@outlook.com>

* Update aio/content/guide/app-shell.md

Co-authored-by: Christian Morante <christianmorante@outlook.com>

* add PR feedback

* docs: update 'usted'-'tú' (Grammatical person)

Co-authored-by: Christian Morante <christianmorante@outlook.com>
2020-07-27 16:21:00 -04:00
JiaLiPassion
96aa14df01 fix(zone.js): zone patch rxjs should return null _unsubscribe correctly. (#37091)
Close #31684.

In some rxjs operator, such as `retryWhen`, rxjs internally will set
`Subscription._unsubscribe` method to null, and the current zone.js monkey patch
didn't handle this case correctly, even rxjs set _unsubscribe to null, zone.js
still return a function by finding the prototype chain.

This PR fix this issue and the following test will pass.

```
const errorGenerator = () => {
  return throwError(new Error('error emit'));
};

const genericRetryStrategy = (finalizer: () => void) => (attempts: Observable<any>) =>
    attempts.pipe(
      mergeMap((error, i) => {
        const retryAttempt = i + 1;
        if (retryAttempt > 3) {
          return throwError(error);
        }
        return timer(retryAttempt * 1);
      }),
      finalize(() => finalizer()));

errorGenerator()
  .pipe(
    retryWhen(genericRetryStrategy(() => {
      expect(log.length).toBe(3);
      done();
    })),
    catchError(error => of(error)))
  .subscribe()
```

PR Close #37091
2020-07-27 12:10:27 -07:00
Kapunahele Wong
2b6ab57d78 docs: add template ref var to glossary (#36743)
There is not an entry in the glossary for template
reference variable. To clarify for site visitors,
we are adding one here.

PR Close #36743
2020-07-27 12:01:47 -07:00
Omar Hasan
b65b6163f7 docs: fix breaking URL for RxJS marble testing (#38209)
When checking this URL for the `RxJS marble testing` Ive found it pointing to `Page not found`

PR Close #38209
2020-07-27 11:12:07 -07:00
Changyu Geng
f74cfadf64 docs: clarify the description of pipes (#37950)
This commit clarifies some of the language regarding pipes in the pipes guide.
This commit also specifies the term transforming rather than formatting.

PR Close #37950
2020-07-27 10:23:20 -07:00
Andrew Kushnir
8e5969bb52 fix(compiler): share identical stylesheets between components in the same file (#38213)
Prior to this commit, duplicated styles defined in multiple components in the same file were not
shared between components, thus causing extra payload size. This commit updates compiler logic to
use `ConstantPool` for the styles (while generating the `styles` array on component def), which
enables styles sharing when needed (when duplicates styles are present).

Resolves #38204.

PR Close #38213
2020-07-27 10:04:30 -07:00
Andrew Kushnir
8fdfa7b604 refactor(compiler): allow strings with certain length to be included into ConstantPool (#38213)
Prior to this commit, the `ConstantPool` ignored all primitive values. It turned out that it's
beneficial to include strings above certain length to the pool as well. This commit updates the
`ConstantPool` logic to allow such strings to be shared across multiple instances if needed.
For instance, this is helpful for component styles that might be reused across multiple components
in the same file.

PR Close #38213
2020-07-27 10:04:30 -07:00
Andrew Kushnir
2fdc18b42c refactor(compiler): separate compilation and transform phases (#38213)
This commit splits the transformation into 2 separate steps: Ivy compilation and actual transformation
of corresponding TS nodes. This is needed to have all `o.Expression`s generated before any TS transforms
happen. This allows `ConstantPool` to properly identify expressions that can be shared across multiple
components declared in the same file.

Resolves #38203.

PR Close #38213
2020-07-27 10:04:30 -07:00
Tim Deschryver
1296003445 docs: add ng-add save option (#38198)
PR Close #38198
2020-07-27 09:52:14 -07:00
Andrew Kushnir
4dfc3fe6a2 refactor(router): extract Router config utils to a separate file (#38229)
This commit refactors Router package to move config utils to a separate file for better
organization and to resolve the problem with circular dependency issue.

Resolves #38212.

PR Close #38229
2020-07-27 09:49:14 -07:00
Daniel
95681b16bd fix(docs): changed the way to express the idea
Changed the way to express the idea from "usted" to "tu"
2020-07-26 20:43:54 -04:00
Andrew Scott
67e3ecc7e3 fix(dev-infra): Ensure conditions with groups do not fail verification (#37798)
There are a few changes in this PR to ensure conditions that are based
on groups (i.e. `- groups.pending.length == 0`) do not fail the verify
task:

* Remove the warning when a condition is encountered that depends on the
`groups` state. The warning will otherwise be printed once for every
file that triggers the execution of the condition (400,000+ times)
* Add an `unverifiable` flag to `GroupCondition` interface and set it to
true when an error is encountered due to attempting to get the state of
`groups` in a condition
* Ignore any unverifiable conditions when gathering unmatched
conditions. These should not be considered `unmatched` for verification
purposes.
* Print the unverifiable conditions by group in the results

Sample output:
```

┌──────────────────────────────────────────────────────────────────────────────┐
│                         PullApprove results by group                         │
└──────────────────────────────────────────────────────────────────────────────┘
Groups skipped (4 groups)
Matched conditions by Group (37 groups)
Unmatched conditions by Group (0 groups)
Unverifiable conditions by Group (3 groups)
  [public-api]
    len(groups.pending.exclude("required-minimum-review")...
    len(groups.rejected.exclude("required-minimum-review")...
  [size-tracking]
    len(groups.pending.exclude("required-minimum-review")...
    len(groups.rejected.exclude("required-minimum-review")...
  [circular-dependencies]
    len(groups.pending.exclude("required-minimum-review")...
    len(groups.rejected.exclude("required-minimum-review")...

```

PR Close #37798
2020-07-24 17:59:39 -07:00
Andrew Scott
9821443150 feat(dev-infra): add phased review to groups requiring final sign-off after initial review (#37798)
The size-tracking, public-api, and circular-dependencies groups can get a lot of
PRs to review. In addition, the members of these groups do not always
have the necessary context to fully review the PR in question. This
change ensures that the owners in the groups where the changes are being
made have approve the changes (ie, the aren't pending or rejected)
before requesting final sign-off from these three critical groups.

PR Close #37798
2020-07-24 17:59:39 -07:00
Andrew Scott
c91cdea0cd refactor(dev-infra): create anchors/aliases for excluded always active groups (#37798)
global-approvers, global-docs-approvers, and required-minimum-review groups are always active. It's useful
to have aliases for getting groups that are active/pending/rejected while excluding these few.

PR Close #37798
2020-07-24 17:59:39 -07:00
JiaLiPassion
6a3e68b606 docs(zone.js): update zone.js bundle doc since the APF change (#37919)
Since the PR #36540 change the zone.js bundles to Angular Package Format, the
bundle name/location are changed, so this PR updated the `README.md` doc for the
zone bundles.
Also add the recent added new bundles `zone-patch-message-port` doc.

PR Close #37919
2020-07-24 15:46:45 -07:00
JiaLiPassion
1822cbcd46 fix(zone.js): patch nodejs EventEmtter.prototype.off (#37863)
Close #35473

zone.js nodejs patch should also patch `EventEmitter.prototype.off` as `removeListener`.
So `off` can correctly remove the listeners added by `EventEmitter.prototype.addListener`

PR Close #37863
2020-07-24 15:45:00 -07:00
JiaLiPassion
a71f114ba4 fix(zone.js): clearTimeout/clearInterval should call on object global (#37858)
Close #37333

`clearTimeout` is patched by `zone.js`, and it finally calls the native delegate of `clearTimeout`,
the current implemention only call `clearNative(id)`, but it should call on object `global` like
`clearNative.call(global, id)`. Otherwise in some env, it will throw error
`clearTimeout called on an object that does not implement interface Window`

PR Close #37858
2020-07-24 15:22:47 -07:00
JiaLiPassion
253337dc0a feat(zone.js): move MutationObserver/FileReader to different module (#31657)
Separate `EventTarget`, `FileReader`, `MutationObserver` and `IntersectionObserver` patches into different module.
So the user can disable those modules separately.

PR Close #31657
2020-07-24 15:12:28 -07:00
Andrii
6e2db228af docs: Fix link by removing a space (#38214)
PR Close #38214
2020-07-24 09:53:06 -07:00
Andrew Scott
cce5583e75 docs(core): Fix incorrectly rendered code example in structural directives guide (#38207)
The code example was missing a close brace and also incorrectly rendered
the template div as an actual div in the page DOM.

PR Close #38207
2020-07-24 09:52:30 -07:00
k-ta-yamada
307db74e93 docs: fixed that class attribute is not closed (#38219)
PR Close #38219
2020-07-24 08:15:44 -07:00
George Kalpakas
88d4b269b5 build(docs-infra): simplify ExampleZipper by removing PackageJsonCustomizer (#38192)
Previously, `ExampleZipper` (the tool used for creating ZIP archives
from our docs examples) used the `PackageJsonCustomizer` to generate
`package.json` files for each example type. This had the following
drawbacks:
- The generated files had to be kept up-to-date with the corresponding
  boilerplate files in `aio/tools/examples/shared/boilerplate/` and
  there was no easy way to find out when the files got out-of-sync.
- The `PackageJsonCustomizer` logic was non-trivial and difficult to
  reason about.
- The same information was duplicated in the boilerplate files and the
  customizer configuration files.

This setup was useful when we used a single `package.json` file for all
docs examples. Now, however, each example type can have its own
boilerplate `package.json` file, including scripts and dependencies
relevant to the example type. Therefore, it is no longer necessary to
generate `package.json` files for ZIP archives.

This commit eliminates the drawbacks mentioned above and simplifies the
`ExampleZipper` tool by removing `PackageJsonCustomizer` and re-using
the boilerplate `package.json` files for ZIP archives.

The changes in this commit also fix some ZIP archives that were
previously broken (for example due to missing dependencies).

PR Close #38192
2020-07-23 11:08:11 -07:00
Saif
ee22aa592e fix(docs-infra): correctly display copy button in IE11 (#38186)
Fix button top portion was clipped in IE11 by setting overflow to visible

Fixes #37816

PR Close #38186
2020-07-23 11:07:28 -07:00
George Kalpakas
dd09fb5348 build(docs-infra): upgrade cli command docs sources to b0b27361d (#38182)
Updating [angular#master](https://github.com/angular/angular/tree/master) from
[cli-builds#master](https://github.com/angular/cli-builds/tree/master).

##
Relevant changes in
[commit range](b76099083...b0b27361d):

**Modified**
- help/update.json

PR Close #38182
2020-07-23 11:06:17 -07:00
Andrew Scott
d0060dcfdc refactor(dev-infra): Add support for groups in the conditions evaluator (#38164)
Conditions can refer to the groups array that is a list of the preceding groups.
This commit adds support to the verification for those conditions.

This commit also adds some tests to the parsing and condition matching
to ensure everything works as expected.

PR Close #38164
2020-07-23 11:05:42 -07:00
Sonu Kapoor
7b2e2f5d91 build(forms): create sample forms app (#38044)
This commit creates a sample forms test application to introduce the symbol
tests. It serves as a guard to ensure that any future work on the
forms package does not unintentionally increase the payload size.

PR Close #38044
2020-07-23 11:04:46 -07:00
kreuzerk
b518b30dae docs: add Kevin Kreuzer to GDE page (#37929)
This commit adds Kevin Kreuzer to the Angular GDE page along with a biography, his contributions, and a photograph.

PR Close #37929
2020-07-23 11:03:57 -07:00
Bogdan Bogdanov
51aa4aa1c3 docs: update dynamic-component loading guide (#36959)
The 'entryComponents' array is no longer a special case for dynamic component loading because of the Ivy compiler.

PR Close #36959
2020-07-23 11:01:08 -07:00
Sonu Kapoor
8bb8f98c28 docs: remove duplicate https:// (#38199)
This doc contained a duplicate `http://` before the domain name leading to an invalid link.
This commit fixes this issue.
PR Close #38199
2020-07-23 10:54:44 -07:00
Michael Prentice
e620827fa8 docs: traducir página de inicio, navegación, cuadro de búsqueda y pie de página 2020-07-23 01:50:03 -04:00
Judy Bogart
3c1866b5bb docs: update api reference for router outlet directive (#38166)
Incorporate more specific information about multiple outlets and how to target them, with link to tutorial example.

PR Close #38166
2020-07-22 20:50:12 -07:00
Oussama Ben Brahim
062b8d90af refactor(forms): refactor common validators used in unit tests (#38020)
A util file is added to forms test package:
- it exposes simpleAsyncValidator, asyncValidator and asyncValidatorReturningObservable validators
- it refactors simpleAsyncValidator and asyncValidator to use common promise creation code
- it exposes currentStateOf allowing to get the validation state of a list of AbstractControl

Closes #37831

PR Close #38020
2020-07-22 20:42:43 -07:00
remackgeek
8df888dfb4 fix(elements): run strategy methods in correct zone (#37814)
Default change detection fails in some cases for @angular/elements where
component events are called from the wrong zone.

This fixes the issue by running all ComponentNgElementStrategy methods
in the same zone it was created in.

Fixes #24181

PR Close #37814
2020-07-22 20:35:47 -07:00
Jeremy Elbourn
778ad3776a docs: create coding standards doc (#37700)
Create initial document for Angular framework coding standards. This
document will evolve over time. This version contains all
non-controversial rules as discussed in a recent team meeting. Some text
and examples were copied from angular/components.

PR Close #37700
2020-07-22 20:32:34 -07:00
George Kalpakas
5a733629b5 build(docs-infra): remove boilerplate file listings in example-boilerplate.js (#38173)
To avoid unnecessary code duplication in docs examples, we have some
boilerplate files for various example types (in
`aio/tools/examples/shared/boilerplate/`). These files are copied to
each example project in `aio/content/examples/` (according to the
example's type, as specified in its `example-config.json` file).

Previously, the `example-boilerplate.js`, which is responsible for
copying the boilerplate files, had lists for files to be copied for each
project type and only copied the listed files from the boilerplate
directory to the example directory. This approach had some drawbacks:
- Files need to be updated in two separate locations: in the boilerplate
  directory that includes the files and the file list in
  `example-boilerplate.js`.
- It is easy to add a file in the boilerplate directory but forget to
  add it in `example-boilerplate.js` and not realize that it is not
  being included in the example project (including the generated
  StackBlitz project and ZIP archive).

This commit changes the approach by removing the boilerplate file
listings from `example-boilerplate.js` and copying all files from a
boilerplate directory to example directories. This addresses the above
drawbacks and simplifies the `example-boilerplate.js` script.

I have verified that the resulting code example doc regions as well as
the generated StackBlitz projects and ZIP archives are identical to the
ones generated before this commit.

PR Close #38173
2020-07-22 10:15:09 -07:00
George Kalpakas
65da87722d fix(docs-infra): include .gitignore file in CLI-based docs examples (#38173)
Previously, the `.gitignore` file that is part of the boilerplate files
for CLI-based docs examples (located in
`aio/tools/examples/shared/boilerplate/cli/`) was not added to the
example projects, because it was not included in the boilerplate file
list in `example-boilerplate.js`.

This commit fixes it by adding the `.gitignore` file to the list. This
ensures that docs examples more closely match CLI-generated projects.

PR Close #38173
2020-07-22 10:15:09 -07:00
George Kalpakas
937b89c230 fix(docs-infra): correctly add polyfills.ts file as boilerplate for i18n docs examples (#38173)
Docs examples of type `i18n` need a slightly modified version of
`polyfills.ts` that imports `@angular/localize/init`. Previously, this
file was not included in `i18n` example projects for two reasons:

- While the file was included in the `i18n` boilerplate files (at
  `aio/tools/examples/shared/boilerplate/i18n/`), it was not included in
  the boilerplate file list in `example-boilerplate.js`.
- The file was in the wrong location: It was located at the project root
  instead of inside the `src/` directory.

This commit addresses the above issues (i.e. adds the file to the
boilerplate file list for `i18n` projects and moves the file inside the
`src/` directory).

PR Close #38173
2020-07-22 10:15:09 -07:00
George Kalpakas
b3d81a837b build(docs-infra): remove obsolete systemjs.config.web[.build].js files from docs examples (#38173)
There were some `systemjs.config.web[.build].js` files in the `systemjs`
boilerplate directory that are not used any more. In the past, these
files were used in the Plunker-based live examples, but we no longer use
Plunker for live examples.

This commit removes these obsolete files.

PR Close #38173
2020-07-22 10:15:09 -07:00
George Kalpakas
7491b854b3 build(docs-infra): remove obsolete typings.d.ts files from angular.io and docs examples (#38173)
There were two `typings.d.ts` files with SystemJS module definitions in
`aio/src/` and `aio/tools/examples/shared/boilerplate/cli/`. These are
remnants from old CLI versions that used SystemJS and are no longer
needed. For docs examples specifically, these files were never copied
over to example projects and thus not included in StackBlitz projects
and ZIP archives.

This commit removes these obsolete files.

PR Close #38173
2020-07-22 10:15:09 -07:00
Georgi K
a1c9f7cdb3 docs: fix typo in ng_control.ts (#38157)
PR Close #38157
2020-07-22 10:14:24 -07:00
Doug Parker
d88711c2fc docs: add Ivy and View Engine test scripts (#38149)
Developer docs previously stated to use `yarn bazel test //packages/...` which attempts to test all packages with View
Engine (the default), even though not all support View Engine. This updates the doc to use `yarn test-ivy-aot` and
`yarn test-non-ivy` which tests both Ivy and View Engine while filtering out tests which are not compatible with each
renderer.

PR Close #38149
2020-07-22 10:13:29 -07:00
Boaz Rymland
5e742d29d0 docs: fix typo from singular to plural spelling (#36586)
This commit fixes the spelling of the singular form
of the word function to the plural spelling in
packages/core/src/application_init.ts

PR Close #36586
2020-07-22 10:12:44 -07:00
Andrew Kushnir
970d10c671 release: cut the v10.1.0-next.2 release 2020-07-22 09:55:21 -07:00
Andrew Kushnir
8851ba9c9d docs: release notes for the v10.0.5 release 2020-07-22 09:49:33 -07:00
Alan Cohen
7f82a2c1c8 docs: fix type in lazy-load callout (#38153)
PR Close #38153
2020-07-21 14:30:46 -07:00
Jaime Oliveira
a9910f5991 docs: fix DOCUMENT import path (#38158) (#38159)
PR Close #38159
2020-07-21 11:35:41 -07:00
Andrew Kushnir
ad7046b934 feat(forms): AbstractControl to store raw validators in addition to combined validators function (#37881)
This commit refactors the way we store validators in AbstractControl-based classes:
in addition to the combined validators function that we have, we also store the original list of validators.
This is needed to have an ability to clean them up later at destroy time (currently it's problematic since
they are combined in a single function).

The change preserves backwards compatibility by making sure public APIs stay the same.
The only public API update is the change to the `AbstractControl` class constructor to extend the set
of possible types that it can accept and process (which should not be breaking).

PR Close #37881
2020-07-21 10:30:19 -07:00
Andrew Kushnir
d72b1e44c6 refactor(core): rename synthetic host property and listener instructions (#37145)
This commit updates synthetic host property and listener instruction names to better align with other instructions.
The `ɵɵupdateSyntheticHostBinding` instruction was renamed to `ɵɵsyntheticHostProperty` (to match the `ɵɵhostProperty`
instruction name) and `ɵɵcomponentHostSyntheticListener` was renamed to `ɵɵsyntheticHostListener` since this
instruction is generated for both Components and Directives (so 'component' is removed from the name).
This PR is a followup after PR #35568.

PR Close #37145
2020-07-21 09:09:24 -07:00
Judy Bogart
eae13e42f3 docs: add routing terms to glossary (#38053)
Update glossary to add term definitions for routing; componentless route, link parameters array, router outlet.

PR Close #38053
2020-07-20 17:09:33 -07:00
Ajit Singh
3373453736 feat(common): add ReadonlyMap in place of Map in keyValuePipe (#37311)
ReadonlyMap is a superset of Map, in keyValuePipe we do not change the value of the object so ReadonlyPipe Works right in this case and we can accomodate more types. To accomodate more types added ReadonlyMap in Key Value pipe.

Fixes #37308

PR Close #37311
2020-07-20 14:13:15 -07:00
Temur Tchanukvadze
4a6dcd006b docs(router): fix typos (#38132)
PR Close #38132
2020-07-20 14:12:21 -07:00
Qais Patankar
7c3c8d6d10 docs(common): fix selector field in NgIfAs example component (#35854)
PR Close #35854
2020-07-20 13:35:04 -07:00
Joey Perrott
655da32837 build: update pullapprove to remove @matsko from reviewer lists (#38146)
With @matsko leaving the Angular team, we need to update the pullapprove
configuration to reflect his no longer being a reviewer for file groups
throughout the repository.

PR Close #38146
2020-07-20 13:33:58 -07:00
Kapunahele Wong
5b31a0a294 docs: separate template syntax into multiple docs (#36954)
This is part of a re-factor of template syntax and
structure. The first phase breaks out template syntax
into multiple documents. The second phase will be
a rewrite of each doc.

Specifically, this PR does the following:

- Breaks sections of the current template syntax document each into their own page.
- Corrects the links to and from these new pages.
- Adds template syntax subsection to the left side NAV which contains all the new pages.
- Adds the new files to pullapprove.

PR Close #36954
2020-07-20 11:16:44 -07:00
Sonu Kapoor
5d3d8b8330 docs: add known issue for bazel (#38074)
This commit adds a known issue for windows, when running tests using
`bazal run`, instead of using `bazel test`

PR Close #38074
2020-07-20 11:15:36 -07:00
Andrew Scott
c8c74153b1 refactor(dev-infra): Update triage labels documentation (#38081)
Add new type: confusing and type: use-case labels to the triage readme as well
as clarify that freq and severity are only required for type: bug/fix

PR Close #38081
2020-07-20 11:14:46 -07:00
Andrew Scott
9dc5e8e7e2 refactor(dev-infra): allow use-case and confusing types to be marked as 'triaged' (#38081)
Some issue reports don't really fall into any of the current buckets that count
towards triage level 2: bug/fix, feature, or refactor. Some reports are:
* working as intended but confusing - the labels might be 'type: confusing', 'comp: docs', 'comp: router'
* generally working as originally designed but a use-case could be argued for a different implementation.
 This type of report is a little hard to triage; it may be neither a bug, nor feature but more of a
 'type: use-case'. These may eventually turn into a bug/fix or feature, but can't necessarily be
 put in those buckets immediately.

PR Close #38081
2020-07-20 11:14:46 -07:00
JoostK
1a7a7360b0 fix(compiler): properly associate source spans for implicitly closed elements (#38126)
HTML is very lenient when it comes to closing elements, so Angular's parser has
rules that specify which elements are implicitly closed when closing a tag.
The parser keeps track of the nesting of tag names using a stack and parsing
a closing tag will pop as many elements off the stack as possible, provided
that the elements can be implicitly closed.

For example, consider the following templates:

- `<div><br></div>`, the `<br>` is implicitly closed when parsing `</div>`,
  because `<br>` is a void element.
- `<div><p></div>`, the `<p>` is implicitly closed when parsing `</div>`,
  as `<p>` is allowed to be closed by the closing of its parent element.
- `<ul><li>A <li>B</ul>`, the first `<li>` is implicitly closed when parsing
  the second `<li>`, whereas the second `<li>` would be implicitly closed when
  parsing the `</ul>`.

In all the cases above the parsed structure would be correct, however the source
span of the closing `</div>` would incorrectly be assigned to the element that
is implicitly closed. The problem was that closing an element would associate
the source span with the element at the top of the stack, however this may not
be the element that is actually being closed if some elements would be
implicitly closed.

This commit fixes the issue by assigning the end source span with the element
on the stack that is actually being closed. Any implicitly closed elements that
are popped off the stack will not be assigned an end source span, as the
implicit closing implies that no ending element is present.

Note that there is a difference between self-closed elements such as `<input/>`
and implicitly closed elements such as `<input>`. The former does have an end
source span (identical to its start source span) whereas the latter does not.

Fixes #36118
Resolves FW-2004

PR Close #38126
2020-07-20 10:02:06 -07:00
JoostK
8edf5ba29d refactor(compiler): remove unused parser methods (#38126)
These methods are no longer used so they can safely be removed.

PR Close #38126
2020-07-20 10:02:06 -07:00
crisbeto
72f1eec3ad docs(core): add note about not mutating multi provider arrays (#37645)
Adds a note to the provider docs that users shouldn't mutate an array that
is returned from a `multi` provider, because it can cause unforeseen
consequences in other parts of the app.

Closes #37481.

PR Close #37645
2020-07-20 10:00:05 -07:00
Douglas Parker
136acdfab6 docs: correct flag default values in --strict (#37982)
Docs state that `strictInjectionParameters` is true by default in `ng new`, however this is not the case in `10.0.1`. It is only set when `--strict` is provided. Clarified that the `--strict` flag is required.

`strictTemplates` does not mention anything about `--strict`, so I included a similar point that it is `true` when a new project is generated with `--strict`.

PR Close #37982
2020-07-17 16:26:49 -07:00
Misko Hevery
095cfd961d build: Ignore .history for the xyz.local-history VSCode extension (#38121)
Ignore .history for the xyz.local-history VSCode extension

PR Close #38121
2020-07-17 13:33:39 -07:00
crisbeto
38a7021d5e fix(core): error due to integer overflow when there are too many host bindings (#38014)
We currently use 16 bits to store information about nodes in a view.
The 16 bits give us 65536 entries in the array, but the problem is that while
the number is large, it can be reached by ~4300 directive instances with host
bindings which could realistically happen is a very large view, as seen in #37876.
Once we hit the limit, we end up overflowing which eventually leads to a runtime error.

These changes bump to using 20 bits which gives us around 1048576 entries in
the array or 16 times more than the current amount which could still technically
be reached, but is much less likely and the user may start hitting browser limitations
by that point.

I picked the 20 bit number since it gives us enough buffer over the 16 bit one,
while not being as massive as a 24 bit or 32 bit.

I've also added a dev mode assertion so it's easier to track down if it happens
again in the future.

Fixes #37876.

PR Close #38014
2020-07-17 12:58:15 -07:00
Saif
b3b03c35b5 fix(docs-infra): correctly display SVG icons in IE11 (#38046)
Fix two issues that affected displaying of SVG icons in IE11:

1. All SVG icons except for one appeared empty. This was related how the
CustomIconRegistry re-used the same <div> element to create all
SVG elements.

2. The GitHub and Twitter buttons next to the search bar were not sized
properly.

Fixes #37847

PR Close #38046
2020-07-17 11:44:34 -07:00
Saif
fd45f7485d docs(docs-infra): reformat redundant sentence (#38109)
reformat sentence uses the npm package manager since npm is node package manager

Fixes #38106

PR Close #38109
2020-07-17 11:39:16 -07:00
Keen Yee Liau
58f6079873 build(language-service): add script to build package locally (#38103)
This commit adds a script to build @angular/language-service
locally so that it can be consumed by the Angular extension for
local development.

PR Close #38103
2020-07-16 16:39:54 -07:00
Paul Gschwendtner
e382632473 build: fix symbol extractor not dealing with ES2015 classes (#38093)
We recently reworked our `ng_rollup_bundle` rule to no longer output
ESM5 and to optimize applications properly (previously applications were
not optimized properly due to incorrect build optimizer setup).

This change meant that a lot of symbols have been removed from the
golden correctly. See: fd65958b887f6ea8dd5235e6de1d533e4c578602

Unfortunately though, a few symbols have been accidentally removed
because they are now part of the bundle as ES2015 classes which the
symbol extractor does not pick up. This commit fixes the symbol
extractor to capture ES2015 classes. We also update the golden to
reflect this change.

PR Close #38093
2020-07-16 13:54:23 -07:00
Pete Bacon Darwin
cf9a47ba53 feat(localize): allow duplicate messages to be handled during extraction (#38082)
Previously, the i18n message extractor just quietly ignored messages that
it extracted that had the same id. It can be helpful to identify these
to track down messages that have the same id but different message text.

Now the messages are checked for duplicate ids with different message text.
Any that are found can be reported based on the new `--duplicateMessageHandling`
command line option (or `duplicateMessageHandling` API options property).

* "ignore" - no action is taken
* "warning" - a diagnostic warning is written to the logger
* "error" - the extractor throws an error and exits

Fixes #38077

PR Close #38082
2020-07-16 13:53:38 -07:00
Pete Bacon Darwin
56dd3e77ac refactor(localize): remove unnecessary ! operator (#38082)
The messages property always exists so there is no need for the ! operator.

PR Close #38082
2020-07-16 13:53:38 -07:00
Judy Bogart
6c9401c338 docs: update router api documentation (#37980)
Edit descriptions, usage examples, and add links to be complete and consistent with API reference doc style

PR Close #37980
2020-07-16 13:52:40 -07:00
Andrew Kushnir
019a696a6a Revert "build: remove obsolete Bazel function ctx.new_file (#38080)" (#38101)
This reverts commit 406f801b7072f65491eac332056a8e444027dc10.

The reason for the revert is the breakage in i18n subsystem in g3.

PR Close #38101
2020-07-16 11:06:23 -07:00
Keen Yee Liau
8b25a64200 build(language-service): remove typescript from ivy bundle (#38088)
Currently the Ivy language service bundle is [10MB](
https://unpkg.com/browse/@angular/language-service@10.0.4/bundles/) because we
accidentally included typescript in the bundle.

With this change, the bundle size goes down to 1.6MB, which is even smaller
than the View Engine bundle (1.8MB).

```bash
$ yarn bazel build //packages/language-service/bundles:ivy
$ ls -lh dist/bin/packages/language-service/bundles/ivy.umd.js
1.6M Jul 15 15:49 dist/bin/packages/language-service/bundles/ivy.umd.js
```

PR Close #38088
2020-07-16 11:04:57 -07:00
Keen Yee Liau
bd71f10234 build(language-service): Remove ls_rollup_bundle (#38086)
`ls_rollup_bundle` is no longer needed since we could invoke `ng_rollup_bundle`
directly.

Background: language service runs rollup to produce a single file to reduce
startup time in the editor. However, due to the need to load dynamic versions
of typescript at runtime (think the case where users can change typescript
version in their editor), we hack the "banner" to export a CommonJS default function,
so that we could dynamically load the typescript module provided at runtime via AMD
and use it throughout the implementation.

PR Close #38086
2020-07-16 11:04:28 -07:00
Jeremy Elbourn
e0b35bfc18 ci: add more owners for some categories (#37994)
* Add petebacondarwin to public-api, size-tracking, and circular-dependencies
* Add mhevery, josephperrott, and jelbourn to code-ownership

PR Close #37994
2020-07-16 11:03:55 -07:00
Ajit Singh
c1539b16ae docs: add Ajit Singh to the collaborators (#37792)
Ajit Singh is a newly added collborator after a few months of contributing add him to the contributors.json

PR Close #37792
2020-07-16 11:02:07 -07:00
Misko Hevery
737506e79c fix(core): Allow modification of lifecycle hooks any time before bootstrap (#35464)
Currently we read lifecycle hooks eagerly during `ɵɵdefineComponent`.
The result is that it is not possible to do any sort of meta-programing
such as mixins or adding lifecycle hooks using custom decorators since
any such code executes after `ɵɵdefineComponent` has extracted the
lifecycle hooks from the prototype. Additionally the behavior is
inconsistent between AOT and JIT mode. In JIT mode overriding lifecycle
hooks is possible because the whole `ɵɵdefineComponent` is placed in
getter which is executed lazily. This is because JIT mode must compile a
template which can be specified as `templateURL` and those we are
waiting for its resolution.

- `+` `ɵɵdefineComponent` becomes smaller as it no longer needs to copy
  lifecycle hooks from prototype to `ComponentDef`
- `-` `ɵɵNgOnChangesFeature` feature is now always included with the
  codebase as it is no longer tree shakable.

Previously we have read lifecycle hooks from prototype in the
`ɵɵdefineComponent` so that lifecycle hook access would be monomorphic.
This decision was made before we had `T*` data structures. By not
reading the lifecycle hooks we are moving the megamorhic read form
`ɵɵdefineComponent` to instructions. However, the reads happen on
`firstTemplatePass` only and are subsequently cached in the `T*` data
structures. The result is that the overall performance should be same
(or slightly better as the intermediate `ComponentDef` has been
removed.)

- [ ] Remove `ɵɵNgOnChangesFeature` from compiler. (It will no longer
      be a feature.)
- [ ] Discuss the future of `Features` as they hinder meta-programing.

Fix #30497

PR Close #35464
2020-07-15 16:22:46 -07:00
Emma Twersky
469aba0140 docs: add Emma Twersky to DevRel Contributor page (#38084)
This commit adds Emma Twersky to the Angular Contributors page along with a bio & a photograph.

PR Close #38084
2020-07-15 13:50:39 -07:00
George Kalpakas
d8c47b971c docs: fix typo in "Creating libraries" guide (by publishing...ensures --> publishing...ensures) (#38032)
PR Close #38032
2020-07-15 13:12:14 -07:00
George Kalpakas
24b420527a docs(service-worker): fix typos in SwRegistrationOptions API docs (#38047)
PR Close #38047
2020-07-15 13:10:25 -07:00
crisbeto
bf641e1b4b fix(core): incorrectly validating properties on ng-content and ng-container (#37773)
Fixes the following issues related to how we validate properties during JIT:
- The invalid property warning was printing `null` as the node name
for `ng-content`. The problem is that when generating a template from
 `ng-content` we weren't capturing the node name.
- We weren't running property validation on `ng-container` at all.
This used to be supported on ViewEngine and seems like an oversight.

In the process of making these changes, I found and cleaned up a
few places where we were passing in `LView` unnecessarily.

PR Close #37773
2020-07-15 12:39:39 -07:00
Laurent Le Brun
406f801b70 build: remove obsolete Bazel function ctx.new_file (#38080)
The function was removed by default in Bazel 0.27.
It is still accessible with the flag `--incompatible_new_actions_api`
(which is set in Google code base), but the flag will be deleted very soon.

This change should be a no-op for Bazel users. The change was tested in
Google (cl/318277076) and should be safe as well.

PR Close #38080
2020-07-15 12:39:00 -07:00
George Kalpakas
c8e77d8536 ci(docs-infra): increase minimum a11y scores for various pages (#37899)
As part of our CI checks, we ensure the a11y score on certain angular.io
pages do not fall below some thresholds.

This commit increases these thresholds based on our current scores to
ensure we do not regress below current values.

PR Close #37899
2020-07-15 12:38:07 -07:00
Sonu Kapoor
6ea2d1e20e build(docs-infra): upgrade lighthouse to 6.1.0 (#37899)
To take advantage of lazy loaded images `img[loading=lazy]`, this commit
upgrades lighthouse to version 6.1.0.

Closes #35965

PR Close #37899
2020-07-15 12:38:07 -07:00
Wagner Maciel
09eee5b312 fix(dev-infra): add missing BUILD file to dev-infra/bazel:files (#38026)
* Without this BUILD file we were seeing errors about the reference to
  expand_template.bzl in ng_rollup_bundle.bzl because dev-infra/bazel
  was not considered a package.

PR Close #38026
2020-07-15 12:34:46 -07:00
Wagner Maciel
904ebfebf3 fix(dev-infra): fix broken zone.js substitution for dev-infra:npm_package (#38026)
* fix substitution that was broken by PR #36540 to match
  the new import path

PR Close #38026
2020-07-15 12:34:46 -07:00
Paul Gschwendtner
545f1dbac9 feat(dev-infra): add bazel firefox browser with RBE compatibility (#38029)
Adds Firefox as browser to `dev-infra/browsers` with RBE
compatibility. The default Firefox browser is not compatible similar to
the default Chromium version exposed by `rules_webtesting`.

The Angular Components repository will use this browser target as
it enables RBE support. Also it gives us more flexibility about
the Firefox version we test against. The version provided by
`rules_webtesting` is very old and most likely not frequently
updated (based on past experience).

PR Close #38029
2020-07-15 12:34:05 -07:00
Judy Bogart
b00121c9a6 docs: update reference doc for router guards and resolvers (#38079)
Complete and clarify descriptions and example of the guard and resolver functions in Router API documentation.

PR Close #38079
2020-07-15 12:32:10 -07:00
Windvis
45d79efc3f docs: remove all references to Angular Console (#37608)
Angular Console has been renamed and links no longer work. It has been decided to remove references to this third-party tool from the AIO documentation.

Closes #37604

PR Close #37608
2020-07-15 12:30:59 -07:00
atscott
1d9e56eba0 docs: release notes for the v10.0.4 release 2020-07-15 11:22:18 -07:00
atscott
e7c722574f release: cut the v10.1.0-next.1 release 2020-07-15 10:07:43 -07:00
Pete Bacon Darwin
b358495a6c fix(ngcc): report a warning if ngcc tries to use a solution-style tsconfig (#38003)
In CLI v10 there was a move to use the new solution-style tsconfig
which became available in TS 3.9.

The result of this is that the standard tsconfig.json no longer contains
important information such as "paths" mappings, which ngcc might need to
correctly compute dependencies.

ngcc (and ngc and tsc) infer the path to tsconfig.json if not given an
explicit tsconfig file-path. But now that means it infers the solution
tsconfig rather than one that contains the useful information it used to
get.

This commit logs a warning in this case to inform the developer
that they might not have meant to load this tsconfig and offer
alternative options.

Fixes #36386

PR Close #38003
2020-07-14 13:21:31 -07:00
Sonu Kapoor
f4fac406b9 docs(core): fixes minor typo in initNgDevMode function docs (#38042)
PR Close #38042
2020-07-14 13:17:32 -07:00
danranVm
5fd2c8f2d6 refactor(forms): remove unnecessary ! operators from validators (#36805)
When we added the strict null checks, the lexer had some `!` operators added to prevent the compilation from failing.

See #24571

PR Close #36805
2020-07-14 11:01:53 -07:00
Aristeidis Bampakos
421e807f80 docs(forms): Fix typos in template-driven forms tutorial (#37933)
Fix two typos in the 'Building a template-driven form` that caused the guide to not be displayed correctly.

PR Close #37933
2020-07-14 11:01:29 -07:00
Aristeidis Bampakos
df8b387570 docs(forms): Minor fix in forms overview guide (#37933)
Remove an article from the `Data flow in forms` section of the forms overview guide. The use of `the` and `a` together
is not syntactically correct.

PR Close #37933
2020-07-14 11:01:29 -07:00
David Martinez Barreiro
f01b0337d2 docs(router): fix typo in "spotlight on pathmatch" (#38039)
https://angular.io/guide/router-tutorial-toh#pathmatch

PR Close #38039
2020-07-14 09:20:18 -07:00
RN Lee
4ec3026a9a docs(router): fix typo in https://angular.io/guide/router#activated-route (#38034)
In angular.io, it linked to the wrong part of the page. https://angular.io/guide/router#activated-route

PR Close #38034
2020-07-14 09:10:26 -07:00
George Kalpakas
9021d3f5e1 docs: fix live examples in testing guides (#38038)
In #37957, parts of the testing guide were broken out into separate
guides. As part of that work, the `<live-example>` tags were also copied
to the new guides. These `<live-example>` tags did not specify the
targeted example project via the `name` attribute, thus they were
implicitly targeting the example with the same name as the guide they
were in. See the [Docs style guide][1] for more info.

However, there is only one example project (`testing/`) and all
`<live-example>` tags were supposed to target that. This worked fine on
the `testing.md` guide, but it broke on other guides (which tried to
target non-existing example projects based on their names).

This commit fixes it by explicitly specifying which example is targeted
by the `<live-example>` tags. It also removes the `embedded-style`
attribute that has no effect.

[1]: https://angular.io/guide/docs-style-guide#live-examples

Fixes #38036

PR Close #38038
2020-07-14 09:10:00 -07:00
Samuel
81542b3b72 docs(core): Fixed typo in Type JSdoc (#37930)
Updated comment doc in packages/core/src/interface/type.ts

PR Close #37930
2020-07-13 14:30:55 -07:00
Andrew Scott
9185c6e971 fix(router): ensure duplicate popstate/hashchange events are handled correctly (#37674)
The current method of handling duplicate navigations caused by 'hashchange' and 'popstate' events for the same url change does not correctly handle cancelled navigations. Because `scheduleNavigation` is called in a `setTimeout` in the location change subscription, the duplicate navigations are not flushed at the same time. This means that if the initial navigation hits a guard that schedules a new navigation, the navigation for the duplicate event will not compare to the correct transition (because we inserted another navigation between the duplicates). See https://github.com/angular/angular/issues/16710#issuecomment-646919529

Fixes #16710

PR Close #37674
2020-07-13 14:24:53 -07:00
Paul Gschwendtner
69472a1ed0 refactor(dev-infra): allow for consumption with rules_nodejs v2.0.0 (#37968)
With `rules_nodejs` v2.0.0 being in RC phase currently, we should
make sure that the package is compatible so that we can use it
in the components repo in combination with rules_nodejs v2.0.0.

In v2.0.0 of the NodeJS rules, Bazel workspaces are recommended
to no longer be symlinked under a separate repository. Instead,
bazel rules and targets should be accessed directly from the
user-selected NPM repository. Usually `@npm`, so that the import
changes to `@npm//@angular/dev-infra-private/<..>`.

PR Close #37968
2020-07-13 14:18:22 -07:00
ivanwonder
10aba15154 fix(language-service): remove completion for string (#37983)
If the user inputs a string(e.g. `<div [ngClass]="'str~{cursor}'"></div>`), the completion is useless.

PR Close #37983
2020-07-13 14:16:56 -07:00
Shapovalov-Dmitry
36dd817913 docs: fixed typo in https://angular.io/guide/glossary (#36220)
PR Close #36220
2020-07-13 14:10:06 -07:00
Krzysztof Platis
0eaa084ced docs(router): fix typo 'containa' to 'contains' (#36764)
Closes #36763

PR Close #36764
2020-07-13 14:09:32 -07:00
Israel Guzman
62e19c8813 docs: Add Scully to resources.json (#37678)
Add Scully to the resource page by adding it to the "Tooling" subcategory in resources.json file

PR Close #37678
2020-07-13 14:08:40 -07:00
cindygk
95669df4c3 docs: remove Markus Padourek from angular collaborators (#37962)
This person was never onboarded

PR Close #37962
2020-07-13 14:08:13 -07:00
Pete Bacon Darwin
6b311552f0 fix(compiler-cli): ensure file_system handles mixed Windows drives (#37959)
The `fs.relative()` method assumed that the file-system is a single tree,
which is not the case in Windows, where you can have multiple drives,
e.g. `C:`, `D:` etc.

This commit changes `fs.relative()` so that it no longer forces the result
to be a `PathSegment` and then flows that refactoring through the rest of
the compiler-cli (and ngcc).  The main difference is that now, in some cases,
we needed to check whether the result is "rooted", i.e an `AbsoluteFsPath`,
rather than a `PathSegment`, before using it.

Fixes #36777

PR Close #37959
2020-07-13 12:05:21 -07:00
Olegas Goncarovas
66947cf9fa docs: fix typo in router.md (#37227)
This commit fixes a typo in the router documentation. "Benfits of a routing module" => "Benefits of a routing module"

PR Close #37227
2020-07-13 09:27:28 -07:00
David Auza
a259a84d3f docs(http): Remove extra semicolons in the http guide (#37228)
An extra semicolon in searchHeroes function was removed in the http guide
found in aio/content/guide/http.md

docs(http): Remove extra semicolon in a code example found in the http guide

Removed extra semicolon in handleError function in the file located at
aio/content/examples/http/src/app/config/config.service.ts, which serves
as a source of code examples for the http guide.

Replace a comma for a dot in the comment at line 79 to ensure consistency
with the rest of the document.

Capitalized and added a dot at the end of the comment at line 84 to
ensure consistency with the other comments.

PR Close #37228
2020-07-13 09:25:19 -07:00
Pete Bacon Darwin
d1aa4678be build(docs-infra): ensure the correct files are in the i18n example (#37947)
The Stackblitz and zip-file include `doc-files` unnecssarily and are missing
the locale files. This commit updates the `stackblitz.json` to fix this.

PR Close #37947
2020-07-13 09:24:33 -07:00
Pete Bacon Darwin
04c220bbdf build(docs-infra): remove unnecessary zipper.json file (#37947)
The `zipper.json` file is only needed if the example does not
have a `stackblitz.json` file, which this (i18n) example does.

Moreover, it appears that having both can cause the generated
zip file to be corrupted and not unzippable.

Fixes #37849

PR Close #37947
2020-07-13 09:24:33 -07:00
Igor Minar
72d6032fa4 docs: reformat and update CONTRIBUTING.md (#37951)
This doc is very old and rusty. I'm reformatting it to follow the one-setence-per-line rule.
I also updated a few sections, since they were either poorly written or obsolete.

PR Close #37951
2020-07-13 09:23:03 -07:00
Igor Minar
53d4859f48 build: add .gitmessage file with commit message template (#37951)
Git provides a way to create a commit message template via the `.gitmessage` file.

Introduce an Angular-specific .gitmessage template based on the original Commit Message Guidelines.
https://github.com/angular/angular/blob/master/CONTRIBUTING.md#-commit-message-guidelines

If this template workflow is proven in practice, we can move the commit message guidelines into the
.gitmessage file to prevent duplication of the content.

This change is a follow up on #37949 and is inspired by info found in the following blog post:
https://thoughtbot.com/blog/better-commit-messages-with-a-gitmessage-template

PR Close #37951
2020-07-13 09:23:03 -07:00
Igor Minar
f66f4a1b3f build: adding shared .ng-dev/gitconfig file for convenience and consistent git config (#37951)
This file is inert unless it's explicitly included into the local git config via:

```
git config --add include.path '../.ng-dev/gitconfig'
```

Calling that command will append the following into `.git/config` of the current git workspace
(i.e. $GIT_DIR, typically `angular/.git/config`):

```
[include]
	path = ../.ng-dev/gitconfig
```

I'm intentionally keeping the config inert for now until we prove that this is a good idea.

Eventually we could roll this change out to all the contributors via an npm post-install script.

PR Close #37951
2020-07-13 09:23:03 -07:00
David Shevitz 🔵
88d68d2d21 docs: Move router tutorial (toh) from router.md to new file (#37979)
In an effort to make angular documentation easier for users to read,
we are moving the router tutorial currently in router.md to a new file.
To support this change, we have done the following:

* Update files to fix any broken links caused by moving the file
* Updated the new file to follow tutorial guidelines
* Add the new file to the table of  contents under, Tutorials.

PR Close #37979
2020-07-10 15:04:55 -07:00
Andrew Scott
4783a071f3 docs(router): fix routerLink docs (#37997)
The current content for the routerLink commands input does not make it to aio.
fixes #35414

PR Close #37997
2020-07-10 11:24:28 -07:00
crisbeto
9322b9a060 fix(compiler): check more cases for pipe usage inside host bindings (#37883)
Builds on top of #34655 to support more cases that could be using a pipe inside host bindings (e.g. ternary expressions or function calls).

Fixes #37610.

PR Close #37883
2020-07-10 11:00:20 -07:00
Paul Gschwendtner
9bd4b74b06 feat(dev-infra): commit message validation should skip lines consisting of URLs (#37890)
The dev-infra commit message validation optionally can check for lines
to not exceed a given amount of characters. This is desired for most
commit messages, but sometimes not actionable if a long URL is inserted
into the commit message. With this commit, we skip the max line length
check for lines that start with an URL.

PR Close #37890
2020-07-10 10:59:28 -07:00
Paul Gschwendtner
e6afcf1f94 build: split dev-infra configuration into individual files (#37890)
Splits the dev-infra configurations into individual files inside the
`.ng-dev/` folder. This helps with clarity as there is no single
configuration file that becomes extremely large and difficult to
maintain.

Additionally, more explicit configuration types are now used. This
fixed the max-line length setting for commit message validation.
This option is currently named incorrectly and a noop.

PR Close #37890
2020-07-10 10:59:28 -07:00
Paul Gschwendtner
4b4b74548d fix(dev-infra): include bazel utility files in npm package (#37891)
We recently added a new folder for common bazel utilities
to `dev-infra`. The `ng_rollup_bundle` rule relies on an
utility that is provided by this `bazel/` folder.

Unfortunately though it looks like this folder is currently
not included in the NPM package, so that the `ng_rollup_bundle`
rule does not work as expected. This commit fixes that by
including the bazel utilities in the NPM package.

PR Close #37891
2020-07-10 10:06:11 -07:00
Paul Gschwendtner
1550663b9e fix(bazel): ng_module rule does not expose flat module information in Ivy (#36971)
The `ng_module` rule supports the generation of flat module bundles. In
View Engine, information about this flat module bundle is exposed
as a Bazel provider. This is helpful as other rules like `ng_package`
could rely on this information to determine entry-points for the APF.

With Ivy this currently does not work because the flat module
information is not exposed in the provider. The reason for this is
unclear. We should also provide this information in Ivy so that rules
like `ng_package` can also determine the correct entry-points when a
package is built specifically with `--config=ivy`.

PR Close #36971
2020-07-09 22:11:17 +00:00
Advaith3600
c40cbecdd1 docs(animations): Added consistency in code examples (#37081)
PR Close #37081
2020-07-09 22:08:00 +00:00
Santosh Yadav
209a365511 docs: add explanation for providedIn any (#35283)
Angular 9 introduces a new value for providedIn called `any` which lets us use unique instance
for servicec in each lazy loaded module, this PR is to document the same

fixes #35179

PR Close #35283
2020-07-09 10:12:00 -07:00
George Kalpakas
fb735d625b refactor(service-worker): use nominal type for normalized URLs (#37922)
Some ServiceWorker operations and methods require normalized URLs.
Previously, the generic `string` type was used.

This commit introduces a new `NormalizedUrl` type, a special kind of
`string`, to make this requirement explicit and use the type system to
enforce it.

PR Close #37922
2020-07-09 09:44:57 -07:00
George Kalpakas
d19ef6534f fix(service-worker): correctly handle relative base href (#37922)
In some cases, it is useful to use a relative base href in the app (e.g.
when an app has to be accessible on different URLs, such as on an
intranet and the internet - see #25055 for a related discussion).

Previously, the Angular ServiceWorker was not able to handle relative
base hrefs (for example when building the with `--base-href=./`).

This commit fixes this by normalizing all URLs from the ServiceWorker
configuration wrt the ServiceWorker's scope.

Fixes #25055

PR Close #37922
2020-07-09 09:44:57 -07:00
George Kalpakas
667aba7508 test(service-worker): make mock implementations more similar to actual ones (#37922)
This commit makes the mock implementations used is ServiceWorker tests
behave more similar to the actual ones.

PR Close #37922
2020-07-09 09:44:57 -07:00
George Kalpakas
d380e93b82 refactor(service-worker): move asset URL normalization to Adapter (#37922)
This is in preparation of enabling the ServiceWorker to handle
relative paths in `ngsw.json` (as discussed in #25055), which will
require normalizing URLs in other parts of the ServiceWorker.

PR Close #37922
2020-07-09 09:44:56 -07:00
George Kalpakas
2156beed0c fix(service-worker): correctly serve ngsw/state with a non-root SW scope (#37922)
The Angular ServiceWorker can serve requests to a special virtual path,
`ngsw/state`, showing [information about its internal state][1], which
can be useful for debugging.

Previously, this would only work if the ServiceWorker's [scope][2] was
the root directory (`/`). Otherwise, (e.g. when building the app with
`--baseHref=/some/path/`), the ServiceWorker would fail to detect a
request to `/some/path/ngsw/state` as matching `ngsw/state` and would
not serve it with the debugging information.

This commit fixes it by ensuring that the ServiceWorker's scope is taken
into account when detecting a request to `ngsw/state`.

[1]: https://angular.io/guide/service-worker-devops#locating-and-analyzing-debugging-information
[2]: https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration/scope

Fixes #30505

PR Close #37922
2020-07-09 09:44:56 -07:00
Abdellatif Ait boudad
b98314e306 docs: add Formly library to the list of resources (#37257)
This commit adds the Formly library to the Angular list of resources at aio/content/marketing/resources.json.

PR Close #37257
2020-07-09 09:19:48 -07:00
Daniel
e50c7dcc4c docs(router): get rid of unnecessary line in wildcard route example and fixing wildcard docregions (#37127)
The wildcard example leads to display a 404 page with the PageNotFoundComponent. But before, there is a wildcard to redirect to the FirstComponent and because of the routes order the FirstComponent will be displayed; which it is not the target of the wildcard route example code. Also, fixing some wildcard docregions
PR Close #37127
2020-07-08 16:04:51 -07:00
Paul Gschwendtner
6b731a067a test: fix test failure in saucelabs ivy ie10 (#37892)
One of the ivy acceptance tests currently fails in IE10. This
is because we recently added a new test that asserts that injecting
`ViewRef` results in a `NullInjectorError`.

Due to limitations in TypeScript and in polyfills for `setPrototypeOf`,
the error cannot be thrown as `ViewRef` is always considered injectable.
In reality, `ViewRef` should not be injectable, as explicitly noted
in c00f4ab2ae.

There seems no way to simulate the proper prototype chain in such
browsers that do not natively support `__proto__`, so TypeScript
and `core-js` polyfills simply break the prototype chain and
assign inherited properties directly on `ViewRef`. i.e. so that
`ViewRef.__NG_ELEMENT_ID__` exists and DI picks it up.

There is a way for TypeScript to theoretically generate proper
prototype chain in ES5 output, but they intend to only bother
about the proper prototype chain in ES6 where `setPrototypeOf`
etc. are offically standarized. See the response:

https://github.com/microsoft/TypeScript/issues/1601#issuecomment-94892833.

PR Close #37892
2020-07-08 16:03:33 -07:00
George Kalpakas
0a3dbc1e8a build(docs-infra): update @angular/cli to 10.0.1 (#37898)
This commit updates the version of Angular CLI used in angular.io to
version 10.0.1. It also reverts some changes (namely commits 38dfbc775f1
and eee2fd22e0a) which were made due to an older bug that is fixed in
the latest version. See #37688 for more details.

Fixes #37699

PR Close #37898
2020-07-08 16:02:46 -07:00
George Kalpakas
b24a24ec58 refactor(docs-infra): avoid Material style duplication warning (#37898)
This commit removes some duplicate imports of Material themes and
theming-related utilities. While this change does not have any impact on
the size of the generated `styles.css` file, it silences a build warning
pointing to [Avoiding duplicated theming styles][1].

[1]: db4b0cd1bf/guides/duplicate-theming-styles.md

PR Close #37898
2020-07-08 16:02:46 -07:00
George Kalpakas
13ef5d6c7d build(docs-infra): update @angular/material to 10.0.1 (#37898)
This commit updates the version of Angular Components used in angular.io
to version 10.0.1. It also updates the angular.io app to adapt to
breaking changes.

PR Close #37898
2020-07-08 16:02:46 -07:00
George Kalpakas
54373cc895 build(docs-infra): update @angular/core to 10.0.2 (#37898)
This commit updates the version of Angular framework used in angular.io
to version 10.0.2. It also features a commit message with a 100+ chars
long body.

PR Close #37898
2020-07-08 16:02:46 -07:00
pkozlowski-opensource
bbe3543c69 refactor(core): remove duplicated WrappedValue class (#37940)
Before this refactoring we had the WrappedValue class in
2 separate places:
- packages/core/src/change_detection/change_detection_util.ts
- packages/core/src/util/WrappedValue.ts

This commit removes the duplicate, leaving the class that has
the deprecation notice.

PR Close #37940
2020-07-08 16:02:16 -07:00
Kapunahele Wong
bdbbff6a1a docs: break testing doc into multiple docs (#37957)
This commit breaks up the testing document into nine total documents, with each document focusing on an existing section of the current testing documentation. There are no content changes.

PR Close #37957
2020-07-08 16:01:49 -07:00
tphobe9312
f81d3f6199 docs(elements): fix typo (you custom element --> your custom element) (#37966)
PR Close #37966
2020-07-08 16:01:22 -07:00
Igor Minar
d0c0f25a48 ci: decrease the minBodyLength commit message limit to 20 chars (#37949)
The motivation behind this change is to improve the productivity in the angular/angular repo
without sacrificing the original goal of having better understanding of changes within
the repo.

When the minBodyLength limit was originally introduced the goal was simple: force
committers to provide more contextual information for each change coming into the
repo. Too often we found ourselves in a situation where nobody understood what
motivated some of the changes and we needed more contextual info to know if the
change was correct, desirable, and still relevant (at a later point in time).

When the limit was introduced, we needed to pick a minimum body length - given no
data, and frustration with even big changes being committed with just a words in
the subject (along the lines of "fix(core): fixing a bug"), we overcompensated
and started off with a really high bar of minBodyLength set to 100 chars.

This turned out to be impractical and created a big friction point in making valid
changes in the angular/angular repo, and in fact caused some of the refactorings
and smaller changes to be either skipped or combined into other commits which
increased the burden for code reviewers.

The evidence in the friction points can be seen in the number of PRs that fail to pass
the current lint check on the first try, but more importantly also in the "creative"
writing that some of the committers are forced to resort to in order to satisfy the
current checks. Examples:

- 286fbf42c6
- b2816a1536

Given that we primarily care to document the motivation behind each change
(the answer to the ultimate question: WHY?), I've collected several *common* &
*valid* commit messages that are minimalistic and capture the WHY sufficiently:

```
Refactoring for readability.  => 28 chars
Improving variable naming.    => 26 chars
Additional test coverage.     => 25 chars
Cleaning up the code.         => 21 chars
Simplified the code.          => 20 chars
```

These commit message bodies in addition to the commit message subject should
sufficiently satisfy the need to capture the context and motivation behind each
change without creating an undue burden on committers.

Example minimalistic commit message:

------

refactor(core): cleanup the expression parser

Simplifying the code.

----

Given this research, I'm decreasing the minBodyLenth in angular/angular to 20 chars.

The commit message quality can be additionally improved by implementing a commit message
template via `.gitmessage` that will guide the committers in following our commit message
guidelines via instructions provided in the form of in-the-flow help rather than as an after
the fact lint check.

More info: https://thoughtbot.com/blog/better-commit-messages-with-a-gitmessage-template

I'm intentionally deferring such change for a separate PR as not to complicate or delay the
minBodyLength limit decrease.

PR Close #37949
2020-07-08 15:43:02 -07:00
Alex Rickabaugh
1f796e9479 release: cut the v10.1.0-next.0 release 2020-07-08 14:21:29 -07:00
Alex Rickabaugh
1237d9cbea docs: release notes for the v10.0.3 release 2020-07-08 14:00:58 -07:00
Alex Rickabaugh
b3969e9654 docs: release notes for the v9.1.12 release 2020-07-08 13:40:27 -07:00
Olivier Combe
6eb868b63a build(compiler-cli): fix bazel deps rules for ngtsc testing packages (#37977)
The ngtsc testing packages for file_system and logging were missing from the bazel deps rules, which means that they were not included in the releases

PR Close #37977
2020-07-08 12:05:22 -07:00
Paul Gschwendtner
82a2207f4a build: filter out duplicate cherry-picked commits in changelog (#37956)
Often changelogs are generated from the patch branch and then
cherry-picked into the `CHANGELOG.md` file in `master` for
better access and readability. This is problematic though as
`conventional-changelog` (the tool we use for generating the
changelog), will duplicate commits when a future changelog
is generated from `master` then (i.e. for a new minor release).

This happens because conventional-changelog always generates the
changelog from the latest tag in a given branch to `HEAD`. The
tag in the patch branch does not correspond to any SHA in `master`
so the intersection of commits is not automatically omitted.

We work around this naively (until we have a better tool provided
by dev-infra), by deduping commits that are already part of the
changelog. This has proven to work as expected in the components
repo.

PR Close #37956
2020-07-08 12:04:46 -07:00
George Kalpakas
289a96b078 docs: minor fixes to docs related to updating to v10 (#37897)
This commit includes a couple of minor fixes to docs related to updating
to v10:
- Fix markdown link in "Updating to Angular version 10" guide.
- Correctly display numbered list in
  "Solution-style `tsconfig.json` migration" guide.

PR Close #37897
2020-07-07 12:17:04 -07:00
Paul Gschwendtner
cb2ab26296 feat(dev-infra): merge script should link to original commit when cherry-picking with API strategy (#37889)
The merge script uses `git cherry-pick` for both the API merge strategy
and the autosquash strategy. It uses cherry-pick to push commits to
different target branches (e.g. into the `10.0.x` branch).

Those commits never point to the commits that landed in the primary
Github branch though. For the autosquash strategy the pull request number
is always included, so there is a way to go back to the source. On the other
hand though, for commits cherry-picked in the API merge strategy, the
pull request number might not always be included (due to Github's
implementation of the rebase merge method).

e.g.
27f52711c0

For those cases we'd want to link the cherry-picked commits to the
original commits so that the corresponding PR is easier to track
down. This is not needed for the autosquash strategy (as outlined
before), but it would have been good for consistency. Unfortunately
though this would rather complicate the strategy as the autosquash
strategy cherry-picks directly from the PR head, so the SHAs that
are used in the primary branch are not known.

PR Close #37889
2020-07-07 12:16:21 -07:00
George Kalpakas
79850983e6 fix(docs-infra): prevent search-bar from overlapping nav-items (#37938)
As part of angular.io's responsive layout, the menu shown in the top-bar
is collapsed into the sidenav on narrow screens at the point where the
search-bar (on the right side of the top-bar) would overlap with the
menu's nav-items.

Previously, the value used as break-point would work on marketing pages,
where the hamburger button is not shown on wide screens. However, on
docs pages (where the hamburger button is always shown, pushing the menu
further to the right), the search-bar would still overlap the menu
nav-items on some resolutions.

This commit fixes it by raising the screen width threshold at a value
that ensures there is no overlap even on pages where the hamburger
button is visible alongside the top-bar menu.

Fixes #37937

PR Close #37938
2020-07-06 13:57:37 -07:00
George Kalpakas
fc7e77934f refactor(docs-infra): decouple showing the top-menu in top-bar from showing the sidenav (#37938)
As part of angular.io's responsive layout, the following rules are
applied:
- On wide screens, a menu is shown in the top-bar and the sidenav is
  shown side-by-side with the docs content.
- On narrow screens, the top-menu is moved from the top-bar to the
  sidenav and the sidenav is closed by default and floats over the
  content when manually opened.

Previously, the break-points at which the top-menu was shown in the
top-bar and the sidenav was shown side-by-side with the content were the
same (using a single variable).

This commit decouples the two break-points to make it possible to use
different values in the future.

PR Close #37938
2020-07-06 13:57:37 -07:00
George Kalpakas
90b93da743 refactor(docs-infra): use Sass variable for top-bar hamburger button show/hide threshold (#37938)
Use a Sass variable for the screen width break-point at which the
top-bar hamburger button is hidden/shown. This allows more easily
updating the break-point.

PR Close #37938
2020-07-06 13:57:37 -07:00
Pete Bacon Darwin
ec32eba02c feat(localize): expose canParse() diagnostics (#37909)
When loading a translation file we ask each `TranslationParser`
whether it can parse the file. Occasionally, this check can find
errors in the file that would be useful to the developer. For example
if the file has invalid XML.

This commit deprecates the previous `canParse()` method and replaces it
with a new `analyze()` method. This returns an object that includes a
boolean `canParse` and then either a `hint` if it can parse the file,
or a `diagnostics` object filled with any messages that can be used to
diagnose problems with the format of the file.

Closes #37901

PR Close #37909
2020-07-06 13:56:39 -07:00
George Kalpakas
596fbb3f06 build(docs-infra): improve applying post-install patches (#37896)
In `aio/`, we have a mechanism to apply patches in a `postinstall` hook.
See `aio/tools/cli-patches/README.md` for more info.

Previously, we had to update `aio/tools/cli-patches/patch.js` to list
each `.patch` file separately. While working on #37688, I found it
helpful for the script to automatically pick up `.patch` files.

This commit updates the script to automatically pick up and apply
`.patch` files from the `aio/tools/cli-patches/` directory. If one wants
to keep a `.patch` file but not apply it, they can change the file's
extension or move it to a sub-directory (without having to update the
script).

PR Close #37896
2020-07-06 13:56:15 -07:00
Andrew Kushnir
aed6b131bb fix(core): handle spaces after select and plural ICU keywords (#37866)
Currently when the `plural` or `select` keywords in an ICU contain trailing spaces (e.g. `{count, select , ...}`), these spaces are also included into the key names in ICU vars (e.g. "VAR_SELECT "). These trailing spaces are not desirable, since they will later be converted into `_` symbols while normalizing placeholder names, thus causing mismatches at runtime (i.e. placeholder will not be replaced with the correct value). This commit updates the code to trim these spaces while generating an object with placeholders, to make sure the runtime logic can replace these placeholders with the right values.

PR Close #37866
2020-07-06 13:55:47 -07:00
Andrew Kushnir
d148fdccf2 fix(dev-infra): fix typo in ng-dev config (#37862)
The logic to exclude certain types of commits (specifically 'docs' ones) was implemented in c5b125b7db. The ng-dev config was updated in the followup commit acf3cff9ee, but there was a typo that prevented the new logic from being activated. This commit updates the name of the config option in the ng-dev config to the right one (minBodyLengthTypeExcludes).

PR Close #37862
2020-07-06 13:55:18 -07:00
Ruben Schuckit
1801d0c650 fix(router): properly compare array queryParams for equality (#37709) (#37860)
queryParams will be judged different if the arrays do not contain the same frequency of elements and the same otherwise.

PR Close #37860
2020-07-06 13:50:32 -07:00
Omar Hasan
a5c30733cb docs: mention for depreciation for Testbed.get() (#37815)
As mention in https://angular.io/guide/deprecations for this API, it may be important mention for this to make developers migrate or avoid using it

PR Close #37815
2020-07-06 13:42:27 -07:00
Dmitrij Kuba
d7dd2959c8 perf(router): apply prioritizedGuardValue operator to optimize CanLoad guards (#37523)
CanLoad guards are processed in asynchronous manner with the following rules:
* If all guards return `true`, operator returns `true`;
* `false` and `UrlTree` values wait for higher priority guards to resolve;
* Highest priority `false` or `UrlTree` value will be returned.

`prioritizedGuardValue` uses `combineLatest` which in order subscribes to each Observable immediately (not waiting when previous one completes that `concatAll` do). So it makes some advantages in order to run them concurrently. Respectively, a time to resolve all guards will be reduced.

PR Close #37523
2020-07-06 13:41:11 -07:00
Andrew Scott
a5ffca0576 fix(router): fix navigation ignoring logic to compare to the browser url (#37716)
This PR changes the logic for determining when to skip route processing from
using the URL of the last attempted navigation to the actual resulting URL after
that transition.

Because guards may prevent navigation and reset the browser URL, the raw
URL of the previous transition may not match the actual URL of the
browser at the end of the navigation process. For that reason, we need to use
`urlAfterRedirects` instead.

Other notes:
These checks in scheduleNavigation were added in eb2ceff4ba
The test still passes and, more surprisingly, passes if the checks are removed
completely. There have likely been changes to the navigation handling that
handle the test in a different way. That said, it still appears to be important
to keep the checks there in some capacity because it does affect how many
navigation events occur. This addresses an issue that came up in #16710: https://github.com/angular/angular/issues/16710#issuecomment-634869739
This also partially addresses #13586 in fixing history for imperative
navigations that are cancelled by guards.

PR Close #37716
2020-07-06 09:38:10 -07:00
Judy Bogart
196bfa8fae docs: restore link to lightweight token page in left nav (#37855)
After recent correction to left nav TOC, the link to this new page was temporarily removed. This restores it to next, because the page is not yet available in stable.

PR Close #37855
2020-07-01 11:55:36 -07:00
Celilsemi Sam Erkiner
1d5ca55aab docs(changelog): remove empty sections (#36264)
The changelog contains some empty sections (such as `### Bug Fixes`). This change removes these empty sections.

PR Close #36264
2020-07-01 09:22:56 -07:00
Celilsemi Sam Erkiner
e0033f1e10 docs(changelog): remove duplicate entries (#36264)
Remove duplicate entries in the changelog, keeping only the earliest instance of changes that appear multiple times.

PR Close #36264
2020-07-01 09:22:56 -07:00
Judy Bogart
9206a26e1d docs: clean up api doc in core (#37053)
Add introductions to usage examples and edit descriptions to be more complete and consistent with current API reference styles

PR Close #37053
2020-06-30 12:11:15 -07:00
Alan Agius
11dd2bef2d docs: add missing single quote (#37854)
The current code is missing a single quote at the end of the import.

(cherry picked from commit e13171ea2960dd0fa0666cb964b53799d2883e3a)

PR Close #37854
2020-06-30 12:10:13 -07:00
Andrew Kushnir
6fc80690ae docs: release notes for the v10.0.2 release 2020-06-30 11:57:17 -07:00
Sonu Kapoor
f6d2705942 docs: add Sonu Kapoor to the collaborator list (#37777)
After 6 months of continuous contributions, Sonu Kapoor did finally make
it into the collaborator list.

PR Close #37777
2020-06-30 10:47:54 -07:00
Alan Agius
79dc14199b docs: update /config/app-package-json redirect (#37774)
With this change we change the redirect for `/config/app-package-json` from `https://webpack.js.org/configuration/optimization/#optimizationsideeffects` to `https://angular.io/guide/strict-mode#non-local-side-effects-in-applications`

The latter page has more details.

PR Close #37774
2020-06-30 10:45:52 -07:00
Alex Rickabaugh
71956250dd perf(compiler-cli): fix memory leak in retained incremental state (#37835)
Incremental compilation allows for the output state of one compilation to be
reused as input to the next compilation. This involves retaining references
to instances from prior compilations, which must be done carefully to avoid
memory leaks.

This commit fixes such a leak with a complicated retention chain:

* `TrackedIncrementalBuildStrategy` unnecessarily hangs on to the previous
  `IncrementalDriver` (state of the previous compilation) once the current
  compilation completes.

  In general this is unnecessary, but should be safe as long as the chain
  only goes back one level - if the `IncrementalDriver` doesn't retain any
  previous `TrackedIncrementalBuildStrategy` instances. However, this does
  happen:

* `NgCompiler` indirectly causes retention of previous `NgCompiler`
  instances (and thus previous `TrackedIncrementalBuildStrategy` instances)
  through accidental capture of the `this` context in a closure created in
  its constructor. This closure is wrapped in a `ts.ModuleResolutionCache`
  used to create a `ModuleResolver` class, which is passed to the program's
  `TraitCompiler` on construction.

* The `IncrementalDriver` retains a reference to the `TraitCompiler` of the
  previous compilation, completing the reference chain.

The final retention chain thus looks like:

* `TrackedIncrementalBuildStrategy` of current program
* `.previous`: `IncrementalDriver` of previous program
* `.lastGood.traitCompiler`: `TraitCompiler`
* `.handlers[..].moduleResolver.moduleResolutionCache`: cache
* (via `getCanonicalFileName` closure): `NgCompiler`
* `.incrementalStrategy`: `TrackedIncrementalBuildStrategy` of previous
  program.

The closure link is the "real" leak here. `NgCompiler` is creating a closure
for `getCanonicalFileName`, delegating to its
`this.adapter.getCanonicalFileName`, for the purposes of creating a
`ts.ModuleResolutionCache`. The fact that the closure references
`NgCompiler` thus eventually causes previous `NgCompiler` iterations to be
retained. This is also potentially problematic due to the shared nature of
`ts.ModuleResolutionCache`, which is potentially retained across multiple
compilations intentionally.

This commit fixes the first two links in the retention chain: the build
strategy is patched to not retain a `previous` pointer, and the `NgCompiler`
is patched to not create a closure in the first place, but instead pass a
bound function. This ensures that the `NgCompiler` does not retain previous
instances of itself in the first place, even if the build strategy does
end up retaining the previous incremental state unnecessarily.

The third link (`IncrementalDriver` unnecessarily retaining the whole
`TraitCompiler`) is not addressed in this commit as it's a more
architectural problem that will require some refactoring. However, the leak
potential of this retention is eliminated thanks to fixing the first two
issues.

PR Close #37835
2020-06-29 16:34:51 -07:00
Pete Bacon Darwin
e84539f809 build(docs-infra): update to latest dgeni-packages (#37793)
This update of dgeni-packages to 0.28.4 fixes the
rendering of type initializers for classes and interfaces.

Closes #37694

PR Close #37793
2020-06-29 15:01:14 -07:00
Jaskaran Singh
873330b82c docs: correct the spelling mistake in observables error handling code (#36437)
This commit fixes a spelling error in the word error in the
observables.md guide. It is currently
spelled errror  and the mistake is not intentional.

PR Close #36437
2020-06-29 15:00:38 -07:00
Santosh Yadav
a177b1b7b1 docs: change definition of providedIn any (#35292)
change in the definition of providedIn:any any instance creates a singleton instance
for each lazy loaded module and one instance for eager loaded module

PR Close #35292
2020-06-29 15:00:00 -07:00
JiaLiPassion
435a28e937 fix(core): fake_async_fallback should have the same logic with fake-async (#37680)
PR https://github.com/angular/angular/pull/37523 failed when trying to use `rxjs delay` operator
inside `fakeAsync`, and the reasons are:

1. we need to import `rxjs-fake-async` patch to make the integration work.
2. since in `angular` repo, the bazel target `/tools/testing:node` not using `zone-testing` bundle,
instead it load `zone-spec` packages seperately, so it causes one issue which is the `zone.js/testing/fake-async`
package is not loaded, we do have a fallback logic under `packages/core/testing` calles `fake_async_fallback`,
but the logic is out of date with `fake-async` under `zone.js` package.

So this PR, I updated the content of `fake_async_fallback` to make it consistent with
`fake-async`. And I will make another PR to try to remove the `fallback` logic.

PR Close #37680
2020-06-29 12:22:52 -07:00
JiaLiPassion
c2b4d92708 feat(zone.js): patch jasmine.createSpyObj to make properties enumerable to be true (#34624)
Close #33657

in jasmine 3.5, there is a new feature, user can pass a properties object to `jasmine.createSpyObj`

```
const spy = jasmine.createSpyObj('spy', ['method1'], {prop1: 'foo'});
expect(spy.prop1).toEqual('foo');
```

This case will not work for Angular TestBed, for example,

```
describe('AppComponent', () => {
  beforeEach(() => {

    //Note the third parameter
    // @ts-ignore
    const someServiceSpy = jasmine.createSpyObj('SomeService', ['someFunction'], ['aProperty']);

    TestBed.configureTestingModule({
      declarations: [
        AppComponent
      ],
      providers: [
        {provide: SomeService, useValue: someServiceSpy},
      ]
    }).compileComponents();

  });

  it('should create the app', () => {
    //spyObj will have someFunction, but will not have aProperty
    let spyObj = TestBed.get(SomeService);
  });
```

Because `jasmine.createSpyObj` will create the `aProperty` with `enumerable=false`,
and `TestBed.configureTestingModule` will try to copy all the properties from spyObj to
the injected service instance. And because `enumerable` is false, so the property (here is aProperty)
will not be copied.

This PR will monkey patch the `jasmine.createSpyObj` and make sure the new property's
`enumerable=true`.

PR Close #34624
2020-06-29 12:22:08 -07:00
JoostK
a87951a28f fix(ngcc): prevent including JavaScript sources outside of the package (#37596)
When ngcc creates an entry-point program, the `allowJs` option is enabled
in order to operate on the JavaScript source files of the entry-point.
A side-effect of this approach is that external modules that don't ship
declaration files will also have their JavaScript source files loaded
into the program, as the `allowJs` flag allows for them to be imported.
This may pose an issue in certain edge cases, where ngcc would inadvertently
operate on these external modules. This can introduce all sorts of undesirable
behavior and incompatibilities, e.g. the reflection host that is selected for
the entry-point's format could be incompatible with that of the external
module's JavaScript bundles.

To avoid these kinds of issues, module resolution that would resolve to
a JavaScript file located outside of the package will instead be rejected,
as if the file would not exist. This would have been the behavior when
`allowJs` is set to false, which is the case in typical Angular compilations.

Fixes #37508

PR Close #37596
2020-06-29 12:21:22 -07:00
JoostK
6b565ba8f2 refactor(ngcc): let isWithinPackage operate on paths instead of source files (#37596)
Changes `isWithinPackage` to take an `AbsoluteFsPath` instead of `ts.SourceFile`,
to allow for an upcoming change to use it when no `ts.SourceFile` is available,
but just a path.

PR Close #37596
2020-06-29 12:21:22 -07:00
Judy Bogart
c29f830c4b docs: correct left nav toc to remove duplicated page links (#37827)
The major sections Angular Libraries, Schematics, and CLI Builders appear twice, in their old location under Techniques, and in the new correct location under Extending Angular

PR Close #37827
2020-06-29 12:19:28 -07:00
nobobo1234
cde4653c62 docs: Changing typo Stacblitz into Stackblitz in the Tour of Hereos tutorial docs page (#37794)
Changing the typo of Stacblitz into Stackblitz in the tour of hereos tutorial docs page since that is the actual name of the service

PR Close #37794
2020-06-29 12:17:40 -07:00
Maksymilian Sielicki
e07d940b9b docs: remove first person from 2 sentences (#37768)
This commit removes two instances of the first person in the
Dependency injection providers documentation.

PR Close #37768
2020-06-29 12:17:04 -07:00
Amadou Sall
ee1526029f docs: add Amadou Sall to GDE page (#36509)
This commit adds Amadou Sall to the Angular GDE page along with a
biography, his role at Air France, and a photograph.

PR Close #36509
2020-06-29 12:16:22 -07:00
George Kalpakas
eba9dd364e fix(elements): fire custom element output events during component initialization (#37570)
Previously, event listeners for component output events attached on an
Angular custom element before inserting it into the DOM (i.e. before
instantiating the underlying component) didn't fire for events emitted
during initialization lifecycle hooks, such as `ngAfterContentInit`,
`ngAfterViewInit`, `ngOnChanges` (initial call) and `ngOnInit`.
The reason was that `NgElementImpl` [subscribed to events][1] _after_
calling [ngElementStrategy#connect()][2], which is where the
[initial change detection][3] takes place (running the initialization
lifecycle hooks).

This commit fixes this by:
1. Ensuring `ComponentNgElementStrategy#events` is defined and available
   for subscribing to, even before instantiating the component.
2. Changing `NgElementImpl` to subscribe to `NgElementStrategy#events`
   (if available) before calling `NgElementStrategy#connect()` (which
   initializes the component instance) if available.
3. Falling back to the old behavior (subscribing to `events` after
   calling `connect()` for strategies that do not initialize `events`
   before their `connect()` is run).

NOTE:
By falling back to the old behavior when `NgElementStrategy#events` is
not initialized before calling `NgElementStrategy#connect()`, we avoid
breaking existing custom `NgElementStrategy` implementations (with
@remackgeek's [ElementZoneStrategy][4] being a commonly used example).

Jira issue: [FW-2010](https://angular-team.atlassian.net/browse/FW-2010)

[1]: c0143cb2ab/packages/elements/src/create-custom-element.ts (L167-L170)
[2]: c0143cb2ab/packages/elements/src/create-custom-element.ts (L164)
[3]: c0143cb2ab/packages/elements/src/component-factory-strategy.ts (L158)
[4]: f1b6699495/projects/elements-zone-strategy/src/lib/element-zone-strategy.ts

Fixes #36141

PR Close #37570
2020-06-29 10:33:40 -07:00
Pete Bacon Darwin
78a44768e0 fix(ngcc): ensure lockfile is removed when analyzeFn fails (#37739)
Previously an error thrown in the `analyzeFn` would cause
the ngcc process to exit immediately without removing the
lockfile, and potentially before the unlocker process had been
successfully spawned resulting in the lockfile being orphaned
and left behind.

Now we catch these errors and remove the lockfile as needed.

PR Close #37739
2020-06-29 10:29:11 -07:00
Andrew Kushnir
98c047b763 ci: decrease payload size limit for integration tests (#37784)
This commit updates the payload size limit for the `hello_world` test app built using Closure. This is likely an effect of the changes in https://github.com/angular/angular/pull/36578 (that reduces the bundle size for most of the apps) and additional changes in subsequent commits.

PR Close #37784
2020-06-26 16:43:03 -07:00
crisbeto
543b679762 fix(core): error when invoking callbacks registered via ViewRef.onDestroy (#37543)
Invoking a callback registered through `ViewRef.onDestroy` throws an error, because we weren't registering it correctly in the internal data structure. These changes also remove the `storeCleanupFn` function, because it was mostly identical to `storeCleanupWithContext` and was only used in one place.

Fixes #36213.

PR Close #37543
2020-06-26 15:02:41 -07:00
crisbeto
c00f4ab2ae fix(core): don't consider inherited NG_ELEMENT_ID during DI (#37574)
Special DI tokens like `ChangeDetectorRef` and `ElementRef` can provide a factory via `NG_ELEMENT_ID`. The problem is that we were reading it off the token as `token[NG_ELEMENT_ID]` which will go up the prototype chain if it couldn't be found on the current token, resulting in the private `ViewRef` API being exposed, because it extends `ChangeDetectorRef`.

These changes fix the issue by guarding the property access with `hasOwnProperty`.

Fixes #36235.

PR Close #37574
2020-06-26 15:01:20 -07:00
Harri Lehtola
2038568f3e ci: decrease expected AIO and integration payload sizes (#36578) (#36578)
The changes in #36687 removed enough code to exceed the CI check limits, so
the expected main-es2015 size needs adjusting.

PR Close #36578
2020-06-26 14:54:09 -07:00
Harri Lehtola
c509243af5 fix(core): determine required DOMParser feature availability (#36578) (#36578)
Verify that HTML parsing is supported in addition to DOMParser existence.
This maybe wasn't as important before when DOMParser was used just as a
fallback on Firefox, but now that DOMParser is the default choice, we need
to be more accurate.

PR Close #36578
2020-06-26 14:54:09 -07:00
Harri Lehtola
d4544da804 refactor(core): split inert strategies to separate classes (#36578) (#36578)
The `inertDocument` member is only needed when using the InertDocument
strategy. By separating the DOMParser and InertDocument strategies into
separate classes, we can easily avoid creating the inert document
unnecessarily when using DOMParser.

PR Close #36578
2020-06-26 14:54:09 -07:00
Harri Lehtola
b950d4675f fix(core): do not trigger CSP alert/report in Firefox and Chrome (#36578) (#36578)
If [innerHTML] is used in a component and a Content-Security-Policy is set
that does not allow inline styles then Firefox and Chrome show the following
message:

> Content Security Policy: The page’s settings observed the loading of a
resource at self (“default-src”). A CSP report is being sent.

This message is caused because Angular is creating an inline style tag to
test for a browser bug that we use to decide what sanitization strategy to
use, which causes CSP violation errors if inline CSS is prohibited.

This test is no longer necessary, since the `DOMParser` is now safe to use
and the `style` based check is redundant.

In this fix, we default to using `DOMParser` if it is available and fall back
to `createHTMLDocument()` if needed. This is the approach used by DOMPurify
too.

The related unit tests in `html_sanitizer_spec.ts`, "should not allow
JavaScript execution when creating inert document" and "should not allow
JavaScript hidden in badly formed HTML to get through sanitization (Firefox
bug)", are left untouched to assert that the behavior hasn't changed in
those scenarios.

Fixes #25214.

PR Close #36578
2020-06-26 14:54:08 -07:00
Keen Yee Liau
ae5257cda6 fix(language-service): incorrect autocomplete results on unknown symbol (#37518)
This commit fixes a bug whereby the language service would incorrectly
return HTML elements if autocomplete is requested for an unknown symbol.
This is because we walk through every possible scenario, and fallback to
element autocomplete if none of the scenarios match.

The fix here is to return results from interpolation if we know for sure
we are in a bound text. This means we will now return an empty results if
there is no suggestions.

This commit also refactors the code a little to make it easier to
understand.

PR Close #37518
2020-06-26 14:51:32 -07:00
Andrew Kushnir
8fd8143ab8 docs: release notes for the v10.0.1 release 2020-06-26 13:35:40 -07:00
Igor Minar
acf3cff9ee ci: exclude "docs" commit type from minBodyLength commit message validation (#37764)
docs commits are sometimes trivial (e.g. an obvious typo fix) and in such cases its very
akward to to write up 100 chars worth of text about why this typo fix is the best thing in the
world and why it is so important and crucial that we must know why we are fixing the typo
at all. After all most typos are not just typos. Or are they? We'll shall see...

PR Close #37764
2020-06-26 11:13:09 -07:00
Igor Minar
c5b125b7db feat(dev-infra): add support for minBodyLengthTypeExcludes to commit-message validation (#37764)
This feature will allow us to exclude certain commits from the 100 chars minBodyLength requirement for commit
messages which is hard to satisfy for commits that make trivial changes (e.g. fixing typos in docs or comments).

PR Close #37764
2020-06-26 11:13:09 -07:00
Santosh Yadav
fc5c34d1b8 feat(platform-browser): Allow sms-URLs (#31463)
sms ulr is already supported by google/closure-library and and validations are added to check
if the body passed is safe or not you can refer bb7ea65319/closure/goog/html/safeurl.js (L440-L454) for more details

Fixes #31462

PR Close #31463
2020-06-26 11:12:32 -07:00
Andrew Kushnir
0879d2e85d refactor(core): throw more descriptive error message in case of invalid host element (#35916)
This commit replaces an assert with more descriptive error message that is thrown in case `<ng-template>` or `<ng-container>` is used as host element for a Component.

Resolves #35240.

PR Close #35916
2020-06-26 11:10:14 -07:00
Joey Perrott
83fe963a4b build: move shims_for_IE to third_party directory (#37624)
The shims_for_IE.js file contains vendor code that predates the third_party
directory. This file is currently used for internal karma testing setup. This
change corrects this by moving the shims_for_IE file to //third_part/

PR Close #37624
2020-06-26 11:09:01 -07:00
Keen Yee Liau
e0eeb4afcb refactor(compiler-cli): Remove any cast for CompilerHost (#37079)
This commit removes the FIXME for casting CompilerHost to any since
google3 is now already on TS 3.8.

PR Close #37079
2020-06-26 11:08:17 -07:00
Keen Yee Liau
c942662d79 fix(language-service): reinstate getExternalFiles() (#37750)
`getExternalFiles()` is an API that could optionally be provided by a tsserver plugin
to notify the server of any additional files that should belong to a particular project.

This API was removed in https://github.com/angular/angular/pull/34260 mainly
due to performance reasons.

However, with the introduction of "solution-style" tsconfig in typescript 3.9,
the Angular extension could no longer reliably detect the owning Project solely
based on the ancestor tsconfig.json. In order to support this use case, we have
to reinstate `getExternalFiles()`.

Fixes https://github.com/angular/vscode-ng-language-service/issues/824

PR Close #37750
2020-06-26 09:57:08 -07:00
Ajit Singh
6341a837c1 docs: correct outdated dev instructions for public api golds (#37026)
This change updates the dev instructions to reflect the location and generation of public API golds, which changed in #35768.

PR Close #37026
2020-06-26 09:56:32 -07:00
Nick Hodges
f954ab6f10 docs: add note about the month being zero-based in the Date constructor (#37770)
Because the month is zero based, it may confuse some users that '3'
is in fact 'April'. This comment should clear that up.

PR Close #37770
2020-06-26 09:55:18 -07:00
Paul Gschwendtner
3ee666580a fix(dev-infra): merge script should not always require full repo permissions (#37718)
We recently added OAuth scope checking to the dev-infra Git client
and started leveraging it for the merge script. We set the `repo` scope
as required for running the merge script. We can loosen this requirement
as in the Angular org where the script is consumed, only pull requests on
public repositories are merged through the script.

This should help with reducing the risk with compromised tokens as no
access had to be granted on `repo:invite`, `repo_deployment` etc.

PR Close #37718
2020-06-26 09:52:33 -07:00
Paul Gschwendtner
dbc2364d16 fix(dev-infra): support running scripts from within a detached head (#37737)
Scripts provided in the `ng-dev` command might use local `git`
commands. For such scripts, we keep track of the branch that
has been checked out before the command has been invoked.

We do this so that we can later (upon command completion)
restore back to the original branch. We do not want to
leave the Git repository in a dirty state.

It looks like this logic currently only deals with branches
but does not work properly when a command is invoked from
a detached head. We can make it work by just checking out
the previous revision (if no branch is checked out).

PR Close #37737
2020-06-26 09:51:09 -07:00
George Kalpakas
eee2fd22e0 ci(docs-infra): store JS bundles as CI artifacts to debug size check flakes (#37703)
As reported in #37699, the size of the main angular.io bundle sometimes
ends up bigger than expected on CI. This usually goes away after
rerunning the job a couple of times.

It is unclear what is causing this. In order to help debug the issue,
this commit stores the JS files that are checked as part of the aio
payload-size check as CI artifacts, where they can be retrieved from and
inspected.

PR Close #37703
2020-06-25 17:29:35 -07:00
Joey Perrott
638dd15f61 build: add wombot proxy for publish config for @angular/benchpress (#37752)
Adds the publishConfig registry value to the package.json of the
@angular/benchpress package to publish it via wombat rather than
through npm directly.

PR Close #37752
2020-06-25 17:08:18 -07:00
Gui Seek
9c668e091f docs(elements): fixed command that adds the package @angular/elements (#37681)
I was using schematics with the `--name` parameter instead of the `--project`, I did both ways before sending and my suspicion about outdated documentation was confirmed

PR Close #37681
2020-06-25 17:07:29 -07:00
Edric Chan
b2816a1536 docs: typo fixes for schematics-for-libraries.md (#37753)
Addresses small typos such as extra whitespaces.

This change was extracted from #29505.
This change was extracted from #29505.
This change was extracted from #29505.

PR Close #37753
2020-06-25 17:06:37 -07:00
Alex Rickabaugh
2cbc429291 test(compiler-cli): disable DynamicValue diagnostic tests on Windows (#37763)
This commit disables all diagnostic tests for DynamicValue diagnostics which
make assertions about the diagnostic filename while running tests on Windows.

Such assertions are currently suffering from a case sensitivity issue.

PR Close #37763
2020-06-25 17:04:57 -07:00
Igor Minar
4c7f32f28c fix(docs-infra): fix deploy-to-firebase.sh for master and v10.0.x branches (#37762)
The deployment to aio is currently failing because #37721 introduced
"project" entry into the firebase.json which means that we now need to
select the deployment target before deploying to firebase.

This change fixes the issue and refactors the file to be easier to read.

I also added extra echo statements so that the CI logs are easier to
read in case we need to troubleshoot future issues.

PR Close #37762
2020-06-25 17:03:24 -07:00
Alex Rickabaugh
8572e885b4 test(compiler-cli): fix assertion of diagnostic filename on Windows (#37758)
Several partial_evaluator tests in the diagnostics_spec check assert
correctness of diagnostic filenames. Previously these assertions compared
a resolved (`absoluteFrom`) filename with the TypeScript `ts.SourceFile`'s
`fileName` string, which caused the tests to fail on Windows because the
drive letter case differed.

This commit changes the assertions to use `absoluteFromSourceFile` instead
of the `fileName` string, resulting in an apples-to-apples comparison of
canonicalized paths.

PR Close #37758
2020-06-25 15:40:43 -07:00
Igor Minar
0e3e9cd382 fix(docs-infra): fix typo in the deploy-to-firebase.sh script (#37754)
This typo caused the script to fail on Linux (interestingly it works fine on Mac).

This is a painful reminder that we should not write any more Bash scripts EVER. shelljs FTW! :-)

PR Close #37754
2020-06-25 15:21:24 -07:00
Andrew Kushnir
9118f49a63 fix(core): cleanup DOM elements when root view is removed (#37600)
Currently when bootstrapped component is being removed using `ComponentRef.destroy` or `NgModuleRef.destroy` methods, DOM nodes may be retained in the DOM tree. This commit fixes that problem by always attaching host element of the internal root view to the component's host view node, so the cleanup can happen correctly.

Resolves #36449.

PR Close #37600
2020-06-25 14:34:35 -07:00
Adam
d37049a2a2 feat(platform-server): add option for absolute URL HTTP support (#37539)
In version 10.0.0-next.8, we introduced absolute URL support for
server-based HTTP requests, so long as the fully-resolved URL was
provided in the initial config. However, doing so represents a
breaking change for users who already have their own interceptors
to model this functionality, since our logic executes before all
interceptors fire on a request. See original PR #37071.

Therefore, we introduce a flag to make this change consistent with
v9 behavior, allowing users to opt in to this new behavior. This
commit also fixes two issues with the previous implementation:
1. if the server was initiated with a relative URL, the absolute
URL construction would fail because needed components were empty
2. if the user's absolute URL was on a port, the port would not
be included

PR Close #37539
2020-06-25 14:26:09 -07:00
Paul Gschwendtner
d12cdb5019 fix(migrations): do not incorrectly add todo for @Injectable or @Pipe (#37732)
As of v10, the `undecorated-classes-with-decorated-fields` migration
generally deals with undecorated classes using Angular features. We
intended to run this migation as part of v10 again as undecorated
classes with Angular features are no longer supported in planned v11.

The migration currently behaves incorrectly in some cases where an
`@Injectable` or `@Pipe` decorated classes uses the `ngOnDestroy`
lifecycle hook. We incorrectly add a TODO for those classes. This
commit fixes that.

Additionally, this change makes the migration more robust to
not migrate a class if it inherits from a component, pipe
injectable or non-abstract directive. We previously did not
need this as the undecorated-classes-with-di migration ran
before, but this is no longer the case.

Last, this commit fixes an issue where multiple TODO's could be
added. This happens when multiple Angular CLI build targets have
an overlap in source files. Multiple programs then capture the
same source file, causing the migration to detect an undecorated
class multiple times (i.e. adding a TODO twice).

Fixes #37726.

PR Close #37732
2020-06-25 14:22:08 -07:00
JoostK
ce879fc416 refactor(compiler-cli): more accurate reporting of complex function call (#37587)
This commit introduces a dedicated `DynamicValue` kind to indicate that a value
cannot be evaluated statically as the function body is not just a single return
statement. This allows more accurate reporting of why a function call failed
to be evaluated, i.e. we now include a reference to the function declaration
and have a tailor-made diagnostic message.

PR Close #37587
2020-06-25 14:16:35 -07:00
JoostK
712f1bd0b7 feat(compiler-cli): explain why an expression cannot be used in AOT compilations (#37587)
During AOT compilation, the value of some expressions need to be known at
compile time. The compiler has the ability to statically evaluate expressions
the best it can, but there can be occurrences when an expression cannot be
evaluated statically. For instance, the evaluation could depend on a dynamic
value or syntax is used that the compiler does not understand. Alternatively,
it is possible that an expression could be statically evaluated but the
resulting value would be of an incorrect type.

In these situations, it would be helpful if the compiler could explain why it
is unable to evaluate an expression. To this extend, the static interpreter
in Ivy keeps track of a trail of `DynamicValue`s which follow the path of nodes
that were considered all the way to the node that causes an expression to be
considered dynamic. Up until this commit, this rich trail of information was
not surfaced to a developer so the compiler was of little help to explain
why static evaluation failed, resulting in situations that are hard to debug
and resolve.

This commit adds much more insight to the diagnostic that is produced for static
evaluation errors. For dynamic values, the trail of `DynamicValue` instances
is presented to the user in a meaningful way. If a value is available but not
of the correct type, the type of the resolved value is shown.

Resolves FW-2155

PR Close #37587
2020-06-25 14:16:35 -07:00
JoostK
d2fb552116 refactor(compiler-cli): create diagnostics using ts.DiagnosticRelatedInformation (#37587)
Previously, an anonymous type was used for creating a diagnostic with related
information. The anonymous type would then be translated into the necessary
`ts.DiagnosticRelatedInformation` shape within `makeDiagnostic`. This commit
switches the `makeDiagnostic` signature over to taking `ts.DiagnosticRelatedInformation`
directly and introduces `makeRelatedInformation` to easily create such objects.
This is done to aid in making upcoming work more readable.

PR Close #37587
2020-06-25 14:16:35 -07:00
Alex Rickabaugh
5103d908c8 perf(compiler-cli): fix regressions in incremental program reuse (#37641)
Commit 4213e8d5 introduced shim reference tagging into the compiler, and
changed how the `TypeCheckProgramHost` worked under the hood during the
creation of a template type-checking program. This work enabled a more
incremental flow for template type-checking, but unintentionally introduced
several regressions in performance, caused by poor incrementality during
`ts.Program` creation.

1. The `TypeCheckProgramHost` was made to rely on the `ts.CompilerHost` to
   retrieve instances of `ts.SourceFile`s from the original program. If the
   host does not return the original instance of such files, but instead
   creates new instances, this has two negative effects: it incurs
   additional parsing time, and it interferes with TypeScript's ability to
   reuse information about such files.

2. During the incremental creation of a `ts.Program`, TypeScript compares
   the `referencedFiles` of `ts.SourceFile` instances from the old program
   with those in the new program. If these arrays differ, TypeScript cannot
   fully reuse the old program. The implementation of reference tagging
   introduced in 4213e8d5 restores the original `referencedFiles` array
   after a `ts.Program` is created, which means that future incremental
   operations involving that program will always fail this comparison,
   effectively limiting the incrementality TypeScript can achieve.

Problem 1 exacerbates problem 2: if a new `ts.SourceFile` is created by the
host after shim generation has been disabled, it will have an untagged
`referencedFiles` array even if the original file's `referencedFiles` was
not restored, triggering problem 2 when creating the template type-checking
program.

To fix these issues, `referencedFiles` arrays are now restored on the old
`ts.Program` prior to the creation of a new incremental program. This allows
TypeScript to get the most out of reusing the old program's data.

Additionally, the `TypeCheckProgramHost` now uses the original `ts.Program`
to retrieve original instances of `ts.SourceFile`s where possible,
preventing issues when a host would otherwise return fresh instances.

Together, these fixes ensure that program reuse is as incremental as
possible, and tests have been added to verify this for certain scenarios.

An optimization was further added to prevent the creation of a type-checking
`ts.Program` in the first place if no type-checking is necessary.

PR Close #37641
2020-06-25 14:12:20 -07:00
Pete Bacon Darwin
9318e23e64 perf(ngcc): use EntryPointManifest to speed up noop ProgramBaseEntryPointFinder (#37665)
Previously the `ProgramBasedEntryPointFinder` was parsing all the
entry-points referenced by the program for dependencies even if all the
entry-points had been processed already.

Now this entry-point finder will re-use the `EntryPointManifest` to load
the entry-point dependencies when possible which avoids having to parse
them all again, on every invocation of ngcc.

Previously the `EntryPointManifest` was only used in the
`DirectoryWalkerEntryPointFinder`, which also contained the logic for
computing the contents of the manifest. This logic has been factored out
into an `EntryPointCollector` class. Both the `ProgramBasedEntryPointFinder`
and `DirectoryWalkerEntryPointFinder` now use the `EntryPointManifest` and
the `EntryPointCollector`.

The result of this change is that there is a small cost on the first run of
ngcc to compute and store the manifest - the processing takes 102% of the
processing time before this PR. But on subsequent runs there is a
significant benefit on subsequent runs - the processing takes around 50%
of the processing time before this PR.

PR Close #37665
2020-06-25 14:11:03 -07:00
Pete Bacon Darwin
290bc7334d test(localize): add compile time extraction to integration test (#32912)
The integration test for i18n now makes use of the new extraction tooling
from the `@angular/localize` package rather than the old ViewEngine extractor.

PR Close #32912
2020-06-25 14:10:03 -07:00
Pete Bacon Darwin
190561d8a6 feat(localize): implement message extraction tool (#32912)
This tool, which can be run from the node_modules bin folder, can parse
the source files in your compiled app and generate a translation file
formatted with the configured syntax.

For example:

```
./node_modules/.bin/localize-extract -s 'dist/**/*.js' -f xliff1 -o dist/messages.en.xlf
```

PR Close #32912
2020-06-25 14:10:03 -07:00
Pete Bacon Darwin
ddb0a4e2e5 refactor(localize): handle location endings correctly (#32912)
Previously source locations required an ending position but this was not
being computed effectively. Now ending position is optional and it is
computed from an `endPath` passed to `getLocation()`.

PR Close #32912
2020-06-25 14:10:03 -07:00
Pete Bacon Darwin
07a07e34bc fix(compiler-cli): only read source-map comment from last line (#32912)
Source-maps can be linked to from a source-file by a comment at
the end of the file.

Previously the `SourceFileLoader` would read
the first comment that matched `//# sourceMappingURL=` but
this is not valid since some bundlers may include embedded
source-files that contain such a comment.

Now we only look for this comment in the last non-empty line
in the file.

PR Close #32912
2020-06-25 14:10:03 -07:00
Pete Bacon Darwin
dda3f49952 refactor(compiler): add source-map spans to localized strings (#32912)
Previously localized strings were not mapped to their original
source location, so it was not possible to back-trace them
in tools like the i18n message extractor.

PR Close #32912
2020-06-25 14:10:03 -07:00
Pete Bacon Darwin
decd95e7f0 fix(compiler-cli): ensure source-maps can handle webpack:// protocol (#32912)
Webpack and other build tools sometimes inline the contents of the
source files in their generated source-maps, and at the same time
change the paths to be prefixed with a protocol, such as `webpack://`.

This can confuse tools that need to read these paths, so now it is
possible to provide a mapping to where these files originated.

PR Close #32912
2020-06-25 14:10:03 -07:00
Pete Bacon Darwin
6abb8d0d91 feat(compiler-cli): add SourceFile.getOriginalLocation() to sourcemaps package (#32912)
This method will allow us to find the original location given a
generated location, which is useful in fine grained work with
source-mapping. E.g. in `$localize` tooling.

PR Close #32912
2020-06-25 14:10:03 -07:00
Sonu Kapoor
2b2146bc58 docs: Uses correct component in the MessageService (#37666)
This commit uses the correct component (`HeroesComponent`) in the.
`MessageService`. Previously, the `MessageService` was using
`HeroeService`.

Closes #37654

PR Close #37666
2020-06-25 13:48:59 -07:00
Igor Minar
3a698e2d08 feat(docs-infra): update deploy-to-firebase.sh script to support v9 multisite setup (#37721)
v9.angular.io was used to pilot the firebase hosting multisites setup for angular.io.

The deployments so far have been done manually to control the deployment process.

This change, automates the deployment for v9.angular.io so that future deployments can be made from
the CI.

See https://angular-team.atlassian.net/browse/DEV-125 for more info.

In the process of updating the scripts I rediscovered a bug in the deploy-to-firebase.sh script that
incorrect compared two numbers as strings. This previously worked correctly because we were comparing
single digit numbers. With the release of v10, we now compare 9 > 10 which behaves differently for
strings and numbers. The bug was fixed by switching to an arithmetic comparison of the two variables.

This bug has been fixed on the master branch but not on the 9.1.x branch. I realized this during the
rebase, but found my version to be a bit cleaner, so I kept it.

PR Close #37721
2020-06-25 13:44:52 -07:00
Dmitrij Kuba
8a74508130 fix(http): avoid abort a request when fetch operation is completed (#37367)
`abort` method is calling, even if fetch operation is completed

Fixes https://github.com/angular/angular/issues/36537

PR Close #37367
2020-06-25 12:09:39 -07:00
Ajit Singh
ef1fb6dee4 fix(common): date pipe gives wrong week number (#37632)
Date pipe is giving wrong week number when used with the date format 'w'. If first week(according to Iso)  has some days in previous year

Fixes #33961

PR Close #37632
2020-06-25 12:08:46 -07:00
Sonu Kapoor
e36d5b201a fix(forms): correct usage of selectedOptions (#37620)
Previously, `registerOnChange` used `hasOwnProperty` to identify if the
property is supported. However, this does not work as the `selectedOptions`
property is an inherited property. This commit fixes this by verifying
the property on the prototype instead.

Closes #37433

PR Close #37620
2020-06-25 12:08:00 -07:00
Oussama Ben Brahim
77b62a52c0 fix(forms): handle form groups/arrays own pending async validation (#22575)
introduce a boolean to track form groups/arrays own pending async validation to distinguish between pending state due to children and pending state due to own validation

Fixes #10064

PR Close #22575
2020-06-25 12:07:25 -07:00
Krzysztof Grzybek
616543ded0 fix(router): add null support for RouterLink directive (#32616)
Value of "undefined" passed as segment in routerLink is stringified to string "undefined".
This change introduces the same behavior for value of "null".

PR Close #32616
2020-06-25 11:58:00 -07:00
Anas Barghoud
2170ea270a fix(router): fix error when calling ParamMap.get function (#31599)
fix this.params.hasOwnProperty is not a function in case of creating an object using Object.create()

PR Close #31599
2020-06-25 11:57:24 -07:00
Manduro
80d0067048 fix(router): RouterLinkActive should run CD when setting isActive (#21411)
When using the routerLinkActive directive inside a component that is using ChangeDetectionStrategy.OnPush and lazy loaded module routes the routerLinkActive directive does not update after clicking a link to a lazy loaded route that has not already been loaded.

Also the OnPush nav component does not set routerLinkActive correctly when the default route loads, the non-OnPush nav component works fine.

regression caused by #15943
closes #19934

PR Close #21411
2020-06-25 11:56:26 -07:00
Wagner Maciel
5218916a7e feat(dev-infra): add a way to pass assets down to a benchmark application (#37695)
* add a param called ng_assets to the component_benchmark macro to allow static assets to be provided to the base angular app, not just through the ts_devserver

PR Close #37695
2020-06-25 11:51:51 -07:00
Keen Yee Liau
1c1eb3045c docs: Add support schedule for v10 (#37745)
This commit adds the support schedule for v10.
v10.0.0 was released on June 24, 2020.
Active support ends six months later, on Dec 24, 2020.
Long term support ends a year after that, on Dec 24, 2021.

PR Close #37745
2020-06-25 11:49:17 -07:00
Alex Rickabaugh
4967997536 ci(compiler-cli): exempt compiler-cli .bazel files from dev-infra approval (#37558)
Previously, dev-infra approval (via PullApprove) was required for all
.bazel files in the monorepo, including those in packages/compiler-cli.

The compiler-cli package is a little special in this sense:
 * it's not shipped to NPM in the APF
 * it uses lots of internal subpackages to organize and test its code

As a result:
 * changes to compiler-cli BUILD.bazel files are not user visible and
   don't have larger implications for the packages published to NPM,
   unlike changes to other BUILD.bazel files in the repo
 * the requirement for dev-infra approval for BUILD.bazel changes is
   overly burdensome, because compiler-cli build files change more
   rapidly than those of other packages.

This commit exempts the compiler-cli's build files from the requirement
for dev-infra approval. It will be sufficient for such files to be
approved by the normal compiler reviewers.

PR Close #37558
2020-06-25 11:47:50 -07:00
Trung Vo
666e6d15fa docs: Replace $emdash; with an actual em dash (#37723)
fix documentation in the lifecycle hooks guide where $emdash; was not being replaced by an actual em dash (-)

PR Close #37723
2020-06-25 11:41:54 -07:00
Paul Gschwendtner
f3ec37ebbf release(benchpress): bump version to v0.2.1 and update @angular/core peer dependency (#37676)
Updates the version of `@angular/benchpress` to the next patch
version. i.e. `v0.2.1`. Additionally, the peer dependency
on `@angular/core` has been updated to be satisifed with
Angular v10 and v11.

Benchpress should be at least compatibe with the next two major
versions as it does not rely on any deprecated API from `@angular/core`.

PR Close #37676
2020-06-25 11:39:08 -07:00
Paul Gschwendtner
cc3b1ebd96 refactor: cleanup unused dependencies in benchpress package (#37676)
Removes unused packages from the benchpress `package.json`. That
helps with deduping dependencies, and avoiding unused code
being downloaded.

PR Close #37676
2020-06-25 11:39:08 -07:00
Joey Perrott
29490cce30 build: set up caretaker note label in merge tooling (#37675)
Leverage the caretaker note label configuration in ng-dev's merge
tooling to prompt the caretaker for confirmation  when a PR has
the `PR action: merge-assistance` label. This should help to
surface for the caretaker, PRs which may need additional steps
taken, announcement messaging, etc.

PR Close #37675
2020-06-25 11:38:21 -07:00
Pete Bacon Darwin
bedc0451a0 docs(ngcc): add additional next steps to an error (#37672)
The file-writing error in the this commit can also be the result
of the ngcc process dying in the middle of writing files.

This commit improves the error message to offer a resolution
in case this is the reason for the error.

Fixes #36393

PR Close #37672
2020-06-25 11:37:43 -07:00
Ajit Singh
a0595f4b4f fix(forms): change error message (#37643)
Error message mention that ngModel and ngModelChange will be removed in Angular v7 but right not now sure when it will be removed so changed it to a future version

PR Close #37643
2020-06-25 11:36:59 -07:00
Ajit Singh
8924ec1474 test(docs-infra): add end to end tests for api reference (#37612)
Api search functionality only had unit tests @gkalpak suggested we should have some e2e tests too. Added some end to end tests.

Fixes #35170

PR Close #37612
2020-06-25 11:36:02 -07:00
Igor Minar
4481bebb38 docs: add v9.angular.io to the angular.io version picker (#37719)
Now that v10 is out, it's time to add the v9.angular.io link to the version picker, so here we go...

PR Close #37719
2020-06-24 19:53:24 -07:00
kuncevic
f5bbfd7b8c docs(changelog): fix v10 announcement url (#37722)
PR Close #37722
2020-06-24 19:50:44 -07:00
Misko Hevery
41ce5240f2 docs: release notes for the v10.0.0 release 2020-06-24 16:05:23 -07:00
Igor Minar
243824ef74 docs: updating guides and docs related to the v10 release (#37705)
Mostly just adding links to the migrations that were missing, adding the migrations into the navbar,
as well as correcting the @angular/bazel removal in the update guide.

I also added a commented out preamble for the release notes.

PR Close #37705
2020-06-24 09:37:34 -07:00
Judy Bogart
c95802f26f docs: add lightweight token page to library section of docs (#36144)
adds new DI technique recommendation for libraries to ensure tree-shaking for unused services
includes reasons for packaging schematics with libraries, clarify schematic usage recommendation

PR Close #36144
2020-06-23 16:34:51 -07:00
Charles Lyding
71c0363bb5 docs: add tslib update migration docs (#37402)
This adds documentation for the v10.0 tooling migration `update-libraries-tslib` contained within the `@schematics/angular` package.

PR Close #37402
2020-06-23 13:07:39 -07:00
Charles Lyding
e03adaf9b0 docs: add module/target compiler option migration docs (#37429)
This adds documentation for the v10.0 tooling migration `update-module-and-target-compiler-options` contained within the `@schematics/angular` package.

PR Close #37429
2020-06-23 12:46:22 -07:00
George Kalpakas
38dfbc775f ci(docs-infra): disable flaky tests (#37673)
I could not figure out the root cause of the flakes, so disabling the
flaky tests for now. See
https://github.com/angular/angular/pull/37637#issuecomment-647608149 for
more info.

Fixes #37629

PR Close #37673
2020-06-23 12:45:11 -07:00
David Shevitz 🔵
5229809adb docs: Initial commit of update guide for v10 release. (#37152)
This update includes modifications to the navigation.json file to
remove unneeded migration guides.

TODO: Redirects from v9 topics to v10; links to removed migration
guides need to point to v9.angular.io.

PR Close #37152
2020-06-23 11:56:49 -07:00
Charles Lyding
9d88ca07f8 docs: add solution-style tsconfig migration docs (#37512)
This adds documentation for the v10.0 tooling migration `solution-style-tsconfig` contained within the `@schematics/angular` package.

PR Close #37512
2020-06-23 11:55:01 -07:00
David Shevitz 🔵
97383488e8 docs: add strict-mode.md file to pullapprove (#37679)
When I created the strict-mode.md file, I didn't add it to the
pullapprove list. Now it's there.

The issue was introduced in #37486.

PR Close #37679
2020-06-23 10:05:50 -07:00
David Shevitz 🔵
cb566add3c docs: Add content for new strict mode for Angular CLI (#37486)
In v10, the Angular CLI supports a strict mode, which turns
on additional flags for the TypeScript and Angular compilers.

PR Close #37486
2020-06-22 16:29:15 -07:00
Pete Bacon Darwin
5c40fd65fa refactor(compiler-cli): tidy up file_system BUILD.bazel file_system (#37114)
* Re-order the `load` and `package` statements
* Make `srcs` glob more generic
* Remove unnecessary dependencies

PR Close #37114
2020-06-22 13:38:47 -07:00
Pete Bacon Darwin
2b53b07c70 refactor(ngcc): move sourcemaps into ngtsc (#37114)
The `SourceFile` and associated code is general and reusable in
other projects (such as `@angular/localize`). Moving it to `ngtsc`
makes it more easily shared.

PR Close #37114
2020-06-22 13:38:47 -07:00
Pete Bacon Darwin
6de5a12a9d refactor(ngcc): move logging code into ngtsc (#37114)
The `Logger` interface and its related classes are general purpose
and could be used by other tooling. Moving it into ngtsc is a more
suitable place from which to share it - similar to the FileSystem stuff.

PR Close #37114
2020-06-22 13:38:47 -07:00
Paul Gschwendtner
3a418ab63b docs: fix invalid anchor for CLI flags in deprecation guide (#37662)
75218342967591627ee44b73999a4cfd52fb5470 added content for CLI
deprecations to the `angular.io` deprecations guide. It looks
like the anchor for the CLI deprecations is incorrect and
ends up showing up as code in the guide.

This commit fixes the anchor so that it doesn't show
up as code in the guide.

PR Close #37662
2020-06-22 10:57:16 -07:00
Joey Perrott
c8c0063499 ci: disable saucelabs tests on Firefox ESR while investigating failures (#37647)
Firefox ESR tests fail running the acceptance tests on saucelabs.  These tests are being
disabled while investigating the failure as it is not entirely clear whether this is
saucelabs failure or a something like a memory pressure error in the test itself.

PR Close #37647
2020-06-22 10:56:28 -07:00
Joey Perrott
34259e90cb build: determine pullapprove fallback with better active group counting (#37636)
Previously, the fallback group simply determined its active state based on the
of active groups during processing.  Instead, we should consider if there are
any active groups after excluding the ones we don't want to be considered, i.e.
the minimum required review group and the global approval groups.  This allows
for an explicit test of the active groups that exist rather than a prone to get
out of date number of expected active groups.

With this change, we additionally need to check to ensure that global approvals
have not caused other groups to no longer be active, causing a false case of
no active groups, when they have simply been superceded by a global approval.

PR Close #37636
2020-06-22 10:56:00 -07:00
Joey Perrott
d0c69d207c build: update required-minimum-review group to be global approvable (#37636)
Previously, the required-minimum-review group was still considered active when
a global approval was provided.  This would result in global approvers needing
to Reviewd-For both the global approval and minimum review groups.  Instead
when a global approver provides their approval, the minimum review group should
be considered satisified.

PR Close #37636
2020-06-22 10:56:00 -07:00
Joey Perrott
1f0818002c build: correct listed username for @Splaktar in pullapprove config (#37636)
Previously, Michael Prentice's username was erroneously listed at @michaelprentice
however his Github username is actually @Splaktar.  This issue is corrected by this
change to properly allow him to provide reviews.

PR Close #37636
2020-06-22 10:56:00 -07:00
Paul Gschwendtner
fd65958b88 test: update symbol goldens to reflect optimized application (#37623)
Interestingly enough, our rollup bundle optimization pipeline
did not work properly before 1b827b058e5060963590628d4735e6ac83c6dfdd.

Unused declarations were not elided because build optimizer did not
consider the Angular packages as side-effect free. Build optimizer has
a hard-coded list of Angular packages that are considered side-effect
free. Though this one did not match in the old version of the rollup
bundle rule, as internal sources were resolved through their resolved
bazel-out paths. Hence build optimizer could not detect the known
Angular framework packages. Now though, since we leverage the
Bazel-idiomatic `@bazel/rollup` implementation, sources are resolved
through linked `node_modules`, and build optimizer is able to properly
detect files as side-effect free.

PR Close #37623
2020-06-22 10:55:29 -07:00
Paul Gschwendtner
12f674f404 ci: update components-repo-unit-tests job commit (#37623)
Updates to the latest commit of the `angular/components` repository. We
need to do this because we removed the `esm5.bzl` output flavour aspect,
but an old version of the components repo relied on this file to exist.

This is no longer the case, and we can simply update the version of the
components repo we can test against.

PR Close #37623
2020-06-22 10:55:29 -07:00
Paul Gschwendtner
413a0fb1ae fix(language-service): non-existent module format in package output (#37623)
The language-service package currently sets the `module` `package.json`
property and refers to a folder called `fesm5`. The language-service
though does not build with `ng_package` so this folder never existed.
Now with APF v10, ng package would not generate this folder either.

We should just remove the property as the primary entry-point is
the UMD bundle resolved through `main`. There is no module flavour
exposed to the NPM package as `pkg_npm` uses the named AMD module
devmode output that doesn't work for `module`.

PR Close #37623
2020-06-22 10:55:29 -07:00
Paul Gschwendtner
85abfd2171 test: remove unused stale ng_package test golden file (#37623)
It looks like there is a leftover golden in the `ng_package`
tests that is no longer used anywhere and does not reflect
the latest Angular Package Format v10 changes. We should be
able to remove it to keep our codebase healthy.

PR Close #37623
2020-06-22 10:55:29 -07:00
Paul Gschwendtner
1601ee6f6a refactor(dev-infra): ng_rollup_bundle rule should leverage @bazel/rollup (#37623)
Refactors the `ng_rollup_bundle` rule to a macro that relies on
the `@bazel/rollup` package. This means that the rule no longer
deals with custom ESM5 flavour output, but rather only builds
prodmode ES2015 output. This matches the common build output
in Angular projects, and optimizations done in CLI where
ES2015 is the default optimization input.

The motiviation for this change is:

* Not duplicating rollup Bazel rules. Instead leveraging the official
rollup rule.
* Not dealing with a third TS output flavor in Bazel.The ESM5 flavour has the
potential of slowing down local development (as it requires compilation replaying)
* Updating the rule to be aligned with current CLI optimizations.

This also _fixes_ a bug that surfaced in the old rollup bundle rule.
Code that is unused, is not removed properly. The new rule fixes this by
setting the `toplevel` flag. This instructs terser to remove unused
definitions at top-level. This matches the optimization applied in CLI
projects. Notably the CLI doesn't need this flag, as code is always
wrapped by Webpack. Hence, the unused code eliding runs by default.

PR Close #37623
2020-06-22 10:55:28 -07:00
Greg Magolan
6898eab946 feat(bazel): provide LinkablePackageInfo from ng_module (#37623)
Adds the `LinkablePackageInfo` to the `ng_module` rule. This allows
the linker to properly link `ng_module` targets in Node runtime
actions. Currently this does not work properly and packages like
`@angular/core` are not linked, so we cannot rely on the linker.

9a5de3728b/internal/linker/link_node_modules.bzl (L144-L146).

PR Close #37623
2020-06-22 10:55:28 -07:00
Paul Gschwendtner
62a85f5e55 refactor(bazel): cleanup ng_package rule to not build fesm5 and esm5 output (#37623)
As of Angular Package Format v10, we no longer ship a `fesm5` and
`fesm5` output in packages. We made this change to the `ng_package`
rule but intentionally did not clean up related build actions.

This follow-up commit cleans this up by:

* No longer building fesm5 bundles, or providing esm2015 output.
* No longer requesting and building a third flavor for ESM5. We can
use TSC to downlevel ES2015 sources/prodmode output similarly to how it
is done in `ng-packagr`.

The third output flavor (ESM5) resulted in a build slow-down as we
required a full recompilation of sources. Now, we only have a single
compilation for prodmode output, and then downlevel it on-demand
to ES5 for the UMD bundles. Here is timing for building the release
packages in `angular/angular` before this change, and afterwards:

* Before: 462.157s = ~7.7min
* After: 339.703s =  ~5.6min

This signifies a time reduction by 27% when running
`./scripts/build/build-packages-dist.sh`.

PR Close #37623
2020-06-22 10:55:28 -07:00
Joey Perrott
a8af8551ec refactor(dev-infra): migrate github api in GitClient to rely on GithubClient (#37593)
GitClient now uses GithubClient for github API interactions.  GithubClient is
a class which extends Octokit and provides a member which allows for GraphQL
requests against the Github GraphQL api, as well as providing convenience methods
for common/repeated Github API requests.

PR Close #37593
2020-06-22 10:54:43 -07:00
Tony Bove
7e0eccc4ef docs: Refactor-i18n (#36924)
Rewrite headings to focus on tasks and separate reference info and best practices from tasks. Add missing steps or procedures, and links to important information. Make the example open in StackBlitz. See i18n Documentation Plan at https://docs.google.com/document/d/1aV2TKsIqry7JnNiHEfhmheu5rNAbNl1IRYVhYErc7Ks/edit?usp=sharing

PR Close #36924
2020-06-22 10:52:59 -07:00
Andrew Kushnir
2a970a0af8 Revert "fix(router): fix navigation ignoring logic to compare to the browser url (#37408)" (#37650)
This reverts commit d3a817549b82c3f8c866296af4e952d1af5ac087.

The reason for the revert is the problem reported in g3 which requires additional investigation.

PR Close #37650
2020-06-22 10:47:47 -07:00
Pete Bacon Darwin
bd7f440357 perf(ngcc): shortcircuit tokenizing in ESM dependency host (#37639)
This dependency host tokenizes files to identify all the imported
paths. This commit calculates the last place in the source code
where there can be an import path; it then exits the tokenization
when we get to this point in the file.

Testing with a reasonably large project showed that the tokenizer
spends about 2/3 as much time scanning files. For example in a
"noop" hot run of ngcc using the program-based entry-point
finder the percentage of time spent in the `scan()` function of
the TS tokenizer goes down from 9.9% to 6.6%.

PR Close #37639
2020-06-18 16:05:42 -07:00
nitinknolder
d0437b3be0 docs: fix grammatical errors in developer docs (#37633)
The CONTRIBUTOR and DEVELOPER markdown docs contained a few typos
and grammatical errors, which are fixed in this commit.

PR Close #37633
2020-06-18 16:04:58 -07:00
Tiep Phan
1d844b9bd8 docs(core): correct type for opts.read (#37626)
The ContentChildren decorator has a metadata property named "read" which
can be used to read a different token from the queried elements. The
documentation incorrectly says "True to read..." when it should say
"Used to read...".

PR Close #37626
2020-06-18 16:04:09 -07:00
Paul Gschwendtner
53e95233c3 refactor(dev-infra): cleanup shared package dependencies (#37594)
Cleans up the dependencies used in the shared dev-infra package
configuration. With the recent benchmarking utilities that have
been added, a lot of peer dependencies have been added.

We decided that we don't want to list every used dependencies as
peer dependency as that could result in unnecessary churn/noise
for consumers of the dev-infra package. Additionally, not all parts
of the dev-infra package are necessarily used.

Due to this, we want to apply the following rules for the package
dependencies:

1. If a dependency is only used in a shipped Bazel macro/rule that can be
optionally consumed, omit it from `package.json`. Bazel reports the
missing dependency on its own, so we want to avoid adding it to the
package json file.

2. Otherwise, if the dependency is large and commonly used (like
buildifier), add it to the `peerDependencies`. If not, add it
to the dependencies that are always brought in. We consider it
as acceptable to bring in a few small dependencies that might not
be used or not. Making all of those option would complicate the
use of the dev-infra package.

ds

PR Close #37594
2020-06-18 16:03:14 -07:00
Paul Gschwendtner
879a674420 refactor(dev-infra): use shelljs instead of fs-extra for benchmark utils (#37594)
We added a new dependency on `fs-extra` to the dev-infra package. We can
remove this dependency and replace it with `shelljs` that is extensively
used in other places already.

The motiviation is that we can reduce dependencies needed for
for consumption of the shared dev-infra package.

PR Close #37594
2020-06-18 16:03:14 -07:00
ggradnig
71f008f906 fix(router): remove parenthesis for primary outlet segment after removing auxiliary outlet segment (#24656) (#37163)
For URLs that use auxiliary route outlets in the second or following path segments,
when removing the auxiliary route segment, parenthesis remain for the primary outlet segment.
This causes the following error when trying to reload an URL: "Cannot match any route".
The commit adds a check for this scenario, serializing the URL as "a/b" instead of "a/(b)".

PR Close #24656

PR Close #37163
2020-06-18 16:02:19 -07:00
Sonu Kapoor
1197965e69 docs: move ng-vikings 2020 to the already presented section (#37466)
This commit moves the ng-vikings 2020 event from the currently presenting
section into the already presented section.

PR Close #37466
2020-06-17 11:18:47 -07:00
Paul Gschwendtner
8154bbd538 feat(dev-infra): support for caretaker note label in merge script (#37595)
Adds support for a caretaker note label to the merge script.
Whenever a configured label is applied, the merge script will
not merge automatically, but instead prompt first in order
to ensure that the caretaker paid attention to the manual
caretaker note on the PR. This helps if a PR needs special
attention.

PR Close #37595
2020-06-16 11:58:55 -07:00
Alan Agius
f5e39999d7 docs: add side effect package.json in app structure (#37521)
With this change we add the special `package.json` which is used to mark the application free of non-local side-effects in the application source files section

PR Close #37521
2020-06-16 11:57:40 -07:00
Alan Agius
ff33ab1379 docs: @angular/language‑service is no longer a dev-dependencies (#37521)
`@angular/
language‑service` is no longer needed as a dev-dependencies, infact we no longer generate project with this dependency as it can conflict with the https://marketplace.visualstudio.com/items?itemName=Angular.ng-template

PR Close #37521
2020-06-16 11:57:39 -07:00
David Shevitz 🔵
7521834296 docs: add new section for CLI deprecations (#37332)
Current documentation does not list CLI flag deprecations. This
change adds it for v10.

PR Close #37332
2020-06-16 11:57:04 -07:00
Ajit Singh
1185aa07a3 docs: wrong example in routerLink (#37590)
In routerLink if a fragment is added than fragment example shows that it is added before the params '/user/bob#education?debug=true' but actually they are added after that '/user/bob?debug=true#education' changed documentation to show correct example

Fixes #18630

PR Close #37590
2020-06-16 09:45:22 -07:00
Jan Krems
ceca5dded5 feat(bazel): expose explicit mapping from closure to devmode files (#36262)
This feature is aimed at development tooling that has to translate
production build inputs into their devmode equivalent. The current
process involves guessing the devmode filename based on string
replace patterns. This allows consuming build actions to read the
known mappings instead.

This is a change in anticipation of an update to the general
Typescript build rules to consume this data.

PR Close #36262
2020-06-15 14:32:22 -07:00
lazarljubenovic
2a145f2463 perf(forms): optimize internal method _anyControls in FormGroup (#32534)
The method was previously looping through all controls, even after finding at least one that
satisfies the provided condition. This can be a bottleneck with large forms. The new version
of the method returns as soon as a single control which conforms to the condition is found.

PR Close #32534
2020-06-15 14:31:48 -07:00
Joey Perrott
e0dfa42d6e ci: include PR author as an approver of all PRs (#36915)
This change adds an implicit approval for any change by the
PR author.  This allows for a PR author to provide the required
owner approval for an area of the code base.

This change helps to align the review methodology with how Google's
internal system works. Where anyone is able to provide the LGTM
for a change if thats all that is needed.

PR Close #36915
2020-06-15 14:29:33 -07:00
Joey Perrott
cc37af2314 fix(dev-infra): allow for deep merging of pullapprove config aliases (#36915)
Set the yaml parser to support deep merges of yaml aliases,
to support having a default value for all rules to build upon.

PR Close #36915
2020-06-15 14:29:32 -07:00
crisbeto
87a679b210 build: import in-memory-web-api project (#37182)
Moves the `angular-in-memory-web-api` project into the main repository in order to make it easier to maintain and release.

PR Close #37182
2020-06-15 14:28:37 -07:00
Misko Hevery
a7359d494a docs: release notes for the v10.0.0-rc.6 release 2020-06-15 14:22:30 -07:00
Paul Gschwendtner
66e6b932d8 refactor(compiler-cli): skip class decorators in tooling constructor parameters transform (#37545)
We recently added a transformer to NGC that is responsible for downleveling Angular
decorators and constructor parameter types. The primary goal was to mitigate a
TypeScript limitation/issue that surfaces in Angular projects due to the heavy
reliance on type metadata being captured for DI. Additionally this is a pre-requisite
of making `tsickle` optional in the Angular bazel toolchain.

See: 401ef71ae5b01be95d124184a0b6936fc453a5d4 for more context on this.

Another (less important) goal was to make sure that the CLI can re-use
this transformer for its JIT mode compilation. The CLI (as outlined in
the commit mentioned above), already has a transformer for downleveling
constructor parameters. We want to avoid this duplication and exported
the transform through the tooling-private compiler entry-point.

Early experiments in using this transformer over the current one, highlighted
that in JIT, class decorators cannot be downleveled. Angular relies on those
to be invoked immediately for JIT (so that factories etc. are generated upon loading)

The transformer we exposed, always downlevels such class decorators
though, so that would break CLI's JIT mode. We can address the CLI's
needs by adding another flag to skip class decorators. This will allow
us to continue with the goal of de-duplication.

PR Close #37545
2020-06-15 12:47:57 -07:00
Misko Hevery
cc49a91de7 Revert "feat(bazel): expose explicit mapping from closure to devmode files (#36262)"
This reverts commit 7ac166ff0870a826a21b103b86557ca5bea7abc2.
2020-06-15 10:19:56 -07:00
Alex Rickabaugh
300c2fec9c refactor(compiler-cli): make IncrementalBuild strategy configurable (#37339)
Commit 24b2f1da2b introduced an `NgCompiler` which operates on a
`ts.Program` independently of the `NgtscProgram`. The NgCompiler got its
`IncrementalDriver` (for incremental reuse of Angular compilation results)
by looking at a monkey-patched property on the `ts.Program`.

This monkey-patching operation causes problems with the Angular indexer
(specifically, it seems to cause the indexer to retain too much of prior
programs, resulting in OOM issues). To work around this, `IncrementalDriver`
reuse is now handled by a dedicated `IncrementalBuildStrategy`. One
implementation of this interface is used by the `NgtscProgram` to perform
the old-style reuse, relying on the previous instance of `NgtscProgram`
instead of monkey-patching. Only for `NgTscPlugin` is the monkey-patching
strategy used, as the plugin sits behind an interface which only provides
access to the `ts.Program`, not a prior instance of the plugin.

PR Close #37339
2020-06-15 09:50:08 -07:00
George Kalpakas
a7faa6bb65 docs(service-worker): minor fixes/improvements in the SW Communication guide (#37555)
This commit includes various fixes/improvements for the
"Service worker communication" guide.

This partially addresses #37527.

PR Close #37555
2020-06-15 09:48:55 -07:00
George Kalpakas
bcc0a035cc docs(service-worker): update default value of SwRegistrationOptions#registrationStrategy (#37555)
The default value was changed from `registerWhenStable` to
`registerWhenStable:30000` in 29e8a64cf02fa9b80d38c30091e0b730403c54c8,
but the decumentation was not updated to reflect that.

This commit updates the documentation to mention the correct default
value.

PR Close #37555
2020-06-15 09:48:55 -07:00
ivanwonder
e99bcbb4d4 fix(language-service): wrong completions in conditional operator (#37505)
In `a ? b.~{cursor}`, the LS will provide the symbols in the scope of the current template, because the `path.tail` is `falseExp` whose value is `EmptyExpr`, and the span of `falseExp` is wider than the `trueExp`, so the value of `path` should be narrowed.

PR Close #37505
2020-06-15 09:41:25 -07:00
David Shevitz 🔵
adc9d5cdcb docs: describe how to configure CommonJS modules (#37331)
In version 10, we have a new option for the `angular.json` file,
`allowedCommonJsDependencies`, so users can opt in to support
CommonJS modules.

PR Close #37331
2020-06-15 09:40:44 -07:00
Sonu Kapoor
d330cd85ac refactor: move hover into a proper @media hover (#37320)
This commit moves the contributor hover into the `@media(hover:hover)`
query. This will help to identify if the user's primary input mechanism
can hover over elements.

PR Close #37320
2020-06-15 09:39:17 -07:00
David Shevitz 🔵
09d6dc50ef docs: Update documentation to reflect addition of tsconfig.base.json. (#37222)
In version 10, there is a new `tsconfig.json` file, which contains
the paths to all other `tsconfig` files used in a workspace. The
previous `tsconfig.json` file still exists, but has been renamed to
`tsconfig.base.json`.

In addition to documenting this change, I have updated files that
refer to TypeScript configuration files generically to remove specific
references to `tsconfig.json.` This should help avoid confusing users.

PR Close #37222
2020-06-15 09:37:00 -07:00
Jan Krems
7ac166ff08 feat(bazel): expose explicit mapping from closure to devmode files (#36262)
This feature is aimed at development tooling that has to translate
production build inputs into their devmode equivalent. The current
process involves guessing the devmode filename based on string
replace patterns. This allows consuming build actions to read the
known mappings instead.

This is a change in anticipation of an update to the general
Typescript build rules to consume this data.

PR Close #36262
2020-06-15 09:35:35 -07:00
Jesse Lucas
ae4f81cbab docs: Change 'function' to 'method' for clarity that getHereos() is (#35998)
intended as a class method

Change 'function' to 'method' for clarity that getHereos() is
intended as a class method in Tour of Heroes part 4.

PR Close #35998
2020-06-15 09:07:51 -07:00
David Shevitz
c1fdfd4f14 docs: update CONTRIBUTING.md with info about major docs changes (#35238)
The goal of this change is to clarify definition of major feature submissions to include writing new topics for the docs.

PR Close #35238
2020-06-15 09:05:16 -07:00
Aamir Mukaram
62e4acc3d1 docs: fix typo in control_value_accessor.ts (#37057)
This commit updates the `ControlValueAccessor` class description in the `@angular/forms` package to fix a typo.

PR Close #37057
2020-06-12 15:11:11 -07:00
Doug Parker
1091ddbb8e build(bazel): check for renderer flag in ng_module() (#37529)
This checks for a Bazel flag in `ng_module()` in the `_renderer` attribute
which specifies the renderer to use for the build.

The main advantage of this flag is that it can be overridden with [Bazel
transitions](https://docs.bazel.build/versions/master/skylark/config.html),
giving much more flexibility for migrating individual applications in a
Bazel workspace to Ivy.

This flag is not intended to replace `--config ivy` or
`--define angular_ivy_enabled=True` (although it technically could). As a
result, this flag is not and will not actually be used anywhere in the
`angular/angular` repo. Instead, a `string_flag()` is provided  internally
which sets the renderer via a transition. See http://cl/315749946.

Note that this does **not** introduce a dependency on Skylib for
`angular/angular`. The dependency isn't actually necessary because
`BuildSettingInfo` is not used externally anyways. By doing this, it is not
necessary for downstream, external workspaces to depend on Skylib.

PR Close #37529
2020-06-12 15:10:39 -07:00
Joey Perrott
b45acb8d32 feat(dev-infra): add # to outputed list of PRs for discover-new-conflicts (#37556)
Adding in a `#` prepended to each PR number in the list of conflicting PRs
found by the discover-new-conflicts script will allow for users to copy
paste the output from the script into a github comment and have the PRs
automatically link.

PR Close #37556
2020-06-12 15:08:53 -07:00
Joey Perrott
104abe04ba ci: upload build results to ResultStore for CI linux bazel executions (#37560)
Bazel invocations will upload to ResultStore to allow for us to have better viewing
of execution/build logs.  This is only done on CI as the BES API requires credentials
from service accounts, rather than end user accounts.

PR Close #37560
2020-06-12 15:08:03 -07:00
Joey Perrott
1bc807c81a style(common): enforce format on newly included files (#36940)
Historically files to be formatted were added to a listing (via matchers)
to be included in formatting.  Instead, this change begins efforts to
instead include all files in format enforcement, relying instead on an
opt out methodology.

PR Close #36940
2020-06-12 15:06:41 -07:00
Joey Perrott
d3b5e5696f style(dev-infra): enforce format on newly included files (#36940)
Historically files to be formatted were added to a listing (via matchers)
to be included in formatting.  Instead, this change begins efforts to
instead include all files in format enforcement, relying instead on an
opt out methodology.

PR Close #36940
2020-06-12 15:06:41 -07:00
Joey Perrott
34e4098e85 build: increase scope of files with enforced formatting (#36940)
Historically files to be formatted were added to a listing (via matchers)
to be included in formatting.  Instead, this change begins efforts to
instead include all files in format enforcement, relying instead on an
opt out methodology.

PR Close #36940
2020-06-12 15:06:41 -07:00
Alan Agius
8dcf618411 docs: add redirects for cli generated config files (#37533)
With this change we add redirects for config files generated by the Angular CLI. These links form part of a comment in the generated files, thus it is important that they valid for the many years to come.

PR Close #37533
2020-06-12 08:51:24 -07:00
Kishan Gajera
7cc7955b5d docs: fix contributor website links with no protocol (#37528)
Two contributor website links do not have a protocol so they are treated as a relative URL and do not work as expected.

PR Close #37528
2020-06-12 08:50:52 -07:00
Ajit Singh
a075260751 docs: document how external link icons work (#37025)
After PR #36601 which added icons to all external links. Documented how this is happening via comments in scss file. For details visit PR #36601

PR Close #37025
2020-06-12 08:50:18 -07:00
crisbeto
aba33de5f5 build: fix outdated payload size (#37551)
Updates the payload size for one of the bundles that is currently causing one of the CI tasks to fail on master.

PR Close #37551
2020-06-12 08:49:45 -07:00
Moritz Obermeier
fe0782afa9 docs: small change in the Introduction (#35528)
The word "both" is automatically connected with the previous two bullet points and not the following two (because documents are usually read from top to bottom), which made the original sentence confusing for first time readers.

PR Close #35528
2020-06-11 19:11:56 -07:00
rch850
3545520e81 docs: fix result of sanitization example (#36059)
This commit fixes sanitization example
in https://angular.io/guide/template-syntax#content-security.

* Escape < and > of interpolation result.
* Fix result of property binding result.

PR Close #36059
2020-06-11 19:11:23 -07:00
Tony Bove
5ea9119322 docs: make correction in Tutorial toh-pt6 (#37516)
Fixes issue [29535](https://github.com/angular/angular/issues/29535) for the tutorial (toh-pt6) to remove the phrase that directed the reader to delete mock-heroes.ts when it is still needed for further tutorial steps.

PR Close #37516
2020-06-11 19:10:48 -07:00
crisbeto
2e355fd4d3 fix(compiler): unable to resolve destructuring variable declarations (#37497)
Currently the partial evaluator isn't able to resolve a variable declaration that uses destructuring in the form of `const {value} = {value: 0}; const foo = value;`. These changes add some logic to allow for us to resolve the variable's value.

Fixes #36917.

PR Close #37497
2020-06-11 19:10:04 -07:00
David Shevitz 🔵
12f2101d08 docs: add link to Angular component/material changelog. (#37491)
At present, users don't have an easy way to discover what
deprecations occurred for Angular CDK or Angular Material.
This change adds a link to the changelog to the deprecations.md
file.

PR Close #37491
2020-06-11 19:04:12 -07:00
Andrew Scott
d3a817549b fix(router): fix navigation ignoring logic to compare to the browser url (#37408)
This PR changes the logic for determining when to skip route processing from
using the URL of the last attempted navigation to the actual resulting URL after
that transition.

Because guards may prevent navigation and reset the browser URL, the raw
URL of the previous transition may not match the actual URL of the
browser at the end of the navigation process. For that reason, we need to use
`urlAfterRedirects` instead.

Other notes:
These checks in scheduleNavigation were added in eb2ceff4ba
The test still passes and, more surprisingly, passes if the checks are removed
completely. There have likely been changes to the navigation handling that
handle the test in a different way. That said, it still appears to be important
to keep the checks there in some capacity because it does affect how many
navigation events occur. This addresses an issue that came up in #16710: https://github.com/angular/angular/issues/16710#issuecomment-634869739
This also partially addresses #13586 in fixing history for imperative
navigations that are cancelled by guards.

PR Close #37408
2020-06-11 19:03:40 -07:00
David Shevitz 🔵
c5493c192c docs: differential loading is opt-in (#37327)
With version 10, differential loading changes from `opt-out` to `opt
in`. This change updates the documentation accordingly.

PR Close #37327
2020-06-11 19:02:58 -07:00
Suguru Inatomi
d17084bf97 docs: add tslib change to v10 CHANGELOG (#37303)
Previously the tslib 2.0 change was not listed in the CHANGELOG because
it was marked as a refactoring. This change is important enough to be
listed in the changelog even tough it doesn't affect most of the users.

For users that do get unexpectedly affected by this change, it might be
useful to find the change listed in the CHANGELOG.

PR Close #37303
2020-06-11 19:01:25 -07:00
Ajit Singh
f150a304e8 refactor(compiler): remove extra imports (#37246)
There are some extra imports in the compiler package. These imports are not used anywhere in the file. So, removed those extra imports

PR Close #37246
2020-06-11 19:00:33 -07:00
Judy Bogart
886e3ebcca docs: update api ref doc for platform browser (#37186)
Edit descriptions, usage examples, and add links to be complete and consistent with API reference doc style

PR Close #37186
2020-06-11 18:59:12 -07:00
George Kalpakas
bf682d73d4 fix(ngcc): correctly get config for packages in nested node_modules/ (#37040)
Previously, ngcc would only be able to match an ngcc configuration to
packages that were located inside the project's top-level
`node_modules/`. However, if there are multiple versions of a package in
a project (e.g. as a transitive dependency of other packages), multiple
copies of a package (at different versions) may exist in nested
`node_modules/` directories. For example, one at
`<project-root>/node_modules/some-package/` and one at
`<project-root>/node_modules/other-package/node_modules/some-package/`.
In such cases, ngcc was only able to detect the config for the first
copy but not for the second.

This commit fixes this by returning a new instance of
`ProcessedNgccPackageConfig` for each different package path (even if
they refer to the same package name). In these
`ProcessedNgccPackageConfig`, the `entryPoints` paths have been
processed to take the package path into account.

PR Close #37040
2020-06-11 18:58:36 -07:00
George Kalpakas
8f3695e20e refactor(ngcc): add packageName property to EntryPoint interface (#37040)
This commit adds a `packageName` property to the `EntryPoint` interface.
In a subsequent commit this will be used to retrieve the correct ngcc
configuration for each package, regardless of its path.

PR Close #37040
2020-06-11 18:58:36 -07:00
George Kalpakas
829ddf95e5 fix(ngcc): correctly retrieve a package's version from its package.json (#37040)
In order to retrieve the ngcc configuration (if any) for an entry-point,
ngcc has to detect the containing package's version.

Previously, ngcc would try to read the version from the entry-point's
`package.json` file, which was different than the package's top-level
`package.json` for secondary entry-points. For example, it would try to
read it from `node_modules/@angular/common/http/package.json` for
entry-point `@angular/common/http`. However, the `package.json` files
for secondary entry-points are not guaranteed to include a `version`
property.

This commit fixes this by first trying to read the version from the
_package's_ `package.json` (falling back to the entry-point's
`package.json`). For example, it will first try to read it from
`@angular/common/package.json` for entry-point `@angular/common/http`.

PR Close #37040
2020-06-11 18:58:36 -07:00
George Kalpakas
fb10f62efc refactor(ngcc): refactor how info is retrieved from entry-point package.json (#37040)
This commit refactors the way info is retrieved from entry-point
`package.json` files to make it easier to extract more info (such as the
package's name) in the future. It also avoids reading and parsing the
`package.json` file multiple times (as was happening before).

PR Close #37040
2020-06-11 18:58:36 -07:00
George Kalpakas
8197557fcf refactor(ngcc): rename EntryPoint#package to EntryPoint#packagePath (#37040)
Rename the `package` property to `packagePath` on the `EntryPoint`
interface. This makes it more clear that the `packagePath` property
holds the absolute path to the containing package (similar to how `path`
holds the path to the entry-point). This will also align with the
`packageName` property that will be added in a subsequent commit.

This commit also re-orders the `EntryPoint` properties to group related
properties together and to match the order of properties on instances
with that on the interface.

PR Close #37040
2020-06-11 18:58:36 -07:00
George Kalpakas
e7a0e87c41 fix(ngcc): correctly get config for sub-entry-points when primary entry-point is ignored (#37040)
Previously, when an entry-point was ignored via an ngcc config, ngcc
would scan sub-directories for sub-entry-points, but would not use the
correct `packagePath`. For example, if `@angular/common` was ignored, it
would look at `@angular/common/http` but incorrectly use
`.../@angular/common/http` as the `packagePath` (instead of
`.../@angular/common`). As a result, it would not retrieve the correct
ngcc config for the actual package.

This commit fixes it by ensuring the correct `packagePath` is used, even
if the primary entry-point corresponding to that path is ignored. In
order to do this, a new return value for `getEntryPointInfo()` is added:
`IGNORED_ENTRY_POINT`. This is used to differentiate between directories
that correspond to no or an incompatible entry-point and those that
correspond to an entry-point that could otherwise be valid but is
explicitly ignored. Consumers of `getEntryPointInfo()` can then use this
info to discard ignored entry-points, but still use the correct
`packagePath` when scanning their sub-directories for secondary
entry-points.

PR Close #37040
2020-06-11 18:58:36 -07:00
George Kalpakas
ab9bc8a9ec refactor(ngcc): clean up unused imports, unused regex parenthesis, typos (#37040)
This is a follow-up to #37075, because I didn't manage to finish my
review before the PR got merged.

PR Close #37040
2020-06-11 18:58:36 -07:00
George Kalpakas
469d2b4640 refactor(ngcc): fix typos in comments (#37040)
This is a follow-up to #36944, because I didn't manage to finish my
review before the PR got merged.

PR Close #37040
2020-06-11 18:58:36 -07:00
JiaLiPassion
31796e8e2f fix(zone.js): remove unused Promise overwritten setter logic (#36851)
In the early Zone.js versions (< 0.10.3), `ZoneAwarePromise` did not support `Symbol.species`,
so when user used a 3rd party `Promise` such as `es6-promise`, and try to load the promise library after import of `zone.js`, the loading promise library will overwrite the patched `Promise` from `zone.js` and will break `Promise` semantics with respect to `zone.js`.

Starting with `zone.js` 0.10.3, `Symbol.species` is supported therefore this will not longer be an issue. (https://github.com//pull/34533)

Before 0.10.3, the logic in zone.js tried to handle the case in the wrong way. It did so by overriding the descriptor of `global.Promise`, to allow the 3rd party libraries to override native `Promise` instead of `ZoneAwarePromise`. This is not the correct solution, and since the `Promise.species` is now supported, the 3rd party solution of overriding `global.Promise` is no longer needed.

PR removes the wrong work around logic. (This will improve the bundle size.)

PR Close #36851
2020-06-11 18:56:19 -07:00
JiaLiPassion
284123c6ba fix(core): should fake a top event task when coalescing events to prevent draining microTaskQueue too early. (#36841)
Close #36839.

This is a known issue of zone.js,

```
(window as any)[(Zone as any).__symbol__('setTimeout')](() => {
  let log = '';
  button.addEventListener('click', () => {
    Zone.current.scheduleMicroTask('test', () => log += 'microtask;');
    log += 'click;';
  });
  button.click();
  expect(log).toEqual('click;microtask;');
  done();
});
```

Since in this case, we use native `setTimeout` which is not a ZoneTask,
so zone.js consider the button click handler as the top Task then drain the
microTaskQueue after the click at once, which is not correct(too early).

This case was an edge case and not reported by the users, until we have the
new option ngZoneEventCoalescing, since the event coalescing will happen
in native requestAnimationFrame, so it will not be a ZoneTask, and zone.js will
consider any Task happen in the change detection stage as the top task, and if
there are any microTasks(such as Promise.then) happen in the process, it may be
drained earlier than it should be, so to prevent this situation, we need to schedule
a fake event task and run the change detection check in this fake event task,
so the Task happen in the change detection stage will not be
considered as top ZoneTask.

PR Close #36841
2020-06-11 18:54:22 -07:00
Tony Bove
7259208893 docs: Refactor-pipes (#36820)
Language tightened, and headings rewritten to focus on user tasks. Tasks now separated from concepts, and clarified as examples. Content is up-to-date and complete. Links to important information and relevant topics added.

PR Close #36820
2020-06-11 18:45:15 -07:00
Misko Hevery
7e5f6c2dc1 docs: release notes for the v10.0.0-rc.5 release 2020-06-11 16:08:38 -07:00
Paul Gschwendtner
97dc85ba5e feat(core): support injection token as predicate in queries (#37506)
Currently Angular internally already handles `InjectionToken` as
predicates for queries. This commit exposes this as public API as
developers already relied on this functionality but currently use
workarounds to satisfy the type constraints (e.g. `as any`).

We intend to make this public as it's low-effort to support, and
it's a significant key part for the use of light-weight tokens as
described in the upcoming guide: https://github.com/angular/angular/pull/36144.

In concrete, applications might use injection tokens over classes
for both optional DI and queries, because otherwise such references
cause classes to be always retained. This was also an issue in View
Engine, but now with Ivy, this pattern became worse, as factories are
directly attached to retained classes (ultimately ending up in the
production bundle, while being unused).

More details in the light-weight token guide and in: https://github.com/angular/angular-cli/issues/16866.

Closes #21152. Related to #36144.

PR Close #37506
2020-06-11 13:21:11 -07:00
Alan Agius
a937889c3b refactor(elements): add accessor workaround for build-optimizer (#37456)
Build-optimizer currently uses TypeScript 3.6 which is unable to resolve an 'accessor' in 'getTypeOfVariableOrParameterOrPropertyWorker'.

Unfortunately, in Build optimizer we cannot update the version of TypeScript because of https://github.com/microsoft/TypeScript/issues/38412

PR Close #37456
2020-06-11 12:05:34 -07:00
Alan Agius
aa8f1d569b build: add @babel/preset-env to dependencies (#37456)
`@babel/preset-env` is needed by for NGCC tests: 3569fdf451/packages/compiler-cli/ngcc/test/BUILD.bazel (L84)

However this is not as a depedency in the angular repo.

PR Close #37456
2020-06-11 12:05:34 -07:00
Alan Agius
5dba3bf1fd build: update CLI packages to the latest RC version for v10 (#37456)
With this change we update the Angular CLI repo and aio packages to the latest RC version for version 10.

PR Close #37456
2020-06-11 12:05:33 -07:00
Alan Agius
6651b4171d build: update to typescript 3.9.5 (#37456)
This TypeScript version contains the revert for the classes wrapped in IIFE change that was introduced in version 3.9.

PR Close #37456
2020-06-11 12:05:33 -07:00
David Neil
8c682c52b1 fix(ngcc): use annotateForClosureCompiler option (#36652)
Adds @nocollapse to static properties added by ngcc
iff annotateForClosureCompiler is true.

The Closure Compiler will collapse static properties
into the global namespace.  Adding this annotation keeps
the properties attached to their respective object, which
allows them to be referenced via a class's constructor.
The annotation is already added by ngtsc and ngc under the
same option, this commit extends the functionality to ngcc.

Closes #36618.

PR Close #36652
2020-06-11 11:12:56 -07:00
ajitsinghkaler
e5b09cc49a docs: add example links to 'DoCheck' lifeycle hook docs (#36574)
There were some examples for 'DoCheck' in the lifeCycle hooks guide. Added a link to the relevant section of the guide in the 'DoCheck()' api docs.

Fixes #35596

PR Close #36574
2020-06-11 11:09:58 -07:00
JiaLiPassion
b199ef6bfc feat(zone.js): move all zone optional bundles to plugins folders (#36540)
Zone.js has a lot of optional bundles, such as `zone-patch-message-port`, those
bundles are monkey patch for specified APIs usually for soem experimental APIs or
some old APIs only available for specified platforms. Those bundles will not be
loaded by default.

In this commit, since we have several main `sub packages` such as `zone`, `zone-node`,
`zone-testing`, I put all the optional bundles under `plugins` folders for consistency.

PR Close #36540
2020-06-11 11:08:48 -07:00
JiaLiPassion
583a9d38a1 feat(zone.js): upgrade zone.js to angular package format(APF) (#36540)
Close #35157

In the current version of zone.js, zone.js uses it's own package format, and it is not following the rule
of Angualr package format(APF), so it is not easily to be consumed by Angular CLI or other bundle tools.
For example, zone.js npm package has two bundles,

1. zone.js/dist/zone.js, this is a `es5` bundle.
2. zone.js/dist/zone-evergreen.js, this is a `es2015` bundle.

And Angular CLI has to add some hard-coding code to handle this case, o5376a8b139/packages/schematics/angular/application/files/src/polyfills.ts.template (L55-L58)

This PR upgrade zone.js npm package format to follow APF rule, https://docs.google.com/document/d/1CZC2rcpxffTDfRDs6p1cfbmKNLA6x5O-NtkJglDaBVs/edit#heading=h.k0mh3o8u5hx

The updated points are:

1. in package.json, update all bundle related properties

```
  "main": "./bundles/zone.umd.js",
  "module": "./fesm2015/zone.js",
  "es2015": "./fesm2015/zone.js",
  "fesm2015": "./fesm2015/zone.js",
```

2. re-organize dist folder, for example for `zone.js` bundle, now we have

```
  dist/
      bundles/
             zone.js            // this is the es5 bundle
      fesm2015/
             zone.js            // this is the es2015 bundle (in the old version is `zone-evergreen.js`)
```

3. have several sub-packages.

1. `zone-testing`, provide zone-testing bundles include zone.js and testing libraries
2. `zone-node`, provide zone.js implemention for NodeJS
3. `zone-mix`, provide zone.js patches for both Browser and NodeJS

All those sub-packages will have their own `package.json` and the bundle will reference `bundles(es5)` and `fesm2015(es2015)`.

4. keep backward compatibility, still keep the `zone.js/dist` folder, and all bundles will be redirected to `zone.js/bundles` or `zone.js/fesm2015` folders.

PR Close #36540
2020-06-11 11:08:48 -07:00
Stewart Rand
1fce6d6bae docs: Minor grammar fix: "bug-free" (#36515)
Change documentation to a more grammatically correct format. "bug-free" is preferred over "bug free".

PR Close #36515
2020-06-11 11:07:54 -07:00
Stephen Fluin
39f973430a docs: remove out of date GDEs (#36467)
Periodic documentation cleanup of GDEs which are no longer in the Angular program.

Removed:
 - "Filip Bruun Bech-Larsen"
 - "Vinci Rufus"
 - "Jeff Cross"

PR Close #36467
2020-06-11 11:04:11 -07:00
Joey Perrott
20346ff192 build: remove ngcontainer Docker (#36421)
ngcontainer Dockerfile was noted as deprecated ~2 years ago, we no longer
rely on it anymore nor do we publish it.

PR Close #36421
2020-06-10 12:59:07 -07:00
Paul Gschwendtner
bd9c1e6cfc build: add commit message scope for migration changes (#36390)
This is a proposal commit that adds a separate scope for
migration changes. The motiviation is that migrations aren't
necessarily always affecting `@angular/core`, but are just
stored in the core package for a canonical location when
someone runs `ng update`. Additionally, it rather seems confusing in the
changelog if migration changes are listed under `core`.

PR Close #36390
2020-06-10 12:03:45 -07:00
Mike Huang
d76a872efb docs: add Mike Huang as a GDE (#36472)
Update the GDE listing with info abbout Mike Huang.
Update the GDE listing with info abbout Mike Huang.

PR Close #36472
2020-06-10 11:53:25 -07:00
Ajit Singh
a398d6af45 docs: remove redundant web-worker nav (#37289)
Web- worker was 2 times in the nav pointing towards the same file, just with different names removed one to remove redundancy

PR Close #37289
2020-06-10 11:52:06 -07:00
Charles Lyding
e836eaf448 fix(docs-infra): preconnect to analytics origins (#37400)
Lighthouse recommends preconnecting to important third-party origins.
See: https://web.dev/uses-rel-preconnect

PR Close #37400
2020-06-10 11:51:43 -07:00
Pete Bacon Darwin
ae364864f6 fix(ngcc): do not scan import expressions in d.ts files (#37503)
It is quite common for the TS compiler to have to add synthetic
types to function signatures, where the developer has not
explicitly provided them.  This results in `import(...)` expressions
appearing in typings files.  For example in `@ngrx/data` there is a
class with a getter that has an implicit type:

```ts
export declare class EntityCollectionServiceBase<...> {
  ...
  get store() {
    return this.dispatcher.store;
  }
  ...
}
```

In the d.ts file for this we get:

```ts
get store(): Store<import("@ngrx/data").EntityCache>;
```

Given that this file is within the `@ngrx/data` package already,
this caused ngcc to believe that there was a circular dependency,
causing it to fail to process the package - and in fact crash!

This commit resolves this problem by ignoring `import()` expressions
when scanning typings programs for dependencies. This ability was
only introduced very recently in a 10.0.0 RC release, and so it has
limited benefit given that up till now ngcc has been able to process
libraries effectively without it. Moreover, in the rare case that a
package does have such a dependency, it should get picked up
by the sync ngcc+CLI integration point.

PR Close #37503
2020-06-10 11:51:18 -07:00
Keen Yee Liau
cc552dd702 feat(language-service): Remove HTML entities autocompletion (#37515)
This commit removes the autocompletion feature for HTML entities.
HTML entites are things like `&amp;`, `&lt;` etc.

There are a few reasons for the decision:

1. It is outside the core functionality of Angular LS
2. The implementation relies on regex, which incurs performance cost
3. There isn't much value if users do not already know which entity
   they want to use
4. The list that we provide is not exhaustive

PR Close #37515
2020-06-10 11:50:54 -07:00
atscott
021dd33ed8 docs: release notes for the v10.0.0-rc.4 release 2020-06-10 11:45:00 -07:00
atscott
684726cdac docs: release notes for the v9.1.11 release
This commit contains the release notes from the 9.1.11 release. They were Copy-pasted from the CHANGELOG in the 9.1.x branch.
2020-06-10 11:26:59 -07:00
atscott
7b005bb9cf Revert "fix(elements): fire custom element output events during component initialization (#36161)" (#37524)
This reverts commit e9bff5fe9f40d87b2164fc4f667f2cdd0afd4634. Failures
were detected in Google tests due to this commit

PR Close #37524
2020-06-10 17:28:57 +00:00
Paul Gschwendtner
401ef71ae5 fix(compiler-cli): downlevel angular decorators to static properties (#37382)
In v7 of Angular we removed `tsickle` from the default `ngc` pipeline.
This had the negative potential of breaking ES2015 output and SSR due
to a limitation in TypeScript.

TypeScript by default preserves type information for decorated constructor
parameters when `emitDecoratorMetadata` is enabled. For example,
consider this snippet below:

```
@Directive()
export class MyDirective {
  constructor(button: MyButton) {}
}

export class MyButton {}
```

TypeScript would generate metadata for the `MyDirective` class it has
a decorator applied. This metadata would be needed in JIT mode, or
for libraries that provide `MyDirective` through NPM. The metadata would
look as followed:

```
let MyDirective = class MyDir {}

MyDirective = __decorate([
  Directive(),
  __metadata("design:paramtypes", [MyButton]),
], MyDirective);

let MyButton = class MyButton {}
```

Notice that TypeScript generated calls to `__decorate` and
`__metadata`. These calls are needed so that the Angular compiler
is able to determine whether `MyDirective` is actually an directive,
and what types are needed for dependency injection.

The limitation surfaces in this concrete example because `MyButton`
is declared after the `__metadata(..)` call, while `__metadata`
actually directly references `MyButton`. This is illegal though because
`MyButton` has not been declared at this point. This is due to the
so-called temporal dead zone in JavaScript. Errors like followed will
be reported at runtime when such file/code evaluates:

```
Uncaught ReferenceError: Cannot access 'MyButton' before initialization
```

As noted, this is a TypeScript limitation because ideally TypeScript
shouldn't evaluate `__metadata`/reference `MyButton` immediately.
Instead, it should defer the reference until `MyButton` is actually
declared. This limitation will not be fixed by the TypeScript team
though because it's a limitation as per current design and they will
only revisit this once the tc39 decorator proposal is finalized
(currently stage-2 at time of writing).

Given this wontfix on the TypeScript side, and our heavy reliance on
this metadata in libraries (and for JIT mode), we intend to fix this
from within the Angular compiler by downleveling decorators to static
properties that don't need to evaluate directly. For example:

```
MyDirective.ctorParameters = () => [MyButton];
```

With this snippet above, `MyButton` is not referenced directly. Only
lazily when the Angular runtime needs it. This mitigates the temporal
dead zone issue caused by a limitation in TypeScript's decorator
metadata output. See: https://github.com/microsoft/TypeScript/issues/27519.

In the past (as noted; before version 7), the Angular compiler by
default used tsickle that already performed this transformation. We
moved the transformation to the CLI for JIT and `ng-packager`, but now
we realize that we can move this all to a single place in the compiler
so that standalone ngc consumers can benefit too, and that we can
disable tsickle in our Bazel `ngc-wrapped` pipeline (that currently
still relies on tsickle to perform this decorator processing).

This transformation also has another positive side-effect of making
Angular application/library code more compatible with server-side
rendering. In principle, TypeScript would also preserve type information
for decorated class members (similar to how it did that for constructor
parameters) at runtime. This becomes an issue when your application
relies on native DOM globals for decorated class member types. e.g.

```
@Input() panelElement: HTMLElement;
```

Your application code would then reference `HTMLElement` directly
whenever the source file is loaded in NodeJS for SSR. `HTMLElement`
does not exist on the server though, so that will become an invalid
reference. One could work around this by providing global mocks for
these DOM symbols, but that doesn't match up with other places where
dependency injection is used for mocking DOM/browser specific symbols.

More context in this issue: #30586. The TL;DR here is that the Angular
compiler does not care about types for these class members, so it won't
ever reference `HTMLElement` at runtime.

Fixes #30106. Fixes #30586. Fixes #30141.
Resolves FW-2196. Resolves FW-2199.

PR Close #37382
2020-06-10 09:24:11 -07:00
Joey Perrott
0a1d078a74 Revert "build: remove wombot proxy registry from package.jsons for release (#37378)" (#37495)
This reverts commit 26849ca99dcafc45fb8cb0e97af7aeb85ea11852.

PR Close #37495
2020-06-10 08:21:45 -07:00
atscott
35502c739c docs: release notes for the v9.1.10 release
This commit contains the release notes from the 9.1.10 release. They were copy-pasted from the CHANGELOG in the 9.1.x branch.
2020-06-09 15:25:31 -07:00
crisbeto
b2ccc34f9c perf(core): avoid pulling in jit-specific code in aot bundles (#37372)
In #29083 a call to `getCompilerFacade` was added to `ApplicationRef` which pulls in a bit of JIT-specific code. Since the code path that calls the function can't be hit for an AOT-compiled app, these changes add an `ngJitMode` guard which will allow for dead code elimination to drop it completely. Testing it out against a new CLI project showed a difference of ~1.2kb.

PR Close #37372
2020-06-09 13:34:43 -07:00
Andrew Scott
eaa38a5adc docs(dev-infra): add comment about what the requiredBaseCommit is (#37509)
Add a comment to describe what the commit was for the given SHA so that we don't have to look it up.

PR Close #37509
2020-06-09 13:29:24 -07:00
Ajit Singh
cb1373106b docs: wrong links in lifecycle hooks api documentaion (#36557)
lifecycle hooks api detailed documentation contained links which were pointing to onChanges hook only which is removed, made each hook point towards its deafult page link

PR Close #36557
2020-06-09 11:16:43 -07:00
AleksanderBodurri
f6ee911cbb docs(core): fix path referenced in comments of both compiler facade interface files (#37370)
Previously the comments for these files referenced a path to "packages/core/src/render3/jit/compiler_facade_interface.ts" that does not exist in the current codebase.

This PR corrects the path in these comments.

PR Close #37370
2020-06-09 08:28:26 -07:00
Paul Gschwendtner
a3313709ea fix(dev-infra): local changes check not working (#37489)
Looks like we broke the `hasLocalChanges` check in the git client
when we moved it over from the merge script. The problem is that
we are using `git` in the first argument of `git.run`. That
means that we under-the-hood run `git git <..>`.

This commit fixes that, but also switches to a better variant
for ensuring no local changes because it exits with non-zero
when there are local changes.

PR Close #37489
2020-06-09 08:27:32 -07:00
Paul Gschwendtner
0eacba5829 fix(dev-infra): rebase pr script not working (#37489)
The dev-infra rebase PR script currently does not work due to
the following issues:

1. The push refspec is incorrect. It refers to the `base` of the PR, and
not to the `head` of the PR.
2. The push `--force-with-lease` option does not work in a detached head
as no remote-tracking branch is set up.

PR Close #37489
2020-06-09 08:27:32 -07:00
Paul Gschwendtner
bb924b63e6 fix(dev-infra): incorrect token sanitization when no token is specified (#37489)
We recently moved over the git client from the merge script to the
common dev-infra utils. This made specifying a token optional, but
it looks like the logic for sanitizing messages doesn't account
for that, and we currently add `<TOKEN>` between every message
character. e.g.

```
Executing: git <TOKEN>g<TOKEN>i<TOKEN>t<TOKEN>
<TOKEN>s<TOKEN>t<TOKEN>a<TOKEN>t<TOKEN>u<TOKEN>s<TOKEN>
```

PR Close #37489
2020-06-09 08:27:31 -07:00
Adam
7301e70ddd fix(platform-server): correctly handle absolute relative URLs (#37341)
Previously, we would simply prepend any relative URL with the HREF
for the current route (pulled from document.location). However,
this does not correctly account for the leading slash URLs that
would otherwise be parsed correctly in the browser, or the
presence of a base HREF in the DOM.

Therefore, we use the built-in URL implementation for NodeJS,
which implements the WHATWG standard that's used in the browser.
We also pull the base HREF from the DOM, falling back on the full
HREF as the browser would, to form the correct request URL.

Fixes #37314

PR Close #37341
2020-06-09 08:27:00 -07:00
Lars Gyrup Brink Nielsen
7edb026619 fix(common): prevent duplicate URL change notifications (#37459)
Prevent duplicate notifications from being emitted when multiple URL change listeners are registered using SpyLocation#onUrlChange.

Use `@internal` annotation for the `_urlChangeSubscription` properties instead of the `private` access modifier. Otherwise, we get in trouble because of  `SpyLocation implements Location`.

PR Close #37459
2020-06-09 08:26:34 -07:00
Lars Gyrup Brink Nielsen
0b7845964b test(common): prefer TestBed.inject over inject (#37459)
Use the strongly typed TestBed.inject rather than the weakly typed inject test utility function. Reuse injected dependency variables between sibling test cases.

PR Close #37459
2020-06-09 08:26:34 -07:00
Ayaz Hafiz
55979fe0ae feat(language-service): TS references from template items (#37437)
Keen and I were talking about what it would take to support getting
references at a position in the current language service, since it's
unclear when more investment in the Ivy LS will be available. Getting TS
references from a template is trivial -- we simply need to get the
definition of a symbol, which is already handled by the language
service, and ask the TS language service to give us the references for
that definition.

This doesn't handle references in templates, but that could be done in a
subsequent pass.

Part of https://github.com/angular/vscode-ng-language-service/issues/29

PR Close #37437
2020-06-08 17:23:49 -07:00
Keen Yee Liau
6280cf95b4 fix(language-service): Improve signature selection by finding exact match (#37494)
The function signature selection algorithm is totally naive. It'd
unconditionally pick the first signature if there are multiple
overloads. This commit improves the algorithm by returning an exact
match if one exists.

PR Close #37494
2020-06-08 17:23:12 -07:00
Andrew Scott
8d817daf78 fix(router): Fix relative link generation from empty path components (#37446)
Partial resubmit of #26243
Fixes incorrect url tree generation for empty path components with children.
Adds a test to demonstrate the failure of createUrlTree for those routes.
Fixes #13011
Fixes #35687

PR Close #37446
2020-06-08 17:15:37 -07:00
atscott
946f1179e9 docs: release notes for the v10.0.0-rc.3 release
This commit contains the release notes from the 10.0.0-rc.3 release. They were copy-pasted from the CHANGELOG in the 10.0.x branch.
2020-06-08 17:13:37 -07:00
Ajit Singh
87fdd23157 docs: add note on publishing libraries in ivy (#36556)
Libraries are still build using view engine even after Ivy being the default engine for building angular apps. Added note on why libraries are built using VE and how they will be automatically compiled in Ivy using ngcc making it compatible for both

Fixes #35625

PR Close #36556
2020-06-08 15:05:51 -07:00
Gerald Lang
713fb3b587 docs(docs-infra): fix small typo (#37258)
The style guide docs had a typo "Alerts and Calllouts". Callouts is
spelled with two l's, not three. This PR fixes the typo.

PR Close #37258
2020-06-08 14:42:49 -07:00
ajitsinghkaler
0cb0f66c17 docs: place download section in toh to the top (#36567)
this is part of a larger effort to standardise download sections on angular.io

This commit partially addresses #35459

PR Close #36567
2020-06-08 11:41:52 -07:00
Ajit Singh
db11a0ddbf docs(service-worker): add staleWhileRevalidate strategy (#37301)
There is great workaround for implementing staleWhileRevalidate strategy in service-worker by setting strategy to freshness and timeout to 0u. Documented this in service worker config where all other strategies are documented

Fixes #20402

PR Close #37301
2020-06-08 11:41:20 -07:00
Andrew Scott
779344012a refactor(core): assert TNode is not a container when setting attribute on element (#37111)
This PR provides a more helpful error than the one currently present:
`el.setAttribute is not a function`. It is not valid to have directives with host bindings
on `ng-template` or `ng-container` nodes. VE would silently ignore this, while Ivy
attempts to set the attribute and throws an error because these are comment nodes
and do not have `setAttribute` functionality.

It is better to throw a helpful error than to silently ignore this because
putting a directive with host binding on an `ng-template` or `ng-container` is most often a mistake.
Developers should be made aware that the host binding will have no effect in these cases.

Note that an error is already thrown in Ivy, as mentioned above, so this
is not a breaking change and can be merged to both master and patch.

Resolves #35994

PR Close #37111
2020-06-08 11:21:05 -07:00
Keen Yee Liau
650974e1b3 test(language-service): Remove all markers from test project (#37475)
This commit removes all markers from the inline template in
`AppComponent` and external template in `TemplateReference`.

Test scenarios should be colocated with the test cases themselves.
Besides, many existing cases are invalid. For example, if we want to
test autocomplete for HTML element, the existing test case is like:
```
<~{cursor} h1>
```
This doesn't make much sense, becasue the language service already sees
the `h1` tag in the template. The correct test case should be:
```
<~{cursor
```
IMO, this reflects the real-world use case better.

This commit also uncovers a bug in the way HTML entities autocompletion
is done. There's an off-by-one error in which a cursor that immediately
trails the ampersand character fails to trigger HTML entities
autocompletion.

PR Close #37475
2020-06-08 10:25:42 -07:00
Joey Perrott
ed3c549063 ci: remove IgorMinar from reviewers list for pullapprove fallback group (#36456)
Historically we have had a pullapprove group `fallback` which acted as
a catch all for files which did not match any other groups.  This
group assigned reviews to IgorMinar, however it was not apparent that
this group was assigned.  This change removes this assignment.  This
group as active should always coincide with failures of the pullapprove
verification script. We continue to have this group as a secondary test
ensuring all files in the repo are captured by the pullapprove config.

PR Close #36456
2020-06-08 10:07:45 -07:00
George Kalpakas
3a116179b1 build(docs-infra): upgrade cli command docs sources to b76099083 (#37471)
Updating [angular#master](https://github.com/angular/angular/tree/master) from [cli-builds#master](https://github.com/angular/cli-builds/tree/master).

##
Relevant changes in [commit range](89dbc2caa...b76099083):

**Modified**
- help/generate.json

PR Close #37471
2020-06-08 09:33:52 -07:00
Pete Bacon Darwin
5e64c2b1df style(ngcc): post-merge review tidy up (#37461)
This commit tidies up a few of the code comments from a recent commit to
help improve the clarity of the algorithm.

PR Close #37461
2020-06-08 09:32:11 -07:00
Adrien Vergé
d63ecf4c5f fix(service-worker): Don't stay locked in EXISTING_CLIENTS_ONLY if corrupted data (#37453)
**Problem**

After #31109 and #31865, it's still possible to get locked in state
`EXISTING_CLIENTS_ONLY`, without any possibility to get out (even by
pushing new updates on the server).
More specifically, if control doc `/latest` of `ngsw:/:db:control` once
gets a bad value, then the service worker will fail early, and won't be
able to overwrite `/latest` with new, valid values (the ones from future
updates).

For example, once in this state, URL `/ngsw/state` will show:

    NGSW Debug Info:
    Driver state: EXISTING_CLIENTS_ONLY (Degraded due to failed initialization: Invariant violated (initialize): latest hash 8b75… has no known manifest
    Error: Invariant violated (initialize): latest hash 8b75… has no known manifest
        at Driver.<anonymous> (https://my.app/ngsw-worker.js:2302:27)
        at Generator.next (<anonymous>)
        at fulfilled (https://my.app/ngsw-worker.js:175:62))
    Latest manifest hash: 8b75…
    Last update check: 22s971u

... with hash `8b75…` corresponding to no installed version.

**Solution**

Currently, when such a case happens, the service worker [simply fails
with an assertion][1]. Because this failure happens early, and is not
handled, the service worker is not able to update `/latest` to new
installed app versions.

I propose to detect this corrupted case (a `latest` hash that doesn't
match any installed version) a few lines above, so that the service
worker can correctly call its [already existing cleaning code][2].

[1]: https://github.com/angular/angular/blob/3569fdf/packages/service-worker/worker/src/driver.ts#L559-L563
[2]: https://github.com/angular/angular/blob/3569fdf/packages/service-worker/worker/src/driver.ts#L505-L519

This change successfully fixes the problem described above.

Unit test written with the help of George Kalpakas. Thank you!

PR Close #37453
2020-06-08 09:31:34 -07:00
Wagner Maciel
77efddcac3 fix(dev-infra): await setup in runBenchmark (#37428)
* Fix for issue #36986.
* Changes runBenchmark into an async function.
* Awaits config.setup in runBenchmark.

PR Close #37428
2020-06-08 09:17:34 -07:00
Greg Magolan
d887ba85ad build: update to latest stable Chromium 83.0.4103 in both rules_webtesting and puppeteer (#37427)
Also added in detailed instructions of the process to determine the URLs corresponding to Chromium version desired

PR Close #37427
2020-06-08 09:16:40 -07:00
Joey Perrott
0c75a06b1e build: upgrade to bazel 3.2.0 and rules_nodejs 1.7.0 (#37358)
Upgrade to rely on bazel version 3.2.0 and rules_nodejs 1.7.0.  This
is part of a routine update as new versions become available.

PR Close #37358
2020-06-08 09:15:50 -07:00
Igor Minar
aaa20093b2 ci: special case tooling-cli-shared-api review group (#37467)
The new tooling-cli-shared-api is used to guard changes to packages/compiler-cli/src/tooling.ts
which is a private API sharing channel between Angular FW and CLI.

Changes to this file should be rare and explicitly approved by at least two members
of the CLI team.

PR Close #37467
2020-06-05 19:23:52 -07:00
Igor Minar
5568d824dd ci: extend and update the reviewer groups (#37467)
Update the pullapprove config to require multiple reviews for sensitive groups in order
to force distribution of knowledge and improve the review quality.

PR Close #37467
2020-06-05 19:23:52 -07:00
Paul Gschwendtner
17996bf719 fix(dev-infra): properly determine oauth scopes for git client token (#37462)
Resubmit of b2bd38699b0595d0a35b501f20251f8715a9fd1c since
85b6c94cc6d4dd1cfae68fc14575d0efa57574b3 accidentally reverted
the fix due to rebasing most likely.

PR Close #37462
2020-06-05 11:04:36 -07:00
George Kalpakas
2a330a60ed fix(elements): fire custom element output events during component initialization (#36161)
Previously, event listeners for component output events attached on an
Angular custom element before inserting it into the DOM (i.e. before
instantiating the underlying component) didn't fire for events emitted
during initialization lifecycle hooks, such as `ngAfterContentInit`,
`ngAfterViewInit`, `ngOnChanges` (initial call) and `ngOnInit`.
The reason was that that `NgElementImpl` [subscribed to events][1]
_after_ calling [ngElementStrategy#connect()][2], which is where the
[initial change detection][3] takes place (running the initialization
lifecycle hooks).

This commit fixes this by:
1. Ensuring `ComponentNgElementStrategy#events` is defined and available
   for subscribing to, even before instantiating the component.
2. Ensuring `NgElementImpl` subscribes to `NgElementStrategy#events`
   before calling `NgElementStrategy#connect()` (which initializes the
   component instance).

Jira issue: [FW-2010](https://angular-team.atlassian.net/browse/FW-2010)

[1]: c0143cb2ab/packages/elements/src/create-custom-element.ts (L167-L170)
[2]: c0143cb2ab/packages/elements/src/create-custom-element.ts (L164)
[3]: c0143cb2ab/packages/elements/src/component-factory-strategy.ts (L158)

Fixes #36141

PR Close #36161
2020-06-05 10:36:39 -07:00
George Kalpakas
569d1ef583 refactor(elements): remove unnecessary non-null assertions and as any type-casts (#36161)
This commit removes some unnecessary non-null assertions (`!`) and
`as any` type-casts from the `elements` package.

PR Close #36161
2020-06-05 10:36:39 -07:00
Joey Perrott
85b6c94cc6 refactor(dev-infra): move GitClient to common util (#37318)
Moves GitClient from merge script into common utils for unified
method of performing git actions throughout the ng-dev toolset.

PR Close #37318
2020-06-05 09:46:40 -07:00
Pete Bacon Darwin
818d93d7e9 fix(ngcc): find decorated constructor params on IIFE wrapped classes (#37436)
Now in TS 3.9, classes in ES2015 can be wrapped in an IIFE.
This commit ensures that we still find the static properties that contain
decorator information, even if they are attached to the adjacent node
of the class, rather than the implementation or declaration.

Fixes #37330

PR Close #37436
2020-06-05 09:22:04 -07:00
George Kalpakas
d4c0962c7b refactor(dev-infra): use the exec() helper from utils/shelljs whenever possible (#37444)
There is an `exec()` helper provided by `utils/shelljs.ts`, which is a
wrapper around ShellJS' `exec()` with some default options (currently
`silent: true`). The intention is to avoid having to pass these options
to every invocation of the `exec()` function.

This commit updates all code inside `dev-infra/` to use this helper
whenever possible).

NOTE: For simplicity, the `utils/shelljs` helper does not support some
      of the less common call signatures of the original `exec()`
      helper, so in some cases we still need to use the original.

PR Close #37444
2020-06-05 09:21:18 -07:00
Amadou Sall
e31208beb1 docs: fix minor error in the "Structural directives" guide (#37452)
The sample code used in this guide uses [class.od]="odd".
But, in another portion of the guide, [ngClass]="odd" is mentioned instead.

PR Close #37452
2020-06-05 09:20:43 -07:00
Lars Gyrup Brink Nielsen
3569fdf451 fix(common): prevent duplicate URL change notifications (#37404)
Prevent duplicate notifications from being emitted when multiple URL change listeners are registered using Location#onUrlChange.

PR Close #37404
2020-06-04 16:45:06 -07:00
Igor Minar
eb6ba9ac80 docs: fix various typos (#37443)
This change just fixes various typos and misspellings across several docs.

I've included also a fix for an issue surfaced via #37423.

Closes #37423

PR Close #37443
2020-06-04 16:03:54 -07:00
Joey Perrott
4e7a4543b8 style(dev-infra): correct tslint failures in dev-infra directory (#37233)
Fixes tslint failures in dev-infra directory as the directory is now
part of the tslint enforced files.

PR Close #37233
2020-06-04 12:44:46 -07:00
Joey Perrott
753fed285c build: add dev-infra to tslint selected files (#37233)
Adds the dev-infra files to the scope of files on which tslint is
enforced.  This will allow for better code management/conformance.

PR Close #37233
2020-06-04 12:44:46 -07:00
Joey Perrott
dffcca73e4 fix(dev-infra): clean up usages within pullapprove tooling (#37338)
Clean up pullapprove tooling to use newly created common utils.
Additionally, use newly created logging levels rather than
verbose flagging.

PR Close #37338
2020-06-04 12:43:44 -07:00
Andrew Scott
c8f7fc22c7 refactor(dev-infra): change required base commit sha (#37424)
Update the commit sha to require that PRs have been rebased beyond the one which has new header requirements so we don't get failures after merging

PR Close #37424
2020-06-04 10:44:14 -07:00
Paul Gschwendtner
b2bd38699b fix(dev-infra): properly determine oauth scopes for git client token (#37439)
We recently added a better reporting mechanism for oauth tokens
in the dev-infra git util. Unfortunately the logic broke as part
of addressing PR review feedback. Right now, always the empty
promise from `oauthScopes` will be used as `getAuthScopes` considers
it as the already-requested API value. This is not the case as
the default promise is also truthy. We should just fix this by making
the property nullable.

PR Close #37439
2020-06-04 10:42:53 -07:00
Joey Perrott
c025357fb8 feat(dev-infra): Add oauth scope check to ensure necessary permissions for merge tooling (#37421)
Adds an assertion that the provided TOKEN has OAuth scope permissions for `repo`
as this is required for all merge attempts.

On failure, provides detailed error message with remediation steps for the user.

PR Close #37421
2020-06-04 09:35:59 -07:00
Pete Bacon Darwin
57411c85b9 feat(ngcc): implement a program-based entry-point finder (#37075)
This finder is designed to only process entry-points that are reachable
by the program defined by a tsconfig.json file.

It is triggered by calling `mainNgcc()` with the `findEntryPointsFromTsConfigProgram`
option set to true. It is ignored if a `targetEntryPointPath` has been
provided as well.

It is triggered from the command line by adding the `--use-program-dependencies`
option, which is also ignored if the `--target` option has been provided.

Using this option can speed up processing in cases where there is a large
number of dependencies installed but only a small proportion of the
entry-points are actually imported into the application.

PR Close #37075
2020-06-04 09:22:39 -07:00
Pete Bacon Darwin
07a8016118 fix(ngcc): capture dynamic import expressions as well as declarations (#37075)
Previously we only checked for static import declaration statements.
This commit also finds import paths from dynamic import expressions.

Also this commit should speed up processing: Previously we were parsing
the source code contents into a `ts.SourceFile` and then walking the parsed
AST to find import paths.
Generating an AST is unnecessary work and it is faster and creates less
memory pressure to just scan the source code contents with the TypeScript
scanner, identifying import paths from the tokens.

PR Close #37075
2020-06-04 09:22:39 -07:00
Pete Bacon Darwin
4d69da57ca refactor(ngcc): move shared code into DependencyHostBase (#37075)
The various dependency hosts had a lot of duplicated code.
This commit refactors them to move this into the base class.

PR Close #37075
2020-06-04 09:22:39 -07:00
Pete Bacon Darwin
7f98b87ca0 fix(ngcc): ensure that more dependencies are found by EsmDependencyHost (#37075)
Previously this host was skipping files if they had imports that spanned
multiple lines, or if the import was a dynamic import expression.

PR Close #37075
2020-06-04 09:22:39 -07:00
Alan Agius
c61decf7e5 docs: add blank line before header (#37391)
Currently, `Formatting your source code` is not being formatted as a header because of a missing empty line.
PR Close #37391
2020-06-04 09:20:26 -07:00
Pete Bacon Darwin
6e7bd939f6 perf(ngcc): cache parsed tsconfig between runs (#37417)
This commit will store a cached copy of the parsed tsconfig
that can be reused if the tsconfig path is the same.

This will improve the ngcc "noop" case, where there is no processing
to do, when the entry-points have already been processed.
Previously we were parsing this config every time we checked for
entry-points to process, which can take up to seconds in some
cases.

Resolves #36882

PR Close #37417
2020-06-04 09:19:38 -07:00
George Kalpakas
2021ad12cf ci(docs-infra): skip deploying RC version when lexicographically smaller than stable (#37426)
The angular.io production deployment script (`deploy-to-firebase.sh`)
compares the major version corresponding to the current branch (e.g.
`8` for branch `8.1.x`) against the major stable version (e.g. `9` if
the current stable version is `9.1.0`). It then uses the result of that
comparison to determine whether the current branch corresponds to a
newer version than stable (i.e. an RC version) and thus should not be
deployed or to an older version and thus may need to be deployed to an
archive vX.angular.io project.

Previously, the script was using string comparison (`<`) to compare the
two major versions. This could produce incorrect results for an RC major
version that is numerically greater than the stable but
lexicographically smaller. For example, 10 vs 9 (10 is numerically
greater but lexicographically smaller than 9).
Example of a CI job that incorrectly tried to deploy an RC branch to
production: https://circleci.com/gh/angular/angular/726414

This commit fixes it by switching to an integer comparison (i.e. using
the `-lt` operator).

PR Close #37426
2020-06-04 09:17:29 -07:00
Ayaz Hafiz
c4f4675ebf fix(language-service): Recover from error in analyzing Ng Modules (#37108)
In place of failing to return analyzed Ng Modules when the analyzer
fails, return the previously-analyzed Ng Modules (which may be empty)
and log an error.

Closes https://github.com/angular/vscode-ng-language-service/issues/777

PR Close #37108
2020-06-03 15:56:19 -07:00
Sonu Kapoor
34827559b9 docs: update the stackblitz in the GitHub Issue template (#37219)
This commit updates the bug report stackblitz template for opening a new
issue based on the current angular release.

Closes #37063

PR Close #37219
2020-06-03 15:55:44 -07:00
Andrew Scott
65c3888d01 docs: update file header to be correct (#37425)
The file header should be Google LLC rather than Google Inc. because it is now an LLC after Alphabet Holdings was formed.

PR Close #37425
2020-06-03 15:31:29 -07:00
Alex Rickabaugh
e648a0c4ca refactor(compiler-cli): extract NgCompilerAdapter interface (#37118)
`NgCompiler` is the heart of ngtsc and can be used to analyze and compile
Angular programs in a variety of environments. Most of these integrations
rely on `NgProgram` and the creation of an `NgCompilerHost` in order to
create a `ts.Program` with the right shape for `NgCompiler`.

However, certain environments (such as the Angular Language Service) have
their own mechanisms for creating `ts.Program`s that don't make use of a
`ts.CompilerHost`. In such environments, an `NgCompilerHost` does not make
sense.

This commit breaks the dependency of `NgCompiler` on `NgCompilerHost` and
extracts the specific interface of the host on which `NgCompiler` depends
into a new interface, `NgCompilerAdapter`. This interface includes methods
from `ts.CompilerHost`, the `ExtendedTsCompilerHost`, as well as APIs from
`NgCompilerHost`.

A consumer such as the language service can implement this API without
needing to jump through hoops to create an `NgCompilerHost` implementation
that somehow wraps its specific environment.

PR Close #37118
2020-06-03 13:29:44 -07:00
Alex Rickabaugh
965a688c97 fix(compiler-cli): use ModuleWithProviders type if static eval fails (#37126)
When the compiler encounters a function call within an NgModule imports
section, it attempts to resolve it to an NgModule-annotated class by
looking at the function body and evaluating the statements there. This
evaluation can only understand simple functions which have a single
return statement as their body. If the function the user writes is more
complex than that, the compiler won't be able to understand it and
previously the PartialEvaluator would return a "DynamicValue" for
that import.

With this change, in the event the function body resolution fails the
PartialEvaluator will now attempt to use its foreign function resolvers to
determine the correct result from the function's type signtaure instead. If
the function is annotated with a correct ModuleWithProviders type, the
compiler will be able to understand the import without static analysis of
the function body.

PR Close #37126
2020-06-03 13:23:16 -07:00
crisbeto
ab3f4c9fe1 fix(core): infinite loop if injectable using inheritance has a custom decorator (#37022)
If we detect that an injectable class is inheriting from another injectable, we generate code that looks something like this:

```
const baseFactory = ɵɵgetInheritedFactory(Child);

@Injectable()
class Parent {}

@Injectable()
class Child extends Parent {
  static ɵfac = (t) => baseFactory(t || Child)
}
```

This usually works fine, because the `ɵɵgetInheritedFactory` resolves to the factory of `Parent`, but the logic can break down if the `Child` class has a custom decorator. Custom decorators can return a new class that extends the original once, which means that the `ɵɵgetInheritedFactory` call will now resolve to the factory of the `Child`, causing an infinite loop.

These changes fix the issue by changing the inherited factory resolution logic so that it walks up the prototype chain class-by-class, while skipping classes that have the same factory as the class that was passed in.

Fixes #35733.

PR Close #37022
2020-06-03 13:16:25 -07:00
Wagner Maciel
40f3bb5638 refactor(dev-infra): small changes and fixes (#36800)
Rename bazel workspace from npm_dev_infra to npm_angular_dev_infra_private to make it clear that this package is private to angular.
Change driver-utilities module_name to match the new bazel workspace name.
Correct a comment by rewording it from "deployed version" to "published version".
Fix merge conflicts in tmpl-package.json
Make "//packages/bazel/src:esm5.bzl" replacement more generalized so that importing from "//packages/bazel" works.
Deleted "dev_infra/*" path from modules/benchmarks tsconfig.
Moved //dev-infra/benchmark/browsers to //dev-infra/browsers.

PR Close #36800
2020-06-03 13:12:30 -07:00
Wagner Maciel
a08d18a1fe revert: "revert: "build(core): use dev-infra's component_benchmark to show PoC (#36434)" (#36798)" (#36800)
This reverts commit 90a2796a7e20eda6a6c8afd10c79b36d75640cdf.

PR Close #36800
2020-06-03 13:12:30 -07:00
Wagner Maciel
64d6f35f94 revert: "revert: "build(dev-infra): update package.json and :npm_package (#36434)" (#36798)" (#36800)
This reverts commit f5ff2068a48f60c747c2936908e848d301f4dba4.

PR Close #36800
2020-06-03 13:12:30 -07:00
Wagner Maciel
caa4ab3235 revert: "revert: "feat(dev-infra): exposed new rule 'component_benchmark' via dev_infra (#36434)" (#36798)" (#36800)
This reverts commit ad8c4cdd752d310316e8fc019f21855701c3a950.

PR Close #36800
2020-06-03 13:12:30 -07:00
lazarljubenovic
06a8ad28a7 refactor(forms): use a type guard to get rid of casts (#32541)
Use an explicit type guard when checking if a given object is of type AbstractControlOptions,
instead of a simple function returning a boolean value. This allows us to remove manual type
casting when using this function, relying instead on TypeScript to infer correct types.

PR Close #32541
2020-06-03 12:29:26 -07:00
Judy Bogart
382aa50c54 docs: refactor template-driven forms doc as a tutorial (#36732)
rework content to meet current documentation standards and conventions, structure as tutorial document type

PR Close #36732
2020-06-03 12:27:28 -07:00
Joey Perrott
044a19966d ci: temporarily disable Android 10 browser unit tests on Saucelabs (#37399)
Disabling Android 10 browser unit tests on Saucelabs due to errors.

After remediation from Saucelabs to correct the discovered failures, this change can be reverted to renable the tests on Android 10.

Example of failures seen:

```
02 06 2020 14:03:05.048:INFO [SaucelabsLauncher]: Chrome 10.0 (Android) session at https://saucelabs.com/tests/54f5fb181db644a3b4779187c2309000

02 06 2020 14:03:06.869:INFO [Chrome Mobile 74.0.3729 (Android 0.0.0)]: Disconnected browser returned on socket E-bi0p0NKtghk-HcAAAO with id 85563367.

Chrome Mobile 74.0.3729 (Android 0.0.0) ERROR: Error: XHR error loading http://angular-ci.local:9876/base/node_modules/rxjs/internal/operators/zip.js

	Error loading http://angular-ci.local:9876/base/node_modules/rxjs/internal/operators/zip.js as "../internal/operators/zip" from http://angular-ci.local:9876/base/node_modules/rxjs/operators/index.js

Error: XHR error loading http://angular-ci.local:9876/base/node_modules/rxjs/internal/operators/zip.js

    at error (http://angular-ci.local:9876/base/node_modules/systemjs/dist/system.src.js?1c6a6c12fec50a8db7aeebe8e06e2b70135c0615:1028:16)

    at XMLHttpRequest.xhr.onreadystatechange [as __zone_symbol__ON_PROPERTYreadystatechange] (http://angular-ci.local:9876/base/node_modules/systemjs/dist/system.src.js?1c6a6c12fec50a8db7aeebe8e06e2b70135c0615:1036:13)

    at XMLHttpRequest.wrapFn (http://angular-ci.local:9876/base/dist/bin/packages/zone.js/npm_package/dist/zone.js?942d01da94828e1c75e8527fa8d06f363d6379ce:809:43)

    at ZoneDelegate.invokeTask (http://angular-ci.local:9876/base/dist/bin/packages/zone.js/npm_package/dist/zone.js?942d01da94828e1c75e8527fa8d06f363d6379ce:432:35)

    at Zone.runTask (http://angular-ci.local:9876/base/dist/bin/packages/zone.js/npm_package/dist/zone.js?942d01da94828e1c75e8527fa8d06f363d6379ce:201:55)

    at ZoneTask.invokeTask [as invoke] (http://angular-ci.local:9876/base/dist/bin/packages/zone.js/npm_package/dist/zone.js?942d01da94828e1c75e8527fa8d06f363d6379ce:514:38)

    at invokeTask (http://angular-ci.local:9876/base/dist/bin/packages/zone.js/npm_package/dist/zone.js?942d01da94828e1c75e8527fa8d06f363d6379ce:1722:18)

    at XMLHttpRequest.globalZoneAwareCallback (http://angular-ci.local:9876/base/dist/bin/packages/zone.js/npm_package/dist/zone.js?942d01da94828e1c75e8527fa8d06f363d6379ce:1748:21)
```

PR Close #37399
2020-06-02 17:32:34 -04:00
Kara Erickson
17e98198f4 docs(core): remove v10 mention from @Injectable warning (#37383)
In v9, we started showing a console warning when
instantiating a token that inherited its @Injectable
decorator rather than providing its own. This warning
said that the pattern would become an error in v10.

However, we have decided to wait until at least v11
to throw in this case, so this commit updates the
warning to be less prescriptive about the exact
version when the pattern will no longer be supported.

PR Close #37383
2020-06-02 17:30:58 -04:00
Terence D. Honles
561c0f81a0 perf(ngcc): allow immediately reporting a stale lock file (#37250)
Currently, if an ngcc process is killed in a manner that it doesn't clean
up its lock file (or is killed too quickly) the compiler reports that it
is waiting on the PID of a process that doesn't exist, and that it will
wait up to a maximum of N seconds. This PR updates the locking code to
additionally check if the process exists, and if it does not it will
immediately bail out, and print the location of the lock file so a user
may clean it up.

PR Close #37250
2020-06-02 17:30:03 -04:00
Judy Bogart
4414be77c4 docs: refactor forms overview (#36919)
Reorganize and edit content of existing form overview to conform to current doc standards and styles

PR Close #36919
2020-06-02 17:29:15 -04:00
Matias Niemelä
1b55da10b1 build: fix integration payload sizes 2020-06-02 10:51:06 -07:00
Markus Ende
78ea2527a1 docs(router): fix a typo in example code (#37309)
The code in the example docs used TestBed.configureTestModule instead of TestBed.configureTestingModule.

PR Close #37309
2020-06-01 17:19:45 -04:00
Andrew Scott
4456e7e4de refactor(core): remove looseIdentical in favor of built-in Object.is (#37191)
Remove `looseIdentical` implementation and instead use the ES2015 `Object.is` in its place.
They behave exactly the same way except for `+0`/`-0`.
`looseIdentical(+0, -0)` => `true`
`Object.is(+0, -0)` => `false`

Other than the difference noted above, this is not be a breaking change because:
1. `looseIdentical` is a private API
2. ES2015 is listed as a mandatory polyfill in the [browser support
guide](https://angular.io/guide/browser-support#mandatory-polyfills)
3. Also note that `Ivy` already uses `Object.is` in `bindingUpdated`.

PR Close #37191
2020-06-01 17:19:17 -04:00
Keen Yee Liau
92c436dd1a test(language-service): disable ivy ls tests on CI (#37348)
This commit disables the tests for Ivy version of language service on CI
because the compiler APIs are not yet stable, so language service should
not assert against its behavipr.

PR Close #37348
2020-06-01 17:18:51 -04:00
Pete Bacon Darwin
b45f336635 fix(ngcc): do not inline source-maps for non-inline typings source-maps (#37363)
Inline source-maps in typings files can impact IDE performance
so ngcc should only add such maps if the original typings file
contains inline source-maps.

Fixes #37324

PR Close #37363
2020-06-01 17:18:31 -04:00
AleksanderBodurri
c3651cec0b docs(core): fix typo in decorators.ts relating to the use of Object.defineProperty. (#37369)
Previously there was a typo in a comment within the PropDecorator function relating to and justifying the use of Object.defineProperty. This PR clears up the wording that comment

PR Close #37369
2020-06-01 17:18:08 -04:00
Andrew Scott
3b52f7066b docs: fix typo in deprecations (#37379)
This PR fixes a typo in the deprecations guide, changing 'dropped support for of Windows 10...' to 'dropped support for Windows 10...'

PR Close #37379
2020-06-01 17:17:44 -04:00
Matias Niemelä
8bb741198b docs: release notes for the v10.0.0-rc.2 release 2020-06-01 11:14:39 -07:00
Joey Perrott
26849ca99d build: remove wombot proxy registry from package.jsons for release (#37378)
Due to an outage with the proxy we rely on for publishing, we need
to temporarily directly publish to NPM using our own angular
credentials again.

PR Close #37378
2020-06-01 12:41:19 -04:00
Igor Minar
4d0e175a65 fix(core): reenable decorator downleveling for Angular npm packages (#37317)
In #37221 we disabled tsickle passes from transforming the tsc output that is used to publish all
Angular framework and components packages (@angular/*).

This change however revealed a bug in the ngc that caused __decorate and __metadata calls to still
be emitted in the JS code even though we don't depend on them.

Additionally it was these calls that caused code in @angular/material packages to fail at runtime
due to circular dependency in the emitted decorator code documeted as
https://github.com/microsoft/TypeScript/issues/27519.

This change partially rolls back #37221 by reenabling the decorator to static fields (static
properties) downleveling.

This is just a temporary workaround while we are also fixing root cause in `ngc` - tracked as
FW-2199.

Resolves FW-2198.
Related to FW-2196

PR Close #37317
2020-05-29 18:52:01 -04:00
Keen Yee Liau
bd7393fc68 docs: Mention Bazel builder and schematics in Deprecations section (#37190)
This commit adds Bazel builder and schematics to the global list of
deprecations in Angular. A link to the migration doc is added.

PR Close #37190
2020-05-28 21:35:40 -04:00
Keen Yee Liau
08ff8aa055 docs(bazel): Mention Architect prototype and Slack Channel (#37190)
This commit adds a link to the Bazel prototype for orchestrating
multiple CLI architects and also adds a link to the #angular channel in
the Bazel Slack workspace.

PR Close #37190
2020-05-28 21:35:40 -04:00
Keen Yee Liau
f60d159d71 docs: Cleanup Bazel schematics deprecation doc (#37190)
This commit improves some wording in the deprecation doc for Bazel
builder and schematics in `@angular/bazel` and fixes the formatting.

PR Close #37190
2020-05-28 21:35:40 -04:00
Keen Yee Liau
6aa5bfa21a refactor(bazel): Remove schematics and builder from package.json (#37190)
This commit removes the fields for ng-add, schematics and builder from
package.json of `@angular/bazel`.

PR Close #37190
2020-05-28 21:35:40 -04:00
Keen Yee Liau
227ba625e6 docs: Add guide/bazel to Service Worker navigationUrls (#37190)
This commit adds an exception for "guide/bazel" to the navigationUrls in
the Service Worker config. This is needed for redirection to work.

PR Close #37190
2020-05-28 21:35:40 -04:00
Keen Yee Liau
e64176019a docs: Redirect /guide/bazel to deprecation doc in Angular repo (#37190)
This commit adds a 301 redirect for /guide/bazel on angular.io to the
deprecation doc for Angular Bazel schematics in Angular repo.

PR Close #37190
2020-05-28 21:35:40 -04:00
Keen Yee Liau
1fc7891add test: remove Bazel schematics integration test (#37190)
This commit removes the integration test for schematics in
`@angular/bazel` that is used to generate a Bazel builder. The Bazel
builder has been deprecated.

PR Close #37190
2020-05-28 21:35:40 -04:00
Keen Yee Liau
e7930fcc15 ci: Remove aio/content/guide/bazel.md from pullapprove (#37190)
This commit removes aio/content/guide/bazel.md from the Bazel list in
pullapprove since Bazel builder has been deprecated and the doc has been
deleted.

PR Close #37190
2020-05-28 21:35:40 -04:00
Keen Yee Liau
4b40740324 docs: Remove 'Building with Bazel' section (#37190)
This commit removes "Building with Bazel" section from angular.io
navigation list and Angular CLI landing page.

PR Close #37190
2020-05-28 21:35:40 -04:00
Keen Yee Liau
a36667d984 refactor(bazel): Remove Schematics for Bazel Builder (#37190)
This commit removes `ng-add` and `ng-new` schematics for the Bazel
Builder, and update the corresponding BUILD files.

PR Close #37190
2020-05-28 21:35:40 -04:00
Keen Yee Liau
9791c9ecaf docs: Remove Bazel builder from @angular/bazel (#37190)
This commit adds a deprecation doc for Bazel builder in
`@angular/bazel` and removes the corresponding guide in angular.io.

PR Close #37190
2020-05-28 21:35:39 -04:00
JiaLiPassion
df082307b9 docs: fix typo in committer.md (#37171)
Fix a type of COMMITTER.md, the url of the pullapprove service should be https://docs.pullapprove.com/,
now the document has an additional `https` prefix.

PR Close #37171
2020-05-28 18:43:05 -04:00
Adam
98d820030c docs(platform-server): fix renderModule usage guidance with Ivy (#37296)
Before the introduction of the Ivy renderer, users would compile
their applications and use the resulting factories for SSR, since
these post-compilation artifacts ensured faster delivery. Thus,
using the original module as the rendering entrypoint was
considered suboptimal and was discouraged.

However, with the introduction of Ivy, this guidance is no longer
applicable since these factories are no longer generated.
Comparable speed is achieved using the factory-less module
renderer, and so we update the guiance in the docs for the method.

PR Close #37296
2020-05-28 16:07:32 -04:00
Joey Perrott
f001aef2dc build: update requiredBaseCommit for patch branch merges (#37316)
Updates the requiredBaseCommit for merging to patch branch to the
latest commit message validation fix found in the 10.0.x branch.

Previously, the patch branch commit used was for the 9.1.x branch.

PR Close #37316
2020-05-28 16:06:08 -04:00
Andrew Scott
64fc8b8ee5 docs: add IE mobile to deprecated browsers (#37313)
Mobile versions of IE should also be deprecated, as the same reasons for deprecating IE 9 and 10 apply.

PR Close #37313
2020-05-27 17:23:18 -04:00
Joey Perrott
a62c1c441c build: migrate ng-dev config to .ng-dev directory (#37142)
Migrate to using .ng-dev directory for ng-dev configuration to allow
better management of the configuration using multiple files.  The
intention is to prevent the config file from becoming unruly.

PR Close #37142
2020-05-26 16:38:22 -04:00
Joey Perrott
3d154ab795 fix(dev-infra): migrate dev-infra config loading to .ng-dev directory (#37142)
Migrate to using .ng-dev directory for ng-dev configuration to better
allow management of the configuration using multiple files.  The
intention is to prevent the config file from becoming unruly.

PR Close #37142
2020-05-26 16:38:22 -04:00
Joey Perrott
d1ea1f4c7f build: update license headers to reference Google LLC (#37205)
Update the license headers throughout the repository to reference Google LLC
rather than Google Inc, for the required license headers.

PR Close #37205
2020-05-26 14:26:58 -04:00
Joey Perrott
5aeb9a4124 build: Update file-header lint rule to Google LLC (#37205)
Update the file-header lint rule to properly reference Google LLC
rather than Google Inc, for the required headers.

PR Close #37205
2020-05-26 14:26:58 -04:00
Joey Perrott
ecce99470a build: deprecate old merge script (#37247)
Deprecate the old merge script as it no longer correctly chooses
the patch branch due to relying on numerical sorting order from
git.  Git actually provides a lexicographical sorting order.  This
that 9.0.x will be chosen rather than 10.0.x as it is sorted based
the 9 vs 1, rather than 9 vs 10.

PR Close #37247
2020-05-26 14:25:43 -04:00
Joey Perrott
540c29cd6b feat(dev-infra): migrate release tool to use new logging system (#37232)
Migrate the release tool in ng-dev to use new logging system rather
than directly calling console.* to create a better experience
for users.

PR Close #37232
2020-05-21 17:40:35 -04:00
Joey Perrott
7827501d2a feat(dev-infra): migrate ts-circular-dependencies tool to use new logging system (#37232)
Migrate the ts-circular-dependencies tool in ng-dev to use new logging system rather
than directly calling console.* to create a better experience
for users.

PR Close #37232
2020-05-21 17:40:35 -04:00
Joey Perrott
e28f13a102 feat(dev-infra): migrate merge tool to use new logging system (#37232)
Migrate the merge tool in ng-dev to use new logging system rather
than directly calling console.* to create a better experience
for users.

PR Close #37232
2020-05-21 17:40:35 -04:00
Joey Perrott
e0002ef9ba feat(dev-infra): migrate ng-dev utils to use new logging system (#37232)
Migrate the ng-dev utils to use new logging system rather
than directly calling console.* to create a better experience
for users.

PR Close #37232
2020-05-21 17:40:35 -04:00
Joey Perrott
367f6fe12d feat(dev-infra): migrate pullapprove tool to use new logging system (#37232)
Migrate the pullapprove tool in ng-dev to use new logging system rather
than directly calling console.* to create a better experience
for users.

PR Close #37232
2020-05-21 17:40:35 -04:00
Joey Perrott
9b3ca19675 feat(dev-infra): migrate rebase tool to use new logging system (#37232)
Migrate the rebase tool in ng-dev to use new logging system rather
than directly calling console.*  to create a better experience
for users.

PR Close #37232
2020-05-21 17:40:35 -04:00
Joey Perrott
9388e47e1e feat(dev-infra): migrate discover-new-conflicts tool to use new logging system (#37232)
Migrate the discover-new-conflicts tool in ng-dev to use new logging system
rather than directly calling console.* to create a better experience
for users.

PR Close #37232
2020-05-21 17:40:35 -04:00
Joey Perrott
171d967993 feat(dev-infra): migrate commit-message tool to use new logging system (#37232)
Migrate the commit-message tool in ng-dev to use new logging system rather
than directly calling console.* to create a better experience
for users.

PR Close #37232
2020-05-21 17:40:35 -04:00
Joey Perrott
40e357411e feat(dev-infra): migrate format tool to use new logging system (#37232)
Migrate the formatting tool in ng-dev to use new logging system rather
than directly calling console.* to create a better experience
for users.

PR Close #37232
2020-05-21 17:40:35 -04:00
Joey Perrott
52c7aae4df feat(dev-infra): add group functions to logging system and remove color param (#37232)
Adds .group and .groupEnd functions to each of the logging functions
to allow creating groups in the logged output.  Additionally removes
the color parameter from logging functions, in favor of the color
being applied to the string at the call site.

PR Close #37232
2020-05-21 17:40:34 -04:00
George Kalpakas
87b1aeac0f build(docs-infra): upgrade cli command docs sources to 89dbc2caa (#37243)
Updating [angular#master](https://github.com/angular/angular/tree/master) from [cli-builds#master](https://github.com/angular/cli-builds/tree/master).

##
Relevant changes in [commit range](200a21f8a...89dbc2caa):

**Modified**
- help/generate.json

PR Close #37243
2020-05-21 17:16:05 -04:00
Joey Perrott
93be1f1543 build: use static patch value for targetting branches in merge config (#37245)
Due to the desired patch branch (10.0.x) being on a semver version
that is unreleased as stable (there is no 10.0.0 on latest, it is on
next) our logic for determining target patch branches does not work.

This change is a workaround to unblock merging in the repo while a
longer term answer is discovered.

PR Close #37245
2020-05-21 17:07:26 -04:00
Paul Gschwendtner
cdb5d07606 feat(dev-infra): expose script for determining merge branches (#37217)
The components repo and framework repository follow the same patch
branch concept. We should be able to share a script for determining
these merge branches.

Additonally the logic has been improved compared to the old merge script because
we no longer consult `git ls-remote` unless really needed. Currently,
`git ls-remote` is always consulted, even though not necessarily needed.

This can slow down the merge script and the caretaker process when a
couple of PRs are merged (personally saw around ~4 seconds per merge).

Additionally, the new logic is more strict and will ensure (in most
cases) that no wrong patch/minor branch is determined. Previously,
the script just used the lexicographically greatest patch branch.
This _could_ be wrong when a new patch branch has been created too
early, or by accident.

PR Close #37217
2020-05-21 10:35:23 -07:00
Paul Gschwendtner
3e5fa56956 fix(dev-infra): ensure ts-node is registered with commonjs as module (#37217)
We recently added support for automatic registration of `ts-node`
when the dev-infra configuration is loaded.

In addition to registering ts-node, we should also ensure that the
`commonjs` module is set up. By default, `ts-node` would use ES module
imports that are not supported by default in NodeJS.

PR Close #37217
2020-05-21 10:35:23 -07:00
887 changed files with 37840 additions and 17574 deletions

View File

@ -30,11 +30,6 @@ var_4: &cache_key_fallback v7-angular-node-12-{{ checksum ".bazelversion" }}
var_3_win: &cache_key_win v7-angular-win-node-12-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "packages/bazel/package.bzl" }}-{{ checksum "aio/yarn.lock" }} var_3_win: &cache_key_win v7-angular-win-node-12-{{ checksum ".bazelversion" }}-{{ checksum "yarn.lock" }}-{{ checksum "WORKSPACE" }}-{{ checksum "packages/bazel/package.bzl" }}-{{ checksum "aio/yarn.lock" }}
var_4_win: &cache_key_win_fallback v7-angular-win-node-12-{{ checksum ".bazelversion" }} var_4_win: &cache_key_win_fallback v7-angular-win-node-12-{{ checksum ".bazelversion" }}
# Cache key for the `components-repo-unit-tests` job. **Note** when updating the SHA in the
# cache keys also update the SHA for the "COMPONENTS_REPO_COMMIT" environment variable.
var_5: &components_repo_unit_tests_cache_key v9-angular-components-09e68db8ed5b1253f2fe38ff954ef0df019fc25a
var_6: &components_repo_unit_tests_cache_key_fallback v9-angular-components-
# Workspace initially persisted by the `setup` job, and then enhanced by `build-npm-packages` and # Workspace initially persisted by the `setup` job, and then enhanced by `build-npm-packages` and
# `build-ivy-npm-packages`. # `build-ivy-npm-packages`.
# https://circleci.com/docs/2.0/workflows/#using-workspaces-to-share-data-among-jobs # https://circleci.com/docs/2.0/workflows/#using-workspaces-to-share-data-among-jobs
@ -156,27 +151,6 @@ commands:
git config --global url."ssh://git@github.com".insteadOf "https://github.com" || true git config --global url."ssh://git@github.com".insteadOf "https://github.com" || true
git config --global gc.auto 0 || true git config --global gc.auto 0 || true
init_saucelabs_environment:
description: Sets up a domain that resolves to the local host.
steps:
- run:
name: Preparing environment for running tests on Sauce Labs.
command: |
# For SauceLabs jobs, we set up a domain which resolves to the machine which launched
# the tunnel. We do this because devices are sometimes not able to properly resolve
# `localhost` or `127.0.0.1` through the SauceLabs tunnel. Using a domain that does not
# resolve to anything on SauceLabs VMs ensures that such requests are always resolved
# through the tunnel, and resolve to the actual tunnel host machine (i.e. the CircleCI VM).
# More context can be found in: https://github.com/angular/angular/pull/35171.
setPublicVar SAUCE_LOCALHOST_ALIAS_DOMAIN "angular-ci.local"
setSecretVar SAUCE_ACCESS_KEY $(echo $SAUCE_ACCESS_KEY | rev)
- run:
# Sets up a local domain in the machine's host file that resolves to the local
# host. This domain is helpful in Sauce Labs tests where devices are not able to
# properly resolve `localhost` or `127.0.0.1` through the sauce-connect tunnel.
name: Setting up alias domain for local host.
command: echo "127.0.0.1 $SAUCE_LOCALHOST_ALIAS_DOMAIN" | sudo tee -a /etc/hosts
# Normally this would be an individual job instead of a command. # Normally this would be an individual job instead of a command.
# But startup and setup time for each individual windows job are high enough to discourage # But startup and setup time for each individual windows job are high enough to discourage
# many small jobs, so instead we use a command for setup unless the gain becomes significant. # many small jobs, so instead we use a command for setup unless the gain becomes significant.
@ -272,109 +246,8 @@ jobs:
- run: yarn -s tslint - run: yarn -s tslint
- run: yarn -s ng-dev format changed $CI_GIT_BASE_REVISION --check - run: yarn -s ng-dev format changed $CI_GIT_BASE_REVISION --check
- run: yarn -s ts-circular-deps:check - run: yarn -s ts-circular-deps:check
- run: yarn -s ng-dev pullapprove verify
- run: yarn -s ng-dev commit-message validate-range --range $CI_COMMIT_RANGE - run: yarn -s ng-dev commit-message validate-range --range $CI_COMMIT_RANGE
test:
executor:
name: default-executor
# Now that large integration tests are running locally in parallel (they can't run on RBE yet
# as they require network access for yarn install), this test is running out of memory
# consistently with the xlarge machine.
# TODO: switch back to xlarge once integration tests are running on remote-exec
resource_class: 2xlarge+
steps:
- custom_attach_workspace
- init_environment
- install_chrome_libs
- install_java
- run:
command: yarn bazel test //... --build_tag_filters=-ivy-only --test_tag_filters=-ivy-only
no_output_timeout: 20m
# Temporary job to test what will happen when we flip the Ivy flag to true
test_ivy_aot:
executor:
name: default-executor
resource_class: xlarge
steps:
- custom_attach_workspace
- init_environment
- install_chrome_libs
# We need to explicitly specify the --symlink_prefix option because otherwise we would
# not be able to easily find the output bin directory when uploading artifacts for size
# measurements.
- run:
command: yarn test-ivy-aot //... --symlink_prefix=dist/
no_output_timeout: 20m
# Publish bundle artifacts which will be used to calculate the size change. **Note**: Make
# sure that the size plugin from the Angular robot fetches the artifacts from this CircleCI
# job (see .github/angular-robot.yml). Additionally any artifacts need to be stored with the
# following path format: "{projectName}/{context}/{fileName}". This format is necessary
# because otherwise the bot is not able to pick up the artifacts from CircleCI. See:
# https://github.com/angular/github-robot/blob/master/functions/src/plugins/size.ts#L392-L394
- store_artifacts:
path: dist/bin/packages/core/test/bundling/hello_world/bundle.min.js
destination: core/hello_world/bundle
- store_artifacts:
path: dist/bin/packages/core/test/bundling/todo/bundle.min.js
destination: core/todo/bundle
- store_artifacts:
path: dist/bin/packages/core/test/bundling/hello_world/bundle.min.js.br
destination: core/hello_world/bundle.br
- store_artifacts:
path: dist/bin/packages/core/test/bundling/todo/bundle.min.js.br
destination: core/todo/bundle.br
# NOTE: This is currently limited to master builds only. See the `monitoring` configuration.
saucelabs_view_engine:
executor:
name: default-executor
# In order to avoid the bottleneck of having a slow host machine, we acquire a better
# container for this job. This is necessary because we launch a lot of browsers concurrently
# and therefore the tunnel and Karma need to process a lot of file requests and tests.
resource_class: xlarge
steps:
- custom_attach_workspace
- init_environment
- init_saucelabs_environment
- run:
name: Run Bazel tests on Saucelabs with ViewEngine
# See /tools/saucelabs/README.md for more info
command: |
yarn bazel run //tools/saucelabs:sauce_service_setup
TESTS=$(./node_modules/.bin/bazelisk query --output label '(kind(karma_web_test, ...) intersect attr("tags", "saucelabs", ...)) except attr("tags", "ivy-only", ...) except attr("tags", "fixme-saucelabs-ve", ...)')
yarn bazel test --config=saucelabs ${TESTS}
yarn bazel run //tools/saucelabs:sauce_service_stop
no_output_timeout: 40m
- notify_webhook_on_fail:
webhook_url_env_var: SLACK_DEV_INFRA_CI_FAILURES_WEBHOOK_URL
# NOTE: This is currently limited to master builds only. See the `monitoring` configuration.
saucelabs_ivy:
executor:
name: default-executor
# In order to avoid the bottleneck of having a slow host machine, we acquire a better
# container for this job. This is necessary because we launch a lot of browsers concurrently
# and therefore the tunnel and Karma need to process a lot of file requests and tests.
resource_class: xlarge
steps:
- custom_attach_workspace
- init_environment
- init_saucelabs_environment
- run:
name: Run Bazel tests on Saucelabs with Ivy
# See /tools/saucelabs/README.md for more info
command: |
yarn bazel run //tools/saucelabs:sauce_service_setup
TESTS=$(./node_modules/.bin/bazelisk query --output label '(kind(karma_web_test, ...) intersect attr("tags", "saucelabs", ...)) except attr("tags", "no-ivy-aot", ...) except attr("tags", "fixme-saucelabs-ivy", ...)')
yarn bazel test --config=saucelabs --config=ivy ${TESTS}
yarn bazel run //tools/saucelabs:sauce_service_stop
no_output_timeout: 40m
- notify_webhook_on_fail:
webhook_url_env_var: SLACK_DEV_INFRA_CI_FAILURES_WEBHOOK_URL
test_aio: test_aio:
executor: default-executor executor: default-executor
steps: steps:
@ -393,10 +266,6 @@ jobs:
- run: yarn --cwd aio test-pwa-score-localhost $CI_AIO_MIN_PWA_SCORE - run: yarn --cwd aio test-pwa-score-localhost $CI_AIO_MIN_PWA_SCORE
# Run accessibility tests # Run accessibility tests
- run: yarn --cwd aio test-a11y-score-localhost - run: yarn --cwd aio test-a11y-score-localhost
# Check the bundle sizes.
- run: yarn --cwd aio payload-size
# Run unit tests for Firebase redirects
- run: yarn --cwd aio redirects-test
deploy_aio: deploy_aio:
executor: default-executor executor: default-executor
@ -426,8 +295,6 @@ jobs:
- run: yarn --cwd aio e2e --configuration=ci - run: yarn --cwd aio e2e --configuration=ci
# Run PWA-score tests # Run PWA-score tests
- run: yarn --cwd aio test-pwa-score-localhost $CI_AIO_MIN_PWA_SCORE - run: yarn --cwd aio test-pwa-score-localhost $CI_AIO_MIN_PWA_SCORE
# Check the bundle sizes.
- run: yarn --cwd aio payload-size aio-local<<# parameters.viewengine >>-viewengine<</ parameters.viewengine >>
test_aio_tools: test_aio_tools:
executor: default-executor executor: default-executor
@ -441,26 +308,6 @@ jobs:
- run: yarn --cwd aio tools-test - run: yarn --cwd aio tools-test
- run: ./aio/aio-builds-setup/scripts/test.sh - run: ./aio/aio-builds-setup/scripts/test.sh
test_docs_examples:
parameters:
viewengine:
type: boolean
default: false
executor:
name: default-executor
resource_class: xlarge
parallelism: 5
steps:
- custom_attach_workspace
- init_environment
- install_chrome_libs
# Install aio
- run: yarn --cwd aio install --frozen-lockfile --non-interactive
# Run examples tests. The "CIRCLE_NODE_INDEX" will be set if "parallelism" is enabled.
# Since the parallelism is set to "5", there will be five parallel CircleCI containers.
# with either "0", "1", etc as node index. This can be passed to the "--shard" argument.
- run: yarn --cwd aio example-e2e --setup --local <<# parameters.viewengine >>--viewengine<</ parameters.viewengine >> --cliSpecsConcurrency=5 --shard=${CIRCLE_NODE_INDEX}/${CIRCLE_NODE_TOTAL} --retry 2
# This job should only be run on PR builds, where `CI_PULL_REQUEST` is not `false`. # This job should only be run on PR builds, where `CI_PULL_REQUEST` is not `false`.
aio_preview: aio_preview:
executor: default-executor executor: default-executor
@ -489,7 +336,6 @@ jobs:
name: Wait for preview and run tests name: Wait for preview and run tests
command: node aio/scripts/test-preview.js $CI_PULL_REQUEST $CI_COMMIT $CI_AIO_MIN_PWA_SCORE command: node aio/scripts/test-preview.js $CI_PULL_REQUEST $CI_COMMIT $CI_AIO_MIN_PWA_SCORE
# The `build-npm-packages` tasks exist for backwards-compatibility with old scripts and # The `build-npm-packages` tasks exist for backwards-compatibility with old scripts and
# tests that rely on the pre-Bazel `dist/packages-dist` output structure (build.sh). # tests that rely on the pre-Bazel `dist/packages-dist` output structure (build.sh).
# Having multiple jobs that independently build in this manner duplicates some work; we build # Having multiple jobs that independently build in this manner duplicates some work; we build
@ -501,7 +347,7 @@ jobs:
build-npm-packages: build-npm-packages:
executor: executor:
name: default-executor name: default-executor
resource_class: xlarge resource_class: medium
steps: steps:
- custom_attach_workspace - custom_attach_workspace
- init_environment - init_environment
@ -523,258 +369,6 @@ jobs:
- "~/bazel_repository_cache" - "~/bazel_repository_cache"
- "~/.cache/bazelisk" - "~/.cache/bazelisk"
# Build the ivy npm packages.
build-ivy-npm-packages:
executor:
name: default-executor
resource_class: xlarge
steps:
- custom_attach_workspace
- init_environment
- run: node scripts/build/build-ivy-npm-packages.js
# Save the npm packages from //packages/... for other workflow jobs to read
- persist_to_workspace:
root: *workspace_location
paths:
- ng/dist/packages-dist-ivy-aot
- ng/dist/zone.js-dist-ivy-aot
# This job creates compressed tarballs (`.tgz` files) for all Angular packages and stores them as
# build artifacts. This makes it easy to try out changes from a PR build for testing purposes.
# More info CircleCI build artifacts: https://circleci.com/docs/2.0/artifacts
#
# NOTE: Currently, this job only runs for PR builds. See `publish_snapshot` for non-PR builds.
publish_packages_as_artifacts:
executor: default-executor
environment:
NG_PACKAGES_DIR: &ng_packages_dir 'dist/packages-dist'
NG_PACKAGES_ARCHIVES_DIR: &ng_packages_archives_dir 'dist/packages-dist-archives'
ZONEJS_PACKAGES_DIR: &zonejs_packages_dir 'dist/zone.js-dist'
ZONEJS_PACKAGES_ARCHIVES_DIR: &zonejs_packages_archives_dir 'dist/zone.js-dist-archives'
steps:
- custom_attach_workspace
- init_environment
# Publish `@angular/*` packages.
- run:
name: Create artifacts for @angular/* packages
command: ./scripts/ci/create-package-archives.sh $CI_BRANCH $CI_COMMIT $NG_PACKAGES_DIR $NG_PACKAGES_ARCHIVES_DIR
- store_artifacts:
path: *ng_packages_archives_dir
destination: angular
# Publish `zone.js` package.
- run:
name: Create artifacts for zone.js package
command: ./scripts/ci/create-package-archives.sh $CI_BRANCH $CI_COMMIT $ZONEJS_PACKAGES_DIR $ZONEJS_PACKAGES_ARCHIVES_DIR
- store_artifacts:
path: *zonejs_packages_archives_dir
destination: zone.js
# This job updates the content of repos like github.com/angular/core-builds
# for every green build on angular/angular.
publish_snapshot:
executor: default-executor
steps:
# See below - ideally this job should not trigger for non-upstream builds.
# But since it does, we have to check this condition.
- run:
name: Skip this job for Pull Requests and Fork builds
# Note: Using `CIRCLE_*` env variables (instead of those defined in `env.sh` so that this
# step can be run before `init_environment`.
command: >
if [[ -n "${CIRCLE_PR_NUMBER}" ]] ||
[[ "$CIRCLE_PROJECT_USERNAME" != "angular" ]] ||
[[ "$CIRCLE_PROJECT_REPONAME" != "angular" ]]; then
circleci step halt
fi
- custom_attach_workspace
- init_environment
# CircleCI has a config setting to force SSH for all github connections
# This is not compatible with our mechanism of using a Personal Access Token
# Clear the global setting
- run: git config --global --unset "url.ssh://git@github.com.insteadof"
- run:
name: Decrypt github credentials
# We need ensure that the same default digest is used for encoding and decoding with
# OpenSSL. OpenSSL versions might have different default digests which can cause
# decryption failures based on the installed OpenSSL version. https://stackoverflow.com/a/39641378/4317734
command: 'openssl aes-256-cbc -d -in .circleci/github_token -md md5 -k "${KEY}" -out ~/.git_credentials'
- run: ./scripts/ci/publish-build-artifacts.sh
aio_monitoring_stable:
executor: default-executor
steps:
- custom_attach_workspace
- init_environment
- install_chrome_libs
- run: setPublicVar_CI_STABLE_BRANCH
- run:
name: Check out `aio/` and yarn from the stable branch
command: |
git fetch origin $CI_STABLE_BRANCH
git checkout --force origin/$CI_STABLE_BRANCH -- aio/ .yarn/ .yarnrc
# Ignore yarn's engines check, because we checked out `aio/package.json` from the stable
# branch and there could be a node version skew, which is acceptable in this monitoring job.
- run: yarn config set ignore-engines true
- run:
name: Run tests against https://angular.io/
command: ./aio/scripts/test-production.sh https://angular.io/ $CI_AIO_MIN_PWA_SCORE
- notify_webhook_on_fail:
webhook_url_env_var: SLACK_CARETAKER_WEBHOOK_URL
- notify_webhook_on_fail:
webhook_url_env_var: SLACK_DEV_INFRA_CI_FAILURES_WEBHOOK_URL
aio_monitoring_next:
executor: default-executor
steps:
- custom_attach_workspace
- init_environment
- install_chrome_libs
- run:
name: Run tests against https://next.angular.io/
command: ./aio/scripts/test-production.sh https://next.angular.io/ $CI_AIO_MIN_PWA_SCORE
- notify_webhook_on_fail:
webhook_url_env_var: SLACK_CARETAKER_WEBHOOK_URL
- notify_webhook_on_fail:
webhook_url_env_var: SLACK_DEV_INFRA_CI_FAILURES_WEBHOOK_URL
legacy-unit-tests-saucelabs:
executor:
name: default-executor
# In order to avoid the bottleneck of having a slow host machine, we acquire a better
# container for this job. This is necessary because we launch a lot of browsers concurrently
# and therefore the tunnel and Karma need to process a lot of file requests and tests.
resource_class: xlarge
steps:
- custom_attach_workspace
- init_environment
- init_saucelabs_environment
- run:
name: Starting Saucelabs tunnel service
command: ./tools/saucelabs/sauce-service.sh run
background: true
- run: yarn tsc -p packages
- run: yarn tsc -p modules
- run: yarn bazel build //packages/zone.js:npm_package
# Build test fixtures for a test that rely on Bazel-generated fixtures. Note that disabling
# specific tests which are reliant on such generated fixtures is not an option as SystemJS
# in the Saucelabs legacy job always fetches referenced files, even if the imports would be
# guarded by an check to skip in the Saucelabs legacy job. We should be good running such
# test in all supported browsers on Saucelabs anyway until this job can be removed.
- run:
name: Preparing Bazel-generated fixtures required in legacy tests
command: |
yarn bazel build //packages/core/test:downleveled_es5_fixture
# Needed for the ES5 downlevel reflector test in `packages/core/test/reflection`.
cp dist/bin/packages/core/test/reflection/es5_downleveled_inheritance_fixture.js \
dist/all/@angular/core/test/reflection/es5_downleveled_inheritance_fixture.js
- run:
# Waiting on ready ensures that we don't run tests too early without Saucelabs not being ready.
name: Waiting for Saucelabs tunnel to connect
command: ./tools/saucelabs/sauce-service.sh ready-wait
- run:
name: Running tests on Saucelabs.
command: |
browsers=$(node -e 'console.log(require("./browser-providers.conf").sauceAliases.CI_REQUIRED.join(","))')
yarn karma start ./karma-js.conf.js --single-run --browsers=${browsers}
- run:
name: Stop Saucelabs tunnel service
command: ./tools/saucelabs/sauce-service.sh stop
# Job that runs all unit tests of the `angular/components` repository.
components-repo-unit-tests:
executor:
name: default-executor
resource_class: xlarge
steps:
- custom_attach_workspace
- init_environment
# Restore the cache before cloning the repository because the clone script re-uses
# the restored repository if present. This reduces the amount of times the components
# repository needs to be cloned (this is slow and increases based on commits in the repo).
- restore_cache:
keys:
- *components_repo_unit_tests_cache_key
# Whenever the `angular/components` SHA is updated, the cache key will no longer
# match. The fallback cache will still match, and CircleCI will restore the most
# recently cached repository folder. Without the fallback cache, we'd need to download
# the repository from scratch and it would slow down the job. This is because we can't
# clone the repository with reduced `--depth`, but rather need to clone the whole
# repository to be able to support arbitrary SHAs.
- *components_repo_unit_tests_cache_key_fallback
- run:
name: "Fetching angular/components repository"
command: ./scripts/ci/clone_angular_components_repo.sh
- run:
# Run yarn install to fetch the Bazel binaries as used in the components repo.
name: Installing dependencies.
# TODO: remove this once the repo has been updated to use NodeJS v12 and Yarn 1.19.1.
# We temporarily ignore the "engines" because the Angular components repository has
# minimum dependency on NodeJS v12 and Yarn 1.19.1, but the framework repository uses
# older versions.
command: yarn --ignore-engines --cwd ${COMPONENTS_REPO_TMP_DIR} install --frozen-lockfile --non-interactive
- save_cache:
key: *components_repo_unit_tests_cache_key
paths:
# Temporary directory must be kept in sync with the `$COMPONENTS_REPO_TMP_DIR` env
# variable. It needs to be hardcoded here, because env variables interpolation is
# not supported.
- "/tmp/angular-components-repo"
- run:
# Updates the `angular/components` `package.json` file to refer to the release output
# inside the `packages-dist` directory. Note that it's not necessary to perform a yarn
# install as Bazel runs Yarn automatically when needed.
name: Setting up release packages.
command: node scripts/ci/update-deps-to-dist-packages.js ${COMPONENTS_REPO_TMP_DIR}/package.json dist/packages-dist/
- run:
name: "Running `angular/components` unit tests"
command: ./scripts/ci/run_angular_components_unit_tests.sh
test_zonejs:
executor:
name: default-executor
resource_class: xlarge
steps:
- custom_attach_workspace
- init_environment
# Install
- run: yarn --cwd packages/zone.js install --frozen-lockfile --non-interactive
# Run zone.js tools tests
- run: yarn --cwd packages/zone.js promisetest
- run: yarn --cwd packages/zone.js promisefinallytest
- run: yarn bazel build //packages/zone.js:npm_package &&
cp dist/bin/packages/zone.js/npm_package/dist/zone-mix.js ./packages/zone.js/test/extra/ &&
cp dist/bin/packages/zone.js/npm_package/dist/zone-patch-electron.js ./packages/zone.js/test/extra/ &&
yarn --cwd packages/zone.js electrontest
- run: yarn --cwd packages/zone.js jesttest
# Windows jobs
# Docs: https://circleci.com/docs/2.0/hello-world-windows/
test_win:
executor: windows-executor
steps:
- setup_win
- run:
# Ran into a command parsing problem where `-browser:chromium-local` was converted to
# `-browser: chromium-local` (a space was added) in https://circleci.com/gh/angular/angular/357511.
# Probably a powershell command parsing thing. There's no problem using a yarn script though.
command: yarn circleci-win-ve
no_output_timeout: 45m
# Save bazel repository cache to use on subsequent runs.
# We don't save node_modules because it's faster to use the linux workspace and reinstall.
- save_cache:
key: *cache_key_win
paths:
- "C:/Users/circleci/bazel_repository_cache"
test_ivy_aot_win:
executor: windows-executor
steps:
- setup_win
- run:
command: yarn circleci-win-ivy
no_output_timeout: 45m
workflows: workflows:
version: 2 version: 2
@ -787,21 +381,9 @@ workflows:
- lint: - lint:
requires: requires:
- setup - setup
- test:
requires:
- setup
- test_ivy_aot:
requires:
- setup
- build-npm-packages: - build-npm-packages:
requires: requires:
- setup - setup
- build-ivy-npm-packages:
requires:
- setup
- legacy-unit-tests-saucelabs:
requires:
- setup
- test_aio: - test_aio:
requires: requires:
- setup - setup
@ -811,22 +393,9 @@ workflows:
- test_aio_local: - test_aio_local:
requires: requires:
- build-npm-packages - build-npm-packages
- test_aio_local:
name: test_aio_local_viewengine
viewengine: true
requires:
- build-npm-packages
- test_aio_tools: - test_aio_tools:
requires: requires:
- build-npm-packages - build-npm-packages
- test_docs_examples:
requires:
- build-npm-packages
- test_docs_examples:
name: test_docs_examples_viewengine
viewengine: true
requires:
- build-npm-packages
- aio_preview: - aio_preview:
# Only run on PR builds. (There can be no previews for non-PR builds.) # Only run on PR builds. (There can be no previews for non-PR builds.)
<<: *only_on_pull_requests <<: *only_on_pull_requests
@ -835,78 +404,3 @@ workflows:
- test_aio_preview: - test_aio_preview:
requires: requires:
- aio_preview - aio_preview
- publish_packages_as_artifacts:
requires:
- build-npm-packages
- publish_snapshot:
# Note: no filters on this job because we want it to run for all upstream branches
# We'd really like to filter out pull requests here, but not yet available:
# https://discuss.circleci.com/t/workflows-pull-request-filter/14396/4
# Instead, the job just exits immediately at the first step.
requires:
# Only publish if tests and integration tests pass
- test
- test_ivy_aot
# Only publish if `aio`/`docs` tests using the locally built Angular packages pass
- test_aio_local
- test_aio_local_viewengine
- test_docs_examples
- test_docs_examples_viewengine
# Get the artifacts to publish from the build-packages-dist job
# since the publishing script expects the legacy outputs layout.
- build-npm-packages
- build-ivy-npm-packages
- legacy-unit-tests-saucelabs
- components-repo-unit-tests:
requires:
- build-npm-packages
- test_zonejs:
requires:
- setup
# Windows Jobs
# These are very slow so we run them on non-PRs only for now.
# TODO: remove the filter when CircleCI makes Windows FS faster.
# The Windows jobs are only run after their non-windows counterparts finish successfully.
# This isn't strictly necessary as there is no artifact dependency, but helps economize
# CI resources by not attempting to build when we know should fail.
- test_win:
<<: *skip_on_pull_requests
requires:
- test
- test_ivy_aot_win:
<<: *skip_on_pull_requests
requires:
- test_ivy_aot
monitoring:
jobs:
- setup
- aio_monitoring_stable:
requires:
- setup
- aio_monitoring_next:
requires:
- setup
- saucelabs_ivy:
# Testing saucelabs via Bazel currently taking longer than the legacy saucelabs job as it
# each karma_web_test target is provisioning and tearing down browsers which is adding
# a lot of overhead. Running once daily on master only to avoid wasting resources and
# slowing down CI for PRs.
# TODO: Run this job on all branches (including PRs) once karma_web_test targets can
# share provisioned browsers and we can remove the legacy saucelabs job.
requires:
- setup
- saucelabs_view_engine:
# Testing saucelabs via Bazel currently taking longer than the legacy saucelabs job as it
# each karma_web_test target is provisioning and tearing down browsers which is adding
# a lot of overhead. Running once daily on master only to avoid wasting resources and
# slowing down CI for PRs.
# TODO: Run this job on all branches (including PRs) once karma_web_test targets can
# share provisioned browsers and we can remove the legacy saucelabs job.
requires:
- setup
triggers:
- schedule:
<<: *only_on_master
# Runs monitoring jobs at 10:00AM every day.
cron: "0 10 * * *"

View File

@ -17,7 +17,7 @@ echo "source $envHelpersPath;" >> $BASH_ENV;
#################################################################################################### ####################################################################################################
setPublicVar CI "$CI" setPublicVar CI "$CI"
setPublicVar PROJECT_ROOT "$projectDir"; setPublicVar PROJECT_ROOT "$projectDir";
setPublicVar CI_AIO_MIN_PWA_SCORE "95"; setPublicVar CI_AIO_MIN_PWA_SCORE "62";
# This is the branch being built; e.g. `pull/12345` for PR builds. # This is the branch being built; e.g. `pull/12345` for PR builds.
setPublicVar CI_BRANCH "$CIRCLE_BRANCH"; setPublicVar CI_BRANCH "$CIRCLE_BRANCH";
setPublicVar CI_BUILD_URL "$CIRCLE_BUILD_URL"; setPublicVar CI_BUILD_URL "$CIRCLE_BUILD_URL";

View File

@ -1,69 +0,0 @@
---
name: "\U0001F41EBug report"
about: Report a bug in the Angular Framework
---
<!--🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅
Oh hi there! 😄
To expedite issue processing please search open and closed issues before submitting a new one.
Existing issues often contain information about workarounds, resolution, or progress updates.
🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅-->
# 🐞 bug report
### Affected Package
<!-- Can you pin-point one or more @angular/* packages as the source of the bug? -->
<!-- ✍edit: --> The issue is caused by package @angular/....
### Is this a regression?
<!-- Did this behavior use to work in the previous version? -->
<!-- ✍️--> Yes, the previous version in which this bug was not present was: ....
### Description
<!-- ✍️--> A clear and concise description of the problem...
## 🔬 Minimal Reproduction
<!--
Please create and share minimal reproduction of the issue starting with this template: https://stackblitz.com/fork/angular-ivy
-->
<!-- ✍️--> https://stackblitz.com/...
<!--
If StackBlitz is not suitable for reproduction of your issue, please create a minimal GitHub repository with the reproduction of the issue.
A good way to make a minimal reproduction is to create a new app via `ng new repro-app` and add the minimum possible code to show the problem.
Share the link to the repo below along with step-by-step instructions to reproduce the problem, as well as expected and actual behavior.
Issues that don't have enough info and can't be reproduced will be closed.
You can read more about issue submission guidelines here: https://github.com/angular/angular/blob/master/CONTRIBUTING.md#-submitting-an-issue
-->
## 🔥 Exception or Error
<pre><code>
<!-- If the issue is accompanied by an exception or an error, please share it below: -->
<!-- ✍️-->
</code></pre>
## 🌍 Your Environment
**Angular Version:**
<pre><code>
<!-- run `ng version` and paste output below -->
<!-- ✍️-->
</code></pre>
**Anything else relevant?**
<!--Is this a browser specific issue? If so, please specify the browser and version. -->
<!--Do any of these matter: operating system, IDE, package manager, HTTP server, ...? If so, please mention it below. -->

View File

@ -1,32 +0,0 @@
---
name: "\U0001F680Feature request"
about: Suggest a feature for Angular Framework
---
<!--🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅
Oh hi there! 😄
To expedite issue processing please search open and closed issues before submitting a new one.
Existing issues often contain information about workarounds, resolution, or progress updates.
🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅-->
# 🚀 feature request
### Relevant Package
<!-- Can you pin-point one or more @angular/* packages the are relevant for this feature request? -->
<!-- ✍edit: --> This feature request is for @angular/....
### Description
<!-- ✍️--> A clear and concise description of the problem or missing capability...
### Describe the solution you'd like
<!-- ✍️--> If you have a solution in mind, please describe it.
### Describe alternatives you've considered
<!-- ✍️--> Have you considered any alternative solutions or workarounds?

View File

@ -1,55 +0,0 @@
---
name: "📚 Docs or angular.io issue report"
about: Report an issue in Angular's documentation or angular.io application
---
<!--🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅
Oh hi there! 😄
To expedite issue processing please search open and closed issues before submitting a new one.
Existing issues often contain information about workarounds, resolution, or progress updates.
🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅-->
# 📚 Docs or angular.io bug report
### Description
<!--edit:--> A clear and concise description of the problem...
## 🔬 Minimal Reproduction
### What's the affected URL?**
<!--edit:--> https://angular.io/...
### Reproduction Steps**
<!-- If applicable please list the steps to take to reproduce the issue -->
<!--edit:-->
### Expected vs Actual Behavior**
<!-- If applicable please describe the difference between the expected and actual behavior after following the repro steps. -->
<!--edit:-->
## 📷Screenshot
<!-- Often a screenshot can help to capture the issue better than a long description. -->
<!--upload a screenshot:-->
## 🔥 Exception or Error
<pre><code>
<!-- If the issue is accompanied by an exception or an error, please share it below: -->
<!-- ✍️-->
</code></pre>
## 🌍 Your Environment
### Browser info
<!--Is this a browser specific issue? If so, please specify the device, browser, and version. -->
### Anything else relevant?
<!--Please provide additional info if necessary. -->

View File

@ -1,11 +0,0 @@
---
name: ⚠️ Security issue disclosure
about: Report a security issue in Angular Framework, Material, or CLI
---
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
Please read https://angular.io/guide/security#report-issues on how to disclose security related issues.
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑

View File

@ -1,16 +0,0 @@
---
name: "❓Support request"
about: Questions and requests for support
---
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
Please do not file questions or support requests on the GitHub issues tracker.
You can get your questions answered using other communication channels. Please see:
https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
Thank you!
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑

View File

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

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

View File

@ -0,0 +1,22 @@
---
name: "📚Traducir doc al español"
about: Solicitud para traducir ciertos docs al español
---
📚Traducir: <!-- ✍️ editar: --> creating-libraries.md
<!--🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅
Traducción de la documentación oficial de Angular a español
🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅-->
## Nombre del archivo:
<!-- ✍️ editar: --> creating-libraries.md
## Ruta donde se encuentra el archivo dentro del proyecto de Angular
<!-- ✍️ editar: --> https://github.com/angular-hispano/angular/blob/master/aio/content/guide/creating-libraries.md

View File

@ -1,43 +1,35 @@
## PR Checklist ## Lista de Verificación del PR
Please check if your PR fulfills the following requirements: Comprueba si tu PR cumple los siguientes requisitos:
- [ ] The commit message follows our guidelines: https://github.com/angular/angular/blob/master/CONTRIBUTING.md#commit - [ ] El mensaje de commit esta conforme con [nuestras reglas](https://github.com/angular-hispano/angular/blob/master/CONTRIBUTING.md#-formato-para-el-mensaje-de-los-commits)
- [ ] Tests for the changes have been added (for bug fixes / features) - [ ] Probe los cambios que agregué (arreglo de bugs / funcionalidades)
- [ ] Docs have been added / updated (for bug fixes / features) - [ ] Revisé previamente las traducciones o cambios de contenido
- [ ] Consulté el [diccionario de términos](https://github.com/angular-hispano/angular/blob/master/aio/diccionario-de-términos.md) en español
- [ ] He creado dos archivos con la extensión correspondiente(.en.md para el archivo en inglés y .md para el Archivo en español)
- [ ] He enlazado el commit con el issue correspondiente <!-- ejemplo Fixes #X -->
## PR Type ## Tipo de PR
What kind of change does this PR introduce? ¿Qué tipo de cambio introduce este PR?
<!-- Please check the one that applies to this PR using "x". --> <!-- Marca con una "x" las opciones que aplican. -->
- [ ] Bugfix - [ ] Bugfix
- [ ] Feature - [ ] Funcionalidad
- [ ] Code style update (formatting, local variables) - [ ] Actualización de el estilo del código (formato, variables locales)
- [ ] Refactoring (no functional changes, no api changes) - [ ] Refactorización (no cambios en la funcionalidad, no cambios en el api)
- [ ] Build related changes - [ ] Cambios relacionados al build
- [ ] CI related changes - [ ] Cambios relacionados al CI (Integración continua)
- [ ] Documentation content changes - [ ] Cambios en el contenido de la documentación
- [ ] angular.io application / infrastructure changes - [ ] Cambios en la aplicación / infraestructura de angular.io
- [ ] Other... Please describe: - [ ] Otro... Por favor describe la:
## ¿Cuál es el comportamiento actual?
<!-- Describe el comportamiento actual que está modificando o vincule a un problema relevante.
-->
## What is the current behavior? ## ¿Cuál es el nuevo comportamiento?
<!-- Please describe the current behavior that you are modifying, or link to a relevant issue. --> <!--
Ejemplo: Archivo en inglés traducido al español
Issue Number: N/A -->
## What is the new behavior?
## Does this PR introduce a breaking change?
- [ ] Yes
- [ ] No
<!-- If this PR contains a breaking change, please describe the impact and migration path for existing applications below. -->
## Other information

View File

@ -6,7 +6,20 @@ import {CommitMessageConfig} from '../dev-infra/commit-message/config';
export const commitMessage: CommitMessageConfig = { export const commitMessage: CommitMessageConfig = {
maxLineLength: 120, maxLineLength: 120,
minBodyLength: 20, minBodyLength: 20,
minBodyLengthTypeExcludes: ['docs'], minBodyLengthTypeExcludes: ['docs', 'upstream'],
types: [
'build',
'ci',
'docs',
'feat',
'fix',
'perf',
'refactor',
'release',
'style',
'test',
'upstream',
],
scopes: [ scopes: [
'animations', 'animations',
'bazel', 'bazel',

View File

@ -115,54 +115,6 @@ pullapprove_conditions:
groups: groups:
# =========================================================
# Require review on all PRs
#
# All PRs require at least one review. This rule will not
# request any reviewers, however will require that at least
# one review is provided before the group is satisfied.
# =========================================================
required-minimum-review:
reviews:
request: 0 # Do not request any reviews from the reviewer group
required: 1 # Require that all PRs have approval from at least one of the users in the group
author_value: 0 # The author of the PR cannot provide an approval for themself
reviewers:
users:
- aikidave # Dave Shevitz
- alan-agius4 # Alan Agius
- alxhub # Alex Rickabaugh
- AndrewKushnir # Andrew Kushnir
- andrewseguin # Andrew Seguin
- atscott # Andrew Scott
- ayazhafiz # Ayaz Hafiz
- clydin # Charles Lyding
- crisbeto # Kristiyan Kostadinov
- dennispbrown # Denny Brown
- devversion # Paul Gschwendtner
- dgp1130 # Doug Parker
- filipesilva # Filipe Silva
- gkalpak # Georgios Kalpakas
- gregmagolan # Greg Magolan
- IgorMinar # Igor Minar
- jbogarthyde # Judy Bogart
- jelbourn # Jeremy Elbourn
- JiaLiPassion # Jia Li
- JoostK # Joost Koehoorn
- josephperrott # Joey Perrott
- juleskremer # Jules Kremer
- kapunahelewong # Kapunahele Wong
- kara # Kara Erickson
- kyliau # Keen Yee Liau
- manughub # Manu Murthy
- mgechev # Minko Gechev
- mhevery # Miško Hevery
- michaelprentice # Michael Prentice
- mmalerba # Miles Malerba
- petebacondarwin # Pete Bacon Darwin
- pkozlowski-opensource # Pawel Kozlowski
- StephenFluin # Stephen Fluin
# ========================================================= # =========================================================
# Global Approvers # Global Approvers
# #
@ -199,6 +151,57 @@ groups:
required: 1 required: 1
reviewed_for: required reviewed_for: required
# =========================================================
# Require review on all PRs
#
# All PRs require at least one review. This rule will not
# request any reviewers, however will require that at least
# one review is provided before the group is satisfied.
# =========================================================
required-minimum-review:
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
reviews:
request: 0 # Do not request any reviews from the reviewer group
required: 1 # Require that all PRs have approval from at least one of the users in the group
author_value: 0 # The author of the PR cannot provide an approval for themself
reviewers:
users:
- aikidave # Dave Shevitz
- alan-agius4 # Alan Agius
- alxhub # Alex Rickabaugh
- AndrewKushnir # Andrew Kushnir
- andrewseguin # Andrew Seguin
- atscott # Andrew Scott
- ayazhafiz # Ayaz Hafiz
- clydin # Charles Lyding
- crisbeto # Kristiyan Kostadinov
- dennispbrown # Denny Brown
- devversion # Paul Gschwendtner
- dgp1130 # Doug Parker
- filipesilva # Filipe Silva
- gkalpak # Georgios Kalpakas
- gregmagolan # Greg Magolan
- IgorMinar # Igor Minar
- jbogarthyde # Judy Bogart
- jelbourn # Jeremy Elbourn
- JiaLiPassion # Jia Li
- JoostK # Joost Koehoorn
- josephperrott # Joey Perrott
- juleskremer # Jules Kremer
- kapunahelewong # Kapunahele Wong
- kara # Kara Erickson
- kyliau # Keen Yee Liau
- manughub # Manu Murthy
- mgechev # Minko Gechev
- mhevery # Miško Hevery
- mmalerba # Miles Malerba
- petebacondarwin # Pete Bacon Darwin
- pkozlowski-opensource # Pawel Kozlowski
- Splaktar # Michael Prentice
- StephenFluin # Stephen Fluin
# ========================================================= # =========================================================
# Framework: Animations # Framework: Animations
# ========================================================= # =========================================================
@ -332,6 +335,7 @@ groups:
'aio/content/images/guide/dependency-injection-in-action/**', 'aio/content/images/guide/dependency-injection-in-action/**',
'aio/content/guide/dependency-injection-navtree.md', 'aio/content/guide/dependency-injection-navtree.md',
'aio/content/guide/dependency-injection-providers.md', 'aio/content/guide/dependency-injection-providers.md',
'aio/content/guide/lightweight-injection-tokens.md',
'aio/content/guide/displaying-data.md', 'aio/content/guide/displaying-data.md',
'aio/content/examples/displaying-data/**', 'aio/content/examples/displaying-data/**',
'aio/content/images/guide/displaying-data/**', 'aio/content/images/guide/displaying-data/**',
@ -505,8 +509,8 @@ groups:
- > - >
contains_any_globs(files, [ contains_any_globs(files, [
'packages/core/src/i18n/**', 'packages/core/src/i18n/**',
'packages/core/src/render3/i18n/**', 'packages/core/src/render3/i18n.ts',
'packages/core/src/render3/instructions/i18n.ts', 'packages/core/src/render3/i18n.md',
'packages/core/src/render3/interfaces/i18n.ts', 'packages/core/src/render3/interfaces/i18n.ts',
'packages/common/locales/**', 'packages/common/locales/**',
'packages/common/src/i18n/**', 'packages/common/src/i18n/**',
@ -783,6 +787,21 @@ groups:
- JiaLiPassion - JiaLiPassion
- mhevery - mhevery
# =========================================================
# in-memory-web-api
# =========================================================
in-memory-web-api:
conditions:
- *can-be-global-approved
- *can-be-global-docs-approved
- >
contains_any_globs(files, [
'packages/misc/angular-in-memory-web-api/**',
])
reviewers:
users:
- IgorMinar
- crisbeto
# ========================================================= # =========================================================
# Benchpress # Benchpress
@ -1091,6 +1110,7 @@ groups:
'dev-infra/**', 'dev-infra/**',
'docs/BAZEL.md', 'docs/BAZEL.md',
'docs/CARETAKER.md', 'docs/CARETAKER.md',
'docs/CODING_STANDARDS.md',
'docs/COMMITTER.md', 'docs/COMMITTER.md',
'docs/DEBUG.md', 'docs/DEBUG.md',
'docs/DEBUG_COMPONENTS_REPO_IVY.md', 'docs/DEBUG_COMPONENTS_REPO_IVY.md',

View File

@ -20,9 +20,9 @@ filegroup(
# do not sort # do not sort
srcs = [ srcs = [
"@npm//:node_modules/core-js/client/core.js", "@npm//:node_modules/core-js/client/core.js",
"//packages/zone.js/dist:zone.js", "//packages/zone.js/bundles:zone.umd.js",
"//packages/zone.js/dist:zone-testing.js", "//packages/zone.js/bundles:zone-testing.umd.js",
"//packages/zone.js/dist:task-tracking.js", "//packages/zone.js/bundles:task-tracking.umd.js",
"//:test-events.js", "//:test-events.js",
"//:third_party/shims_for_IE.js", "//:third_party/shims_for_IE.js",
# Including systemjs because it defines `__eval`, which produces correct stack traces. # Including systemjs because it defines `__eval`, which produces correct stack traces.

View File

@ -1,47 +1,17 @@
<a name="10.0.11"></a> <a name="10.1.0-next.4"></a>
## 10.0.11 (2020-08-19) # 10.1.0-next.4 (2020-08-04)
### Bug Fixes ### Bug Fixes
* **router:** ensure routerLinkActive updates when associated routerLinks change (resubmit of [#38349](https://github.com/angular/angular/issues/38349)) ([#38511](https://github.com/angular/angular/issues/38511)) ([0af9533](https://github.com/angular/angular/commit/0af9533)), closes [#18469](https://github.com/angular/angular/issues/18469) * **common:** narrow `NgIf` context variables in template type checker ([#36627](https://github.com/angular/angular/issues/36627)) ([9c8bc4a](https://github.com/angular/angular/commit/9c8bc4a))
* **compiler:** mark `NgModuleFactory` construction as not side effectful ([#38147](https://github.com/angular/angular/issues/38147)) ([7f8c222](https://github.com/angular/angular/commit/7f8c222))
### Features
<a name="10.0.10"></a> * **core:** rename async to waitForAsync to avoid confusing ([#37583](https://github.com/angular/angular/issues/37583)) ([8f07429](https://github.com/angular/angular/commit/8f07429))
## 10.0.10 (2020-08-17) * **core:** update reference and doc to change `async` to `waitAsync`. ([#37583](https://github.com/angular/angular/issues/37583)) ([8fbf40b](https://github.com/angular/angular/commit/8fbf40b))
### Bug Fixes
* **common:** Allow scrolling when browser supports scrollTo ([#38468](https://github.com/angular/angular/issues/38468)) ([b32126c](https://github.com/angular/angular/commit/b32126c)), closes [#30630](https://github.com/angular/angular/issues/30630)
* **core:** detect DI parameters in JIT mode for downleveled ES2015 classes ([#38500](https://github.com/angular/angular/issues/38500)) ([863acb6](https://github.com/angular/angular/commit/863acb6)), closes [#38453](https://github.com/angular/angular/issues/38453)
* **core:** error if CSS custom property in host binding has number in name ([#38432](https://github.com/angular/angular/issues/38432)) ([cb83b8a](https://github.com/angular/angular/commit/cb83b8a)), closes [#37292](https://github.com/angular/angular/issues/37292)
* **core:** fix multiple nested views removal from ViewContainerRef ([#38317](https://github.com/angular/angular/issues/38317)) ([d5e09f4](https://github.com/angular/angular/commit/d5e09f4)), closes [#38201](https://github.com/angular/angular/issues/38201)
* **ngcc:** detect synthesized delegate constructors for downleveled ES2015 classes ([#38500](https://github.com/angular/angular/issues/38500)) ([f3dd6c2](https://github.com/angular/angular/commit/f3dd6c2)), closes [#38453](https://github.com/angular/angular/issues/38453) [#38453](https://github.com/angular/angular/issues/38453)
* **router:** ensure routerLinkActive updates when associated routerLinks change ([#38349](https://github.com/angular/angular/issues/38349)) ([989e8a1](https://github.com/angular/angular/commit/989e8a1)), closes [#18469](https://github.com/angular/angular/issues/18469)
<a name="10.0.9"></a>
## 10.0.9 (2020-08-12)
### Bug Fixes
* **common:** ensure scrollRestoration is writable ([#30630](https://github.com/angular/angular/issues/30630)) ([#38357](https://github.com/angular/angular/issues/38357)) ([58f4b3a](https://github.com/angular/angular/commit/58f4b3a)), closes [#30629](https://github.com/angular/angular/issues/30629)
* **compiler:** evaluate safe navigation expressions in correct binding order ([#37911](https://github.com/angular/angular/issues/37911)) ([f5b9d87](https://github.com/angular/angular/commit/f5b9d87)), closes [#37194](https://github.com/angular/angular/issues/37194)
* **compiler-cli:** avoid creating value expressions for symbols from type-only imports ([#38415](https://github.com/angular/angular/issues/38415)) ([ca2b4bc](https://github.com/angular/angular/commit/ca2b4bc)), closes [#37912](https://github.com/angular/angular/issues/37912)
* **compiler-cli:** infer quote expressions as any type in type checker ([#37917](https://github.com/angular/angular/issues/37917)) ([5b87c67](https://github.com/angular/angular/commit/5b87c67)), closes [#36568](https://github.com/angular/angular/issues/36568)
* **compiler-cli:** mark eager `NgModuleFactory` construction as not side effectful ([#38320](https://github.com/angular/angular/issues/38320)) ([016a41b](https://github.com/angular/angular/commit/016a41b)), closes [#38147](https://github.com/angular/angular/issues/38147)
* **compiler-cli:** match wrapHost parameter types within plugin interface ([#38004](https://github.com/angular/angular/issues/38004)) ([df01a82](https://github.com/angular/angular/commit/df01a82))
* **compiler-cli:** preserve quotes in class member names ([#38387](https://github.com/angular/angular/issues/38387)) ([c9acb7b](https://github.com/angular/angular/commit/c9acb7b)), closes [#38311](https://github.com/angular/angular/issues/38311)
* **core:** prevent NgModule scope being overwritten in JIT compiler ([#37795](https://github.com/angular/angular/issues/37795)) ([3acebdc](https://github.com/angular/angular/commit/3acebdc)), closes [#37105](https://github.com/angular/angular/issues/37105)
* **core:** queries not matching string injection tokens ([#38321](https://github.com/angular/angular/issues/38321)) ([32109dc](https://github.com/angular/angular/commit/32109dc)), closes [#38313](https://github.com/angular/angular/issues/38313) [#38315](https://github.com/angular/angular/issues/38315)
* **core:** Store the currently selected ICU in `LView` ([#38345](https://github.com/angular/angular/issues/38345)) ([ee5123f](https://github.com/angular/angular/commit/ee5123f))
* **platform-server:** remove styles added by ServerStylesHost on destruction ([#38367](https://github.com/angular/angular/issues/38367)) ([7f11149](https://github.com/angular/angular/commit/7f11149))
* **router:** prevent calling unsubscribe on undefined subscription in RouterPreloader ([#38344](https://github.com/angular/angular/issues/38344)) ([4151314](https://github.com/angular/angular/commit/4151314))
* **service-worker:** fix the chrome debugger syntax highlighter ([#38332](https://github.com/angular/angular/issues/38332)) ([f5d5bac](https://github.com/angular/angular/commit/f5d5bac))
@ -66,6 +36,16 @@
<a name="10.1.0-next.3"></a>
# 10.1.0-next.3 (2020-07-28)
### Bug Fixes
* **elements:** run strategy methods in correct zone ([#37814](https://github.com/angular/angular/issues/37814)) ([8df888d](https://github.com/angular/angular/commit/8df888d)), closes [#24181](https://github.com/angular/angular/issues/24181)
<a name="10.0.6"></a> <a name="10.0.6"></a>
## 10.0.6 (2020-07-28) ## 10.0.6 (2020-07-28)
@ -79,6 +59,23 @@
<a name="10.1.0-next.2"></a>
# 10.1.0-next.2 (2020-07-22)
### Bug Fixes
* **core:** Allow modification of lifecycle hooks any time before bootstrap ([#35464](https://github.com/angular/angular/issues/35464)) ([737506e](https://github.com/angular/angular/commit/737506e)), closes [#30497](https://github.com/angular/angular/issues/30497)
### Features
* **common:** add ReadonlyMap in place of Map in keyValuePipe ([#37311](https://github.com/angular/angular/issues/37311)) ([3373453](https://github.com/angular/angular/commit/3373453)), closes [#37308](https://github.com/angular/angular/issues/37308)
* **forms:** AbstractControl to store raw validators in addition to combined validators function ([#37881](https://github.com/angular/angular/issues/37881)) ([ad7046b](https://github.com/angular/angular/commit/ad7046b))
* **localize:** allow duplicate messages to be handled during extraction ([#38082](https://github.com/angular/angular/issues/38082)) ([cf9a47b](https://github.com/angular/angular/commit/cf9a47b)), closes [#38077](https://github.com/angular/angular/issues/38077)
<a name="10.0.5"></a> <a name="10.0.5"></a>
## 10.0.5 (2020-07-22) ## 10.0.5 (2020-07-22)
@ -113,6 +110,61 @@
* **bazel:** provide LinkablePackageInfo from ng_module ([#37778](https://github.com/angular/angular/issues/37778)) ([6cd10a1](https://github.com/angular/angular/commit/6cd10a1)), closes [/github.com/bazelbuild/rules_nodejs/blob/9a5de3728b05bf1647bbb87ad99f54e626604705/internal/linker/link_node_modules.bzl#L144-L146](https://github.com//github.com/bazelbuild/rules_nodejs/blob/9a5de3728b05bf1647bbb87ad99f54e626604705/internal/linker/link_node_modules.bzl/issues/L144-L146) * **bazel:** provide LinkablePackageInfo from ng_module ([#37778](https://github.com/angular/angular/issues/37778)) ([6cd10a1](https://github.com/angular/angular/commit/6cd10a1)), closes [/github.com/bazelbuild/rules_nodejs/blob/9a5de3728b05bf1647bbb87ad99f54e626604705/internal/linker/link_node_modules.bzl#L144-L146](https://github.com//github.com/bazelbuild/rules_nodejs/blob/9a5de3728b05bf1647bbb87ad99f54e626604705/internal/linker/link_node_modules.bzl/issues/L144-L146)
<a name="10.1.0-next.1"></a>
# 10.1.0-next.1 (2020-07-15)
### Bug Fixes
* **bazel:** ng_module rule does not expose flat module information in Ivy ([#36971](https://github.com/angular/angular/issues/36971)) ([1550663](https://github.com/angular/angular/commit/1550663))
* **compiler:** check more cases for pipe usage inside host bindings ([#37883](https://github.com/angular/angular/issues/37883)) ([9322b9a](https://github.com/angular/angular/commit/9322b9a)), closes [#34655](https://github.com/angular/angular/issues/34655) [#37610](https://github.com/angular/angular/issues/37610)
* **compiler-cli:** ensure file_system handles mixed Windows drives ([#37959](https://github.com/angular/angular/issues/37959)) ([6b31155](https://github.com/angular/angular/commit/6b31155)), closes [#36777](https://github.com/angular/angular/issues/36777)
* **language-service:** remove completion for string ([#37983](https://github.com/angular/angular/issues/37983)) ([10aba15](https://github.com/angular/angular/commit/10aba15))
* **ngcc:** report a warning if ngcc tries to use a solution-style tsconfig ([#38003](https://github.com/angular/angular/issues/38003)) ([b358495](https://github.com/angular/angular/commit/b358495)), closes [#36386](https://github.com/angular/angular/issues/36386)
* **router:** ensure duplicate popstate/hashchange events are handled correctly ([#37674](https://github.com/angular/angular/issues/37674)) ([9185c6e](https://github.com/angular/angular/commit/9185c6e)), closes [/github.com/angular/angular/issues/16710#issuecomment-646919529](https://github.com//github.com/angular/angular/issues/16710/issues/issuecomment-646919529) [#16710](https://github.com/angular/angular/issues/16710)
* **service-worker:** correctly handle relative base href ([#37922](https://github.com/angular/angular/issues/37922)) ([d19ef65](https://github.com/angular/angular/commit/d19ef65)), closes [#25055](https://github.com/angular/angular/issues/25055) [#25055](https://github.com/angular/angular/issues/25055)
* **service-worker:** correctly serve `ngsw/state` with a non-root SW scope ([#37922](https://github.com/angular/angular/issues/37922)) ([2156bee](https://github.com/angular/angular/commit/2156bee)), closes [#30505](https://github.com/angular/angular/issues/30505)
<a name="10.1.0-next.0"></a>
# 10.1.0-next.0 (2020-07-08)
### Bug Fixes
* **common:** date pipe gives wrong week number ([#37632](https://github.com/angular/angular/issues/37632)) ([ef1fb6d](https://github.com/angular/angular/commit/ef1fb6d)), closes [#33961](https://github.com/angular/angular/issues/33961)
* **compiler-cli:** ensure source-maps can handle webpack:// protocol ([#32912](https://github.com/angular/angular/issues/32912)) ([decd95e](https://github.com/angular/angular/commit/decd95e))
* **compiler-cli:** only read source-map comment from last line ([#32912](https://github.com/angular/angular/issues/32912)) ([07a07e3](https://github.com/angular/angular/commit/07a07e3))
* **core:** determine required DOMParser feature availability ([#36578](https://github.com/angular/angular/issues/36578)) ([#36578](https://github.com/angular/angular/issues/36578)) ([c509243](https://github.com/angular/angular/commit/c509243))
* **core:** do not trigger CSP alert/report in Firefox and Chrome ([#36578](https://github.com/angular/angular/issues/36578)) ([#36578](https://github.com/angular/angular/issues/36578)) ([b950d46](https://github.com/angular/angular/commit/b950d46)), closes [#25214](https://github.com/angular/angular/issues/25214)
* **forms:** handle form groups/arrays own pending async validation ([#22575](https://github.com/angular/angular/issues/22575)) ([77b62a5](https://github.com/angular/angular/commit/77b62a5)), closes [#10064](https://github.com/angular/angular/issues/10064)
* **language-service:** non-existent module format in package output ([#37623](https://github.com/angular/angular/issues/37623)) ([413a0fb](https://github.com/angular/angular/commit/413a0fb))
* **router:** fix navigation ignoring logic to compare to the browser url ([#37716](https://github.com/angular/angular/issues/37716)) ([a5ffca0](https://github.com/angular/angular/commit/a5ffca0)), closes [#16710](https://github.com/angular/angular/issues/16710) [#13586](https://github.com/angular/angular/issues/13586)
* **router:** properly compare array queryParams for equality ([#37709](https://github.com/angular/angular/issues/37709)) ([#37860](https://github.com/angular/angular/issues/37860)) ([1801d0c](https://github.com/angular/angular/commit/1801d0c))
* **router:** remove parenthesis for primary outlet segment after removing auxiliary outlet segment ([#24656](https://github.com/angular/angular/issues/24656)) ([#37163](https://github.com/angular/angular/issues/37163)) ([71f008f](https://github.com/angular/angular/commit/71f008f))
### Features
* **bazel:** provide LinkablePackageInfo from ng_module ([#37623](https://github.com/angular/angular/issues/37623)) ([6898eab](https://github.com/angular/angular/commit/6898eab))
* **compiler-cli:** add `SourceFile.getOriginalLocation()` to sourcemaps package ([#32912](https://github.com/angular/angular/issues/32912)) ([6abb8d0](https://github.com/angular/angular/commit/6abb8d0))
* **compiler-cli:** explain why an expression cannot be used in AOT compilations ([#37587](https://github.com/angular/angular/issues/37587)) ([712f1bd](https://github.com/angular/angular/commit/712f1bd))
* **core:** support injection token as predicate in queries ([#37506](https://github.com/angular/angular/issues/37506)) ([97dc85b](https://github.com/angular/angular/commit/97dc85b)), closes [#21152](https://github.com/angular/angular/issues/21152) [#36144](https://github.com/angular/angular/issues/36144)
* **localize:** expose `canParse()` diagnostics ([#37909](https://github.com/angular/angular/issues/37909)) ([ec32eba](https://github.com/angular/angular/commit/ec32eba)), closes [#37901](https://github.com/angular/angular/issues/37901)
* **localize:** implement message extraction tool ([#32912](https://github.com/angular/angular/issues/32912)) ([190561d](https://github.com/angular/angular/commit/190561d))
* **platform-browser:** Allow `sms`-URLs ([#31463](https://github.com/angular/angular/issues/31463)) ([fc5c34d](https://github.com/angular/angular/commit/fc5c34d)), closes [#31462](https://github.com/angular/angular/issues/31462)
* **platform-server:** add option for absolute URL HTTP support ([#37539](https://github.com/angular/angular/issues/37539)) ([d37049a](https://github.com/angular/angular/commit/d37049a)), closes [#37071](https://github.com/angular/angular/issues/37071)
### Performance Improvements
* **compiler-cli:** fix regressions in incremental program reuse ([#37641](https://github.com/angular/angular/issues/37641)) ([5103d90](https://github.com/angular/angular/commit/5103d90))
* **ngcc:** shortcircuit tokenizing in ESM dependency host ([#37639](https://github.com/angular/angular/issues/37639)) ([bd7f440](https://github.com/angular/angular/commit/bd7f440))
* **ngcc:** use `EntryPointManifest` to speed up noop `ProgramBaseEntryPointFinder` ([#37665](https://github.com/angular/angular/issues/37665)) ([9318e23](https://github.com/angular/angular/commit/9318e23))
* **router:** apply prioritizedGuardValue operator to optimize CanLoad guards ([#37523](https://github.com/angular/angular/issues/37523)) ([d7dd295](https://github.com/angular/angular/commit/d7dd295))
<a name="10.0.3"></a> <a name="10.0.3"></a>
## 10.0.3 (2020-07-08) ## 10.0.3 (2020-07-08)
@ -124,6 +176,16 @@
<a name="9.1.12"></a>
## [9.1.12](https://github.com/angular/angular/compare/9.1.11...9.1.12) (2020-07-08)
### Bug Fixes
* **core:** infinite loop if injectable using inheritance has a custom decorator ([6c1ab47](https://github.com/angular/angular/commit/6c1ab47)), closes [#35733](https://github.com/angular/angular/issues/35733)
<a name="10.0.2"></a> <a name="10.0.2"></a>
## [10.0.2](https://github.com/angular/angular/compare/10.0.1...10.0.2) (2020-06-30) ## [10.0.2](https://github.com/angular/angular/compare/10.0.1...10.0.2) (2020-06-30)
@ -235,7 +297,6 @@ To learn about the release highlights and our CLI-powered automated update workf
* **compiler:** avoid undefined expressions in holey array ([#36343](https://github.com/angular/angular/issues/36343)) ([5516802](https://github.com/angular/angular/commit/5516802)) * **compiler:** avoid undefined expressions in holey array ([#36343](https://github.com/angular/angular/issues/36343)) ([5516802](https://github.com/angular/angular/commit/5516802))
* **compiler:** handle type references to namespaced symbols correctly ([#36106](https://github.com/angular/angular/issues/36106)) ([4aa4e6f](https://github.com/angular/angular/commit/4aa4e6f)), closes [#36006](https://github.com/angular/angular/issues/36006) * **compiler:** handle type references to namespaced symbols correctly ([#36106](https://github.com/angular/angular/issues/36106)) ([4aa4e6f](https://github.com/angular/angular/commit/4aa4e6f)), closes [#36006](https://github.com/angular/angular/issues/36006)
* **compiler:** normalize line endings in ICU expansions ([#36741](https://github.com/angular/angular/issues/36741)) ([70dd27f](https://github.com/angular/angular/commit/70dd27f)), closes [#36725](https://github.com/angular/angular/issues/36725) * **compiler:** normalize line endings in ICU expansions ([#36741](https://github.com/angular/angular/issues/36741)) ([70dd27f](https://github.com/angular/angular/commit/70dd27f)), closes [#36725](https://github.com/angular/angular/issues/36725)
* **compiler:** record correct end of expression ([#34690](https://github.com/angular/angular/issues/34690)) ([df890d7](https://github.com/angular/angular/commit/df890d7)), closes [#33477](https://github.com/angular/angular/issues/33477)
* **compiler:** remove outdated and invalid warning for unresolved DI parameters ([#36985](https://github.com/angular/angular/issues/36985)) ([d0280a0](https://github.com/angular/angular/commit/d0280a0)) * **compiler:** remove outdated and invalid warning for unresolved DI parameters ([#36985](https://github.com/angular/angular/issues/36985)) ([d0280a0](https://github.com/angular/angular/commit/d0280a0))
* **compiler:** resolve enum values in binary operations ([#36461](https://github.com/angular/angular/issues/36461)) ([64022f5](https://github.com/angular/angular/commit/64022f5)), closes [#35584](https://github.com/angular/angular/issues/35584) * **compiler:** resolve enum values in binary operations ([#36461](https://github.com/angular/angular/issues/36461)) ([64022f5](https://github.com/angular/angular/commit/64022f5)), closes [#35584](https://github.com/angular/angular/issues/35584)
* **compiler:** switch to 'referencedFiles' for shim generation ([#36211](https://github.com/angular/angular/issues/36211)) ([4213e8d](https://github.com/angular/angular/commit/4213e8d)) * **compiler:** switch to 'referencedFiles' for shim generation ([#36211](https://github.com/angular/angular/issues/36211)) ([4213e8d](https://github.com/angular/angular/commit/4213e8d))
@ -492,6 +553,30 @@ subscribe to the observable and call markForCheck as needed.
<a name="9.1.11"></a>
## [9.1.11](https://github.com/angular/angular/compare/9.1.10...9.1.11) (2020-06-10)
### Reverts
* **elements:** fire custom element output events during component initialization ([dc9da17](https://github.com/angular/angular/commit/dc9da17))
<a name="9.1.10"></a>
## [9.1.10](https://github.com/angular/angular/compare/9.1.9...9.1.10) (2020-06-09)
### Bug Fixes
* **elements:** fire custom element output events during component initialization ([454e073](https://github.com/angular/angular/commit/454e073)), closes [/github.com/angular/angular/blob/c0143cb2abdd172de1b95fd1d2c4cfc738640e28/packages/elements/src/create-custom-element.ts#L167-L170](https://github.com/angular/angular/blob/c0143cb2abdd172de1b95fd1d2c4cfc738640e28/packages/elements/src/create-custom-element.ts/issues/L167-L170) [/github.com/angular/angular/blob/c0143cb2abdd172de1b95fd1d2c4cfc738640e28/packages/elements/src/create-custom-element.ts#L164](https://github.com/angular/angular/blob/c0143cb2abdd172de1b95fd1d2c4cfc738640e28/packages/elements/src/create-custom-element.ts/issues/L164) [/github.com/angular/angular/blob/c0143cb2abdd172de1b95fd1d2c4cfc738640e28/packages/elements/src/component-factory-strategy.ts#L158](https://github.com/angular/angular/blob/c0143cb2abdd172de1b95fd1d2c4cfc738640e28/packages/elements/src/component-factory-strategy.ts/issues/L158) [#36141](https://github.com/angular/angular/issues/36141)
### Performance Improvements
* **ngcc:** cache parsed tsconfig between runs ([1aae94a](https://github.com/angular/angular/commit/1aae94a)), closes [#37417](https://github.com/angular/angular/issues/37417) [#36882](https://github.com/angular/angular/issues/36882)
<a name="9.1.9"></a> <a name="9.1.9"></a>
## [9.1.9](https://github.com/angular/angular/compare/9.1.8...9.1.9) (2020-05-20) ## [9.1.9](https://github.com/angular/angular/compare/9.1.8...9.1.9) (2020-05-20)
@ -533,6 +618,7 @@ This release contains various API docs improvements.
* **compiler-cli**: Revert "fix(compiler-cli): fix case-sensitivity issues in NgtscCompilerHost (#36968)" (#37003) * **compiler-cli**: Revert "fix(compiler-cli): fix case-sensitivity issues in NgtscCompilerHost (#36968)" (#37003)
<a name="9.1.5"></a> <a name="9.1.5"></a>
## [9.1.5](https://github.com/angular/angular/compare/9.1.4...9.1.5) (2020-05-07) ## [9.1.5](https://github.com/angular/angular/compare/9.1.4...9.1.5) (2020-05-07)
@ -578,6 +664,7 @@ This release contains various API docs improvements.
* **ngcc:** recognize enum declarations emitted in JavaScript ([#36550](https://github.com/angular/angular/issues/36550)) ([c440165](https://github.com/angular/angular/commit/c440165)), closes [#35584](https://github.com/angular/angular/issues/35584) * **ngcc:** recognize enum declarations emitted in JavaScript ([#36550](https://github.com/angular/angular/issues/36550)) ([c440165](https://github.com/angular/angular/commit/c440165)), closes [#35584](https://github.com/angular/angular/issues/35584)
<a name="9.1.3"></a> <a name="9.1.3"></a>
## [9.1.3](https://github.com/angular/angular/compare/9.1.2...9.1.3) (2020-04-22) ## [9.1.3](https://github.com/angular/angular/compare/9.1.2...9.1.3) (2020-04-22)
@ -592,8 +679,8 @@ This release contains various API docs improvements.
* **core:** prevent unknown property check for AOT-compiled components ([#36072](https://github.com/angular/angular/issues/36072)) ([fe1d9ba](https://github.com/angular/angular/commit/fe1d9ba)), closes [#35945](https://github.com/angular/angular/issues/35945) * **core:** prevent unknown property check for AOT-compiled components ([#36072](https://github.com/angular/angular/issues/36072)) ([fe1d9ba](https://github.com/angular/angular/commit/fe1d9ba)), closes [#35945](https://github.com/angular/angular/issues/35945)
* **core:** properly identify modules affected by overrides in TestBed ([#36649](https://github.com/angular/angular/issues/36649)) ([9724169](https://github.com/angular/angular/commit/9724169)), closes [#36619](https://github.com/angular/angular/issues/36619) * **core:** properly identify modules affected by overrides in TestBed ([#36649](https://github.com/angular/angular/issues/36649)) ([9724169](https://github.com/angular/angular/commit/9724169)), closes [#36619](https://github.com/angular/angular/issues/36619)
* **language-service:** properly evaluate types in comparable expressions ([#36529](https://github.com/angular/angular/issues/36529)) ([5bab498](https://github.com/angular/angular/commit/5bab498)) * **language-service:** properly evaluate types in comparable expressions ([#36529](https://github.com/angular/angular/issues/36529)) ([5bab498](https://github.com/angular/angular/commit/5bab498))
* **ngcc:** display unlocker process output in sync mode ([#36637](https://github.com/angular/angular/issues/36637)) ([da159bd](https://github.com/angular/angular/commit/da159bd)), closes [/github.com/nodejs/node/issues/3596#issuecomment-250890218](https://github.com/nodejs/node/issues/3596#issuecomment-250890218) * **ngcc:** display unlocker process output in sync mode ([#36637](https://github.com/angular/angular/issues/36637)) ([da159bd](https://github.com/angular/angular/commit/da159bd)), closes [/github.com/nodejs/node/issues/3596#issuecomment-250890218](https://github.com/nodejs/node/issues/3596/issues/issuecomment-250890218)
* **ngcc:** do not use cached file-system ([#36687](https://github.com/angular/angular/issues/36687)) ([18be33a](https://github.com/angular/angular/commit/18be33a)), closes [/github.com/angular/angular-cli/issues/16860#issuecomment-614694269](https://github.com/angular/angular-cli/issues/16860#issuecomment-614694269) * **ngcc:** do not use cached file-system ([#36687](https://github.com/angular/angular/issues/36687)) ([18be33a](https://github.com/angular/angular/commit/18be33a)), closes [/github.com/angular/angular-cli/issues/16860#issuecomment-614694269](https://github.com/angular/angular-cli/issues/16860/issues/issuecomment-614694269)
@ -614,7 +701,7 @@ This release contains various API docs improvements.
* **upgrade:** update $locationShim to handle Location changes before initialization ([#36498](https://github.com/angular/angular/issues/36498)) ([a67afcc](https://github.com/angular/angular/commit/a67afcc)), closes [#36492](https://github.com/angular/angular/issues/36492) * **upgrade:** update $locationShim to handle Location changes before initialization ([#36498](https://github.com/angular/angular/issues/36498)) ([a67afcc](https://github.com/angular/angular/commit/a67afcc)), closes [#36492](https://github.com/angular/angular/issues/36492)
### Performance Improvements ### Performance Improvements
* **ngcc:** only load if it is needed ([#36486](https://github.com/angular/angular/issues/36486)) ([e06512b](https://github.com/angular/angular/commit/e06512b)) * **ngcc:** read dependencies from entry-point manifest ([#36486](https://github.com/angular/angular/issues/36486)) ([918e628](https://github.com/angular/angular/commit/918e628)), closes [#issuecomment-608401834](https://github.com/angular/angular#issuecomment-608401834) * **ngcc:** only load if it is needed ([#36486](https://github.com/angular/angular/issues/36486)) ([e06512b](https://github.com/angular/angular/commit/e06512b)) * **ngcc:** read dependencies from entry-point manifest ([#36486](https://github.com/angular/angular/issues/36486)) ([918e628](https://github.com/angular/angular/commit/918e628)), closes [#issuecomment-608401834](https://github.com/angular/angular/issues/issuecomment-608401834)
* **ngcc:** reduce the size of the entry-point manifest file ([#36486](https://github.com/angular/angular/issues/36486)) ([603b094](https://github.com/angular/angular/commit/603b094)) * **ngcc:** reduce the size of the entry-point manifest file ([#36486](https://github.com/angular/angular/issues/36486)) ([603b094](https://github.com/angular/angular/commit/603b094))
@ -634,7 +721,7 @@ This release contains various API docs improvements.
* **core:** undecorated-classes migration should handle derived abstract classes ([#35339](https://github.com/angular/angular/issues/35339)) ([a631b99](https://github.com/angular/angular/commit/a631b99)) * **core:** undecorated-classes migration should handle derived abstract classes ([#35339](https://github.com/angular/angular/issues/35339)) ([a631b99](https://github.com/angular/angular/commit/a631b99))
* **language-service:** infer type of elements of array-like objects ([#36312](https://github.com/angular/angular/issues/36312)) ([ff523c9](https://github.com/angular/angular/commit/ff523c9)), closes [#36191](https://github.com/angular/angular/issues/36191) * **language-service:** infer type of elements of array-like objects ([#36312](https://github.com/angular/angular/issues/36312)) ([ff523c9](https://github.com/angular/angular/commit/ff523c9)), closes [#36191](https://github.com/angular/angular/issues/36191)
* **language-service:** use the `HtmlAst` to get the span of HTML tag ([#36371](https://github.com/angular/angular/issues/36371)) ([ffa4e11](https://github.com/angular/angular/commit/ffa4e11)) * **language-service:** use the `HtmlAst` to get the span of HTML tag ([#36371](https://github.com/angular/angular/issues/36371)) ([ffa4e11](https://github.com/angular/angular/commit/ffa4e11))
* **ngcc:** add process title ([#36448](https://github.com/angular/angular/issues/36448)) ([136596d](https://github.com/angular/angular/commit/136596d)), closes [36414#issuecomment-609644282](https://github.com/angular/angular/issues/36414#issuecomment-609644282) * **ngcc:** add process title ([#36448](https://github.com/angular/angular/issues/36448)) ([136596d](https://github.com/angular/angular/commit/136596d)), closes [/github.com/angular/angular/issues/36414#issuecomment-609644282](https://github.com/angular/angular/issues/36414/issues/issuecomment-609644282)
* **ngcc:** allow ngcc configuration to match pre-release versions of packages ([#36370](https://github.com/angular/angular/issues/36370)) ([cb0a2a0](https://github.com/angular/angular/commit/cb0a2a0)) * **ngcc:** allow ngcc configuration to match pre-release versions of packages ([#36370](https://github.com/angular/angular/issues/36370)) ([cb0a2a0](https://github.com/angular/angular/commit/cb0a2a0))
* **ngcc:** correctly detect imported TypeScript helpers ([#36284](https://github.com/angular/angular/issues/36284)) ([879457c](https://github.com/angular/angular/commit/879457c)), closes [#36089](https://github.com/angular/angular/issues/36089) * **ngcc:** correctly detect imported TypeScript helpers ([#36284](https://github.com/angular/angular/issues/36284)) ([879457c](https://github.com/angular/angular/commit/879457c)), closes [#36089](https://github.com/angular/angular/issues/36089)
* **ngcc:** correctly identify relative Windows-style import paths ([#36372](https://github.com/angular/angular/issues/36372)) ([0daa488](https://github.com/angular/angular/commit/0daa488)) * **ngcc:** correctly identify relative Windows-style import paths ([#36372](https://github.com/angular/angular/issues/36372)) ([0daa488](https://github.com/angular/angular/commit/0daa488))
@ -711,12 +798,9 @@ To learn about the release highlights and our CLI-powered automated update workf
* **animations:** allow computeStyle to work on elements created in Node ([#35810](https://github.com/angular/angular/issues/35810)) ([17cf04e](https://github.com/angular/angular/commit/17cf04e)) * **animations:** allow computeStyle to work on elements created in Node ([#35810](https://github.com/angular/angular/issues/35810)) ([17cf04e](https://github.com/angular/angular/commit/17cf04e))
* **animations:** false positive when detecting Node in Webpack builds ([#35134](https://github.com/angular/angular/issues/35134)) ([dc4ae4b](https://github.com/angular/angular/commit/dc4ae4b)), closes [#35117](https://github.com/angular/angular/issues/35117) * **animations:** false positive when detecting Node in Webpack builds ([#35134](https://github.com/angular/angular/issues/35134)) ([dc4ae4b](https://github.com/angular/angular/commit/dc4ae4b)), closes [#35117](https://github.com/angular/angular/issues/35117)
* **animations:** process shorthand `margin` and `padding` styles correctly ([#35701](https://github.com/angular/angular/issues/35701)) ([35c9f0d](https://github.com/angular/angular/commit/35c9f0d)), closes [#35463](https://github.com/angular/angular/issues/35463) * **animations:** process shorthand `margin` and `padding` styles correctly ([#35701](https://github.com/angular/angular/issues/35701)) ([35c9f0d](https://github.com/angular/angular/commit/35c9f0d)), closes [#35463](https://github.com/angular/angular/issues/35463)
* **bazel:** devserver shows blank page in Windows ([#35159](https://github.com/angular/angular/issues/35159)) ([727f92f](https://github.com/angular/angular/commit/727f92f))
* **bazel:** do not use manifest paths for generated imports within compilation unit ([#35841](https://github.com/angular/angular/issues/35841)) ([9581658](https://github.com/angular/angular/commit/9581658)) * **bazel:** do not use manifest paths for generated imports within compilation unit ([#35841](https://github.com/angular/angular/issues/35841)) ([9581658](https://github.com/angular/angular/commit/9581658))
* **bazel:** ng_package rule creates incorrect UMD module exports ([#35792](https://github.com/angular/angular/issues/35792)) ([5c2a908](https://github.com/angular/angular/commit/5c2a908)), closes [angular/components#18652](https://github.com/angular/components/issues/18652) * **bazel:** ng_package rule creates incorrect UMD module exports ([#35792](https://github.com/angular/angular/issues/35792)) ([5c2a908](https://github.com/angular/angular/commit/5c2a908)), closes [angular/components#18652](https://github.com/angular/components/issues/18652)
* **bazel:** prod server doesn't serve files in windows ([#35991](https://github.com/angular/angular/issues/35991)) ([96e3449](https://github.com/angular/angular/commit/96e3449)) * **bazel:** prod server doesn't serve files in windows ([#35991](https://github.com/angular/angular/issues/35991)) ([96e3449](https://github.com/angular/angular/commit/96e3449))
* **bazel:** spawn prod server using port 4200 ([#35160](https://github.com/angular/angular/issues/35160)) ([829f506](https://github.com/angular/angular/commit/829f506))
* **bazel:** update ibazel to 0.11.1 ([#35158](https://github.com/angular/angular/issues/35158)) ([4e6d237](https://github.com/angular/angular/commit/4e6d237))
* **bazel:** update several packages for better windows support ([#35991](https://github.com/angular/angular/issues/35991)) ([32f099a](https://github.com/angular/angular/commit/32f099a)) * **bazel:** update several packages for better windows support ([#35991](https://github.com/angular/angular/issues/35991)) ([32f099a](https://github.com/angular/angular/commit/32f099a))
* **bazel:** update typescript peer dependency range ([#36013](https://github.com/angular/angular/issues/36013)) ([5e3a898](https://github.com/angular/angular/commit/5e3a898)) * **bazel:** update typescript peer dependency range ([#36013](https://github.com/angular/angular/issues/36013)) ([5e3a898](https://github.com/angular/angular/commit/5e3a898))
* **common:** let `KeyValuePipe` accept type unions with `null` ([#36093](https://github.com/angular/angular/issues/36093)) ([407fa42](https://github.com/angular/angular/commit/407fa42)), closes [#35743](https://github.com/angular/angular/issues/35743) * **common:** let `KeyValuePipe` accept type unions with `null` ([#36093](https://github.com/angular/angular/issues/36093)) ([407fa42](https://github.com/angular/angular/commit/407fa42)), closes [#35743](https://github.com/angular/angular/issues/35743)
@ -725,7 +809,6 @@ To learn about the release highlights and our CLI-powered automated update workf
* **compiler:** Propagate value span of ExpressionBinding to ParsedProperty ([#36133](https://github.com/angular/angular/issues/36133)) ([2ce5fa3](https://github.com/angular/angular/commit/2ce5fa3)) * **compiler:** Propagate value span of ExpressionBinding to ParsedProperty ([#36133](https://github.com/angular/angular/issues/36133)) ([2ce5fa3](https://github.com/angular/angular/commit/2ce5fa3))
* **compiler:** do not recurse to find static symbols of same module ([#35262](https://github.com/angular/angular/issues/35262)) ([e179c58](https://github.com/angular/angular/commit/e179c58)) * **compiler:** do not recurse to find static symbols of same module ([#35262](https://github.com/angular/angular/issues/35262)) ([e179c58](https://github.com/angular/angular/commit/e179c58))
* **compiler:** record correct end of expression ([#34690](https://github.com/angular/angular/issues/34690)) ([df890d7](https://github.com/angular/angular/commit/df890d7)), closes [#33477](https://github.com/angular/angular/issues/33477) * **compiler:** record correct end of expression ([#34690](https://github.com/angular/angular/issues/34690)) ([df890d7](https://github.com/angular/angular/commit/df890d7)), closes [#33477](https://github.com/angular/angular/issues/33477)
* **compiler:** report errors for missing binding names ([#34595](https://github.com/angular/angular/issues/34595)) ([d13cab7](https://github.com/angular/angular/commit/d13cab7))
* **compiler:** support directive inputs with interpolations on `<ng-template>`s ([#35984](https://github.com/angular/angular/issues/35984)) ([79659ee](https://github.com/angular/angular/commit/79659ee)), closes [#35752](https://github.com/angular/angular/issues/35752) * **compiler:** support directive inputs with interpolations on `<ng-template>`s ([#35984](https://github.com/angular/angular/issues/35984)) ([79659ee](https://github.com/angular/angular/commit/79659ee)), closes [#35752](https://github.com/angular/angular/issues/35752)
* **compiler:** support i18n attributes on `<ng-template>` tags ([#35681](https://github.com/angular/angular/issues/35681)) ([40da51f](https://github.com/angular/angular/commit/40da51f)) * **compiler:** support i18n attributes on `<ng-template>` tags ([#35681](https://github.com/angular/angular/issues/35681)) ([40da51f](https://github.com/angular/angular/commit/40da51f))
* **compiler:** type-checking error for duplicate variables in templates ([#35674](https://github.com/angular/angular/issues/35674)) ([2c41bb8](https://github.com/angular/angular/commit/2c41bb8)), closes [#35186](https://github.com/angular/angular/issues/35186) * **compiler:** type-checking error for duplicate variables in templates ([#35674](https://github.com/angular/angular/issues/35674)) ([2c41bb8](https://github.com/angular/angular/commit/2c41bb8)), closes [#35186](https://github.com/angular/angular/issues/35186)
@ -763,19 +846,13 @@ To learn about the release highlights and our CLI-powered automated update workf
* **core:** workaround Terser inlining bug ([#36200](https://github.com/angular/angular/issues/36200)) ([f71d132](https://github.com/angular/angular/commit/f71d132)) * **core:** workaround Terser inlining bug ([#36200](https://github.com/angular/angular/issues/36200)) ([f71d132](https://github.com/angular/angular/commit/f71d132))
* **elements:** correctly handle setting inputs to `undefined` ([#36140](https://github.com/angular/angular/issues/36140)) ([e066bdd](https://github.com/angular/angular/commit/e066bdd)) * **elements:** correctly handle setting inputs to `undefined` ([#36140](https://github.com/angular/angular/issues/36140)) ([e066bdd](https://github.com/angular/angular/commit/e066bdd))
* **elements:** correctly set `SimpleChange#firstChange` for pre-existing inputs ([#36140](https://github.com/angular/angular/issues/36140)) ([447a600](https://github.com/angular/angular/commit/447a600)), closes [#36130](https://github.com/angular/angular/issues/36130) * **elements:** correctly set `SimpleChange#firstChange` for pre-existing inputs ([#36140](https://github.com/angular/angular/issues/36140)) ([447a600](https://github.com/angular/angular/commit/447a600)), closes [#36130](https://github.com/angular/angular/issues/36130)
* **elements:** schematics fail with schema.json not found error ([#35211](https://github.com/angular/angular/issues/35211)) ([94d002b](https://github.com/angular/angular/commit/94d002b)), closes [#35154](https://github.com/angular/angular/issues/35154)
* **forms:** change Array.reduce usage to Array.forEach ([#35349](https://github.com/angular/angular/issues/35349)) ([554c2cb](https://github.com/angular/angular/commit/554c2cb))
* **ivy:** `LFrame` needs to release memory on `leaveView()` ([#35156](https://github.com/angular/angular/issues/35156)) ([b9b512f](https://github.com/angular/angular/commit/b9b512f)), closes [#35148](https://github.com/angular/angular/issues/35148) * **ivy:** `LFrame` needs to release memory on `leaveView()` ([#35156](https://github.com/angular/angular/issues/35156)) ([b9b512f](https://github.com/angular/angular/commit/b9b512f)), closes [#35148](https://github.com/angular/angular/issues/35148)
* **ivy:** add attributes and classes to host elements based on selector ([#34481](https://github.com/angular/angular/issues/34481)) ([f95b8ce](https://github.com/angular/angular/commit/f95b8ce)) * **ivy:** add attributes and classes to host elements based on selector ([#34481](https://github.com/angular/angular/issues/34481)) ([f95b8ce](https://github.com/angular/angular/commit/f95b8ce))
* **ivy:** ensure module imports are instantiated before the module being declared ([#35172](https://github.com/angular/angular/issues/35172)) ([b6a3a73](https://github.com/angular/angular/commit/b6a3a73))
* **ivy:** error if directive with synthetic property binding is on same node as directive that injects ViewContainerRef ([#35343](https://github.com/angular/angular/issues/35343)) ([d6bc63f](https://github.com/angular/angular/commit/d6bc63f)), closes [#35342](https://github.com/angular/angular/issues/35342) * **ivy:** error if directive with synthetic property binding is on same node as directive that injects ViewContainerRef ([#35343](https://github.com/angular/angular/issues/35343)) ([d6bc63f](https://github.com/angular/angular/commit/d6bc63f)), closes [#35342](https://github.com/angular/angular/issues/35342)
* **ivy:** narrow `NgIf` context variables in template type checker ([#35125](https://github.com/angular/angular/issues/35125)) ([40039d8](https://github.com/angular/angular/commit/40039d8)), closes [#34572](https://github.com/angular/angular/issues/34572) * **ivy:** narrow `NgIf` context variables in template type checker ([#35125](https://github.com/angular/angular/issues/35125)) ([40039d8](https://github.com/angular/angular/commit/40039d8)), closes [#34572](https://github.com/angular/angular/issues/34572)
* **ivy:** queries should match elements inside ng-container with the descendants: false option ([#35384](https://github.com/angular/angular/issues/35384)) ([3f4e02b](https://github.com/angular/angular/commit/3f4e02b)), closes [#34768](https://github.com/angular/angular/issues/34768) * **ivy:** queries should match elements inside ng-container with the descendants: false option ([#35384](https://github.com/angular/angular/issues/35384)) ([3f4e02b](https://github.com/angular/angular/commit/3f4e02b)), closes [#34768](https://github.com/angular/angular/issues/34768)
* **ivy:** repeat template guards to narrow types in event handlers ([#35193](https://github.com/angular/angular/issues/35193)) ([dea1b96](https://github.com/angular/angular/commit/dea1b96)), closes [#35073](https://github.com/angular/angular/issues/35073)
* **ivy:** set namespace for host elements of dynamically created components ([#35136](https://github.com/angular/angular/issues/35136)) ([480a4c3](https://github.com/angular/angular/commit/480a4c3))
* **ivy:** support dynamic query tokens in AOT mode ([#35307](https://github.com/angular/angular/issues/35307)) ([3e3a1ef](https://github.com/angular/angular/commit/3e3a1ef)), closes [#34267](https://github.com/angular/angular/issues/34267) * **ivy:** support dynamic query tokens in AOT mode ([#35307](https://github.com/angular/angular/issues/35307)) ([3e3a1ef](https://github.com/angular/angular/commit/3e3a1ef)), closes [#34267](https://github.com/angular/angular/issues/34267)
* **ivy:** wrong context passed to ngOnDestroy when resolved multiple times ([#35249](https://github.com/angular/angular/issues/35249)) ([5fbfe69](https://github.com/angular/angular/commit/5fbfe69)), closes [#35167](https://github.com/angular/angular/issues/35167) * **ivy:** wrong context passed to ngOnDestroy when resolved multiple times ([#35249](https://github.com/angular/angular/issues/35249)) ([5fbfe69](https://github.com/angular/angular/commit/5fbfe69)), closes [#35167](https://github.com/angular/angular/issues/35167)
* **language-service:** Suggest ? and ! operator on nullable receiver ([#35200](https://github.com/angular/angular/issues/35200)) ([3cc24a9](https://github.com/angular/angular/commit/3cc24a9))
* **language-service:** fix calculation of pipe spans ([#35986](https://github.com/angular/angular/issues/35986)) ([406419b](https://github.com/angular/angular/commit/406419b)) * **language-service:** fix calculation of pipe spans ([#35986](https://github.com/angular/angular/issues/35986)) ([406419b](https://github.com/angular/angular/commit/406419b))
* **language-service:** get the right 'ElementAst' in the nested HTML tag ([#35317](https://github.com/angular/angular/issues/35317)) ([8e354da](https://github.com/angular/angular/commit/8e354da)) * **language-service:** get the right 'ElementAst' in the nested HTML tag ([#35317](https://github.com/angular/angular/issues/35317)) ([8e354da](https://github.com/angular/angular/commit/8e354da))
* **language-service:** infer $implicit value for ngIf template contexts ([#35941](https://github.com/angular/angular/issues/35941)) ([18b1bd4](https://github.com/angular/angular/commit/18b1bd4)) * **language-service:** infer $implicit value for ngIf template contexts ([#35941](https://github.com/angular/angular/issues/35941)) ([18b1bd4](https://github.com/angular/angular/commit/18b1bd4))
@ -800,7 +877,6 @@ To learn about the release highlights and our CLI-powered automated update workf
* **ngcc:** correctly detect outer aliased class identifiers in ES5 ([#35527](https://github.com/angular/angular/issues/35527)) ([fde8915](https://github.com/angular/angular/commit/fde8915)), closes [#35399](https://github.com/angular/angular/issues/35399) * **ngcc:** correctly detect outer aliased class identifiers in ES5 ([#35527](https://github.com/angular/angular/issues/35527)) ([fde8915](https://github.com/angular/angular/commit/fde8915)), closes [#35399](https://github.com/angular/angular/issues/35399)
* **ngcc:** do not crash on entry-point that fails to compile ([#36083](https://github.com/angular/angular/issues/36083)) ([ff665b9](https://github.com/angular/angular/commit/ff665b9)) * **ngcc:** do not crash on entry-point that fails to compile ([#36083](https://github.com/angular/angular/issues/36083)) ([ff665b9](https://github.com/angular/angular/commit/ff665b9))
* **ngcc:** do not crash on overlapping entry-points ([#36083](https://github.com/angular/angular/issues/36083)) ([c9f554c](https://github.com/angular/angular/commit/c9f554c)) * **ngcc:** do not crash on overlapping entry-points ([#36083](https://github.com/angular/angular/issues/36083)) ([c9f554c](https://github.com/angular/angular/commit/c9f554c))
* **ngcc:** ensure that path-mapped secondary entry-points are processed correctly ([#35227](https://github.com/angular/angular/issues/35227)) ([c3c1140](https://github.com/angular/angular/commit/c3c1140)), closes [#35188](https://github.com/angular/angular/issues/35188)
* **ngcc:** handle imports in dts files when processing CommonJS ([#35191](https://github.com/angular/angular/issues/35191)) ([b6e8847](https://github.com/angular/angular/commit/b6e8847)), closes [#34356](https://github.com/angular/angular/issues/34356) * **ngcc:** handle imports in dts files when processing CommonJS ([#35191](https://github.com/angular/angular/issues/35191)) ([b6e8847](https://github.com/angular/angular/commit/b6e8847)), closes [#34356](https://github.com/angular/angular/issues/34356)
* **ngcc:** handle mappings outside the content when flattening source-maps ([#35718](https://github.com/angular/angular/issues/35718)) ([73cf7d5](https://github.com/angular/angular/commit/73cf7d5)), closes [#35709](https://github.com/angular/angular/issues/35709) * **ngcc:** handle mappings outside the content when flattening source-maps ([#35718](https://github.com/angular/angular/issues/35718)) ([73cf7d5](https://github.com/angular/angular/commit/73cf7d5)), closes [#35709](https://github.com/angular/angular/issues/35709)
* **ngcc:** handle missing sources when flattening source-maps ([#35718](https://github.com/angular/angular/issues/35718)) ([72c4fda](https://github.com/angular/angular/commit/72c4fda)), closes [#35709](https://github.com/angular/angular/issues/35709) * **ngcc:** handle missing sources when flattening source-maps ([#35718](https://github.com/angular/angular/issues/35718)) ([72c4fda](https://github.com/angular/angular/commit/72c4fda)), closes [#35709](https://github.com/angular/angular/issues/35709)
@ -1058,7 +1134,7 @@ To learn about the release highlights and our CLI-powered automated update workf
* **compiler-cli:** require node 10 as runtime engine ([#34722](https://github.com/angular/angular/issues/34722)) ([7b77b3d](https://github.com/angular/angular/commit/7b77b3d)) * **compiler-cli:** require node 10 as runtime engine ([#34722](https://github.com/angular/angular/issues/34722)) ([7b77b3d](https://github.com/angular/angular/commit/7b77b3d))
* **language-service:** specific suggestions for template context diags ([#34751](https://github.com/angular/angular/issues/34751)) ([cc7fca4](https://github.com/angular/angular/commit/cc7fca4)) * **language-service:** specific suggestions for template context diags ([#34751](https://github.com/angular/angular/issues/34751)) ([cc7fca4](https://github.com/angular/angular/commit/cc7fca4))
* **language-service:** support multiple symbol definitions ([#34782](https://github.com/angular/angular/issues/34782)) ([2f2396c](https://github.com/angular/angular/commit/2f2396c)) * **language-service:** support multiple symbol definitions ([#34782](https://github.com/angular/angular/issues/34782)) ([2f2396c](https://github.com/angular/angular/commit/2f2396c))
* **ngcc:** lock ngcc when processing ([#34722](https://github.com/angular/angular/issues/34722)) ([6dd51f1](https://github.com/angular/angular/commit/6dd51f1)), closes [32431#issuecomment-571825781](https://github.com/angular/angular/issues/32431#issuecomment-571825781) * **ngcc:** lock ngcc when processing ([#34722](https://github.com/angular/angular/issues/34722)) ([6dd51f1](https://github.com/angular/angular/commit/6dd51f1)), closes [/github.com/angular/angular/issues/32431#issuecomment-571825781](https://github.com/angular/angular/issues/32431/issues/issuecomment-571825781)
* work around 'noImplicityAny' incompatibility due to ts3.7 update ([#34798](https://github.com/angular/angular/issues/34798)) ([251d548](https://github.com/angular/angular/commit/251d548)) * work around 'noImplicityAny' incompatibility due to ts3.7 update ([#34798](https://github.com/angular/angular/issues/34798)) ([251d548](https://github.com/angular/angular/commit/251d548))
* **animations:** not waiting for child animations to finish when removing parent in Ivy ([#34702](https://github.com/angular/angular/issues/34702)) ([92c17fe](https://github.com/angular/angular/commit/92c17fe)), closes [#33597](https://github.com/angular/angular/issues/33597) * **animations:** not waiting for child animations to finish when removing parent in Ivy ([#34702](https://github.com/angular/angular/issues/34702)) ([92c17fe](https://github.com/angular/angular/commit/92c17fe)), closes [#33597](https://github.com/angular/angular/issues/33597)
* **common:** ensure diffing in ngStyle/ngClass correctly emits value changes ([#34307](https://github.com/angular/angular/issues/34307)) ([93a035f](https://github.com/angular/angular/commit/93a035f)), closes [#34336](https://github.com/angular/angular/issues/34336) [#34444](https://github.com/angular/angular/issues/34444) * **common:** ensure diffing in ngStyle/ngClass correctly emits value changes ([#34307](https://github.com/angular/angular/issues/34307)) ([93a035f](https://github.com/angular/angular/commit/93a035f)), closes [#34336](https://github.com/angular/angular/issues/34336) [#34444](https://github.com/angular/angular/issues/34444)
@ -1189,7 +1265,7 @@ To learn about the release highlights and our CLI-powered automated update workf
* **ngcc:** do not output duplicate ɵprov properties ([#34085](https://github.com/angular/angular/issues/34085)) ([5a8d25d](https://github.com/angular/angular/commit/5a8d25d)) * **ngcc:** do not output duplicate ɵprov properties ([#34085](https://github.com/angular/angular/issues/34085)) ([5a8d25d](https://github.com/angular/angular/commit/5a8d25d))
* **ngcc:** render localized strings when in ES5 format ([#33857](https://github.com/angular/angular/issues/33857)) ([c6695fa](https://github.com/angular/angular/commit/c6695fa)) * **ngcc:** render localized strings when in ES5 format ([#33857](https://github.com/angular/angular/issues/33857)) ([c6695fa](https://github.com/angular/angular/commit/c6695fa))
* **ngcc:** render UMD global imports correctly ([#34012](https://github.com/angular/angular/issues/34012)) ([83989b8](https://github.com/angular/angular/commit/83989b8)) * **ngcc:** render UMD global imports correctly ([#34012](https://github.com/angular/angular/issues/34012)) ([83989b8](https://github.com/angular/angular/commit/83989b8))
* **ngcc:** report errors from `analyze` and `resolve` processing ([#33964](https://github.com/angular/angular/issues/33964)) ([ca5d772](https://github.com/angular/angular/commit/ca5d772)), closes [33685#issuecomment-557091719](https://github.com/angular/angular/issues/33685#issuecomment-557091719) * **ngcc:** report errors from `analyze` and `resolve` processing ([#33964](https://github.com/angular/angular/issues/33964)) ([ca5d772](https://github.com/angular/angular/commit/ca5d772)), closes [/github.com/angular/angular/issues/33685#issuecomment-557091719](https://github.com/angular/angular/issues/33685/issues/issuecomment-557091719)
* **router:** make routerLinkActive work with query params which contain arrays ([#22666](https://github.com/angular/angular/issues/22666)) ([f1bf5b2](https://github.com/angular/angular/commit/f1bf5b2)), closes [#22223](https://github.com/angular/angular/issues/22223) * **router:** make routerLinkActive work with query params which contain arrays ([#22666](https://github.com/angular/angular/issues/22666)) ([f1bf5b2](https://github.com/angular/angular/commit/f1bf5b2)), closes [#22223](https://github.com/angular/angular/issues/22223)
* **service-worker:** allow creating post api requests after cache failure ([#33930](https://github.com/angular/angular/issues/33930)) ([63c9123](https://github.com/angular/angular/commit/63c9123)), closes [#33793](https://github.com/angular/angular/issues/33793) * **service-worker:** allow creating post api requests after cache failure ([#33930](https://github.com/angular/angular/issues/33930)) ([63c9123](https://github.com/angular/angular/commit/63c9123)), closes [#33793](https://github.com/angular/angular/issues/33793)
* **service-worker:** throw when using the unsupported `versionedFiles` option in config ([#33903](https://github.com/angular/angular/issues/33903)) ([250e6fd](https://github.com/angular/angular/commit/250e6fd)) * **service-worker:** throw when using the unsupported `versionedFiles` option in config ([#33903](https://github.com/angular/angular/issues/33903)) ([250e6fd](https://github.com/angular/angular/commit/250e6fd))
@ -1268,7 +1344,7 @@ To learn about the release highlights and our CLI-powered automated update workf
* **language-service:** Should not crash if expr ends unexpectedly ([#33524](https://github.com/angular/angular/issues/33524)) ([9ebac71](https://github.com/angular/angular/commit/9ebac71)) * **language-service:** Should not crash if expr ends unexpectedly ([#33524](https://github.com/angular/angular/issues/33524)) ([9ebac71](https://github.com/angular/angular/commit/9ebac71))
* **ngcc:** handle new `__spreadArrays` tslib helper ([#33617](https://github.com/angular/angular/issues/33617)) ([d749dd3](https://github.com/angular/angular/commit/d749dd3)), closes [#33614](https://github.com/angular/angular/issues/33614) * **ngcc:** handle new `__spreadArrays` tslib helper ([#33617](https://github.com/angular/angular/issues/33617)) ([d749dd3](https://github.com/angular/angular/commit/d749dd3)), closes [#33614](https://github.com/angular/angular/issues/33614)
* **ngcc:** override `getInternalNameOfClass()` and `getAdjacentNameOfClass()` for ES5 ([#33533](https://github.com/angular/angular/issues/33533)) ([93a23b9](https://github.com/angular/angular/commit/93a23b9)) * **ngcc:** override `getInternalNameOfClass()` and `getAdjacentNameOfClass()` for ES5 ([#33533](https://github.com/angular/angular/issues/33533)) ([93a23b9](https://github.com/angular/angular/commit/93a23b9))
* **ngcc:** render adjacent statements after static properties ([#33630](https://github.com/angular/angular/issues/33630)) ([fe12d0d](https://github.com/angular/angular/commit/fe12d0d)), closes [/github.com/angular/angular/pull/33337#issuecomment-545487737](https://github.com/angular/angular/pull/33337#issuecomment-545487737) * **ngcc:** render adjacent statements after static properties ([#33630](https://github.com/angular/angular/issues/33630)) ([fe12d0d](https://github.com/angular/angular/commit/fe12d0d)), closes [/github.com/angular/angular/pull/33337#issuecomment-545487737](https://github.com/angular/angular/pull/33337/issues/issuecomment-545487737)
* **ngcc:** render new definitions using the inner name of the class ([#33533](https://github.com/angular/angular/issues/33533)) ([85298e3](https://github.com/angular/angular/commit/85298e3)) * **ngcc:** render new definitions using the inner name of the class ([#33533](https://github.com/angular/angular/issues/33533)) ([85298e3](https://github.com/angular/angular/commit/85298e3))
* **service-worker:** ensure initialization before handling messages ([#32525](https://github.com/angular/angular/issues/32525)) ([72eba77](https://github.com/angular/angular/commit/72eba77)), closes [#25611](https://github.com/angular/angular/issues/25611) * **service-worker:** ensure initialization before handling messages ([#32525](https://github.com/angular/angular/issues/32525)) ([72eba77](https://github.com/angular/angular/commit/72eba77)), closes [#25611](https://github.com/angular/angular/issues/25611)
* **compiler:** i18n - ignore `alt-trans` tags in XLIFF 1.2 ([#33450](https://github.com/angular/angular/issues/33450)) ([936700a](https://github.com/angular/angular/commit/936700a)), closes [#33161](https://github.com/angular/angular/issues/33161) * **compiler:** i18n - ignore `alt-trans` tags in XLIFF 1.2 ([#33450](https://github.com/angular/angular/issues/33450)) ([936700a](https://github.com/angular/angular/commit/936700a)), closes [#33161](https://github.com/angular/angular/issues/33161)
@ -1298,7 +1374,7 @@ To learn about the release highlights and our CLI-powered automated update workf
* **language-service:** Add directive selectors & banana-in-a-box to completions ([#33311](https://github.com/angular/angular/issues/33311)) ([49eec5d](https://github.com/angular/angular/commit/49eec5d)) * **language-service:** Add directive selectors & banana-in-a-box to completions ([#33311](https://github.com/angular/angular/issues/33311)) ([49eec5d](https://github.com/angular/angular/commit/49eec5d))
* **language-service:** Add global symbol for $any() ([#33245](https://github.com/angular/angular/issues/33245)) ([3f257e9](https://github.com/angular/angular/commit/3f257e9)) * **language-service:** Add global symbol for $any() ([#33245](https://github.com/angular/angular/issues/33245)) ([3f257e9](https://github.com/angular/angular/commit/3f257e9))
* **language-service:** Preserve CRLF in templates for language-service ([#33241](https://github.com/angular/angular/issues/33241)) ([65a0d2b](https://github.com/angular/angular/commit/65a0d2b)) * **language-service:** Preserve CRLF in templates for language-service ([#33241](https://github.com/angular/angular/issues/33241)) ([65a0d2b](https://github.com/angular/angular/commit/65a0d2b))
* **ngcc:** do not fail when multiple workers try to create the same directory ([#33237](https://github.com/angular/angular/issues/33237)) ([8017229](https://github.com/angular/angular/commit/8017229)), closes [/github.com/angular/angular/pull/33049#issuecomment-540485703](https://github.com/angular/angular/pull/33049#issuecomment-540485703) * **ngcc:** do not fail when multiple workers try to create the same directory ([#33237](https://github.com/angular/angular/issues/33237)) ([8017229](https://github.com/angular/angular/commit/8017229)), closes [/github.com/angular/angular/pull/33049#issuecomment-540485703](https://github.com/angular/angular/pull/33049/issues/issuecomment-540485703)
* **bazel:** Remove angular devkit and restore ngc postinstall ([#32946](https://github.com/angular/angular/issues/32946)) ([f036684](https://github.com/angular/angular/commit/f036684)) * **bazel:** Remove angular devkit and restore ngc postinstall ([#32946](https://github.com/angular/angular/issues/32946)) ([f036684](https://github.com/angular/angular/commit/f036684))
* **common:** remove deprecated support for intl API ([#29250](https://github.com/angular/angular/issues/29250)) ([9e7668f](https://github.com/angular/angular/commit/9e7668f)), closes [#18284](https://github.com/angular/angular/issues/18284) * **common:** remove deprecated support for intl API ([#29250](https://github.com/angular/angular/issues/29250)) ([9e7668f](https://github.com/angular/angular/commit/9e7668f)), closes [#18284](https://github.com/angular/angular/issues/18284)
* **compiler:** absolute source span for template attribute expressions ([#33189](https://github.com/angular/angular/issues/33189)) ([fd4fed1](https://github.com/angular/angular/commit/fd4fed1)) * **compiler:** absolute source span for template attribute expressions ([#33189](https://github.com/angular/angular/issues/33189)) ([fd4fed1](https://github.com/angular/angular/commit/fd4fed1))
@ -1355,7 +1431,7 @@ To learn about the release highlights and our CLI-powered automated update workf
* **language-service:** Turn on strict mode for test project ([#32783](https://github.com/angular/angular/issues/32783)) ([28358b6](https://github.com/angular/angular/commit/28358b6)) * **language-service:** Turn on strict mode for test project ([#32783](https://github.com/angular/angular/issues/32783)) ([28358b6](https://github.com/angular/angular/commit/28358b6))
* **ngcc:** ensure private exports are added for `ModuleWithProviders` ([#32902](https://github.com/angular/angular/issues/32902)) ([002a97d](https://github.com/angular/angular/commit/002a97d)) * **ngcc:** ensure private exports are added for `ModuleWithProviders` ([#32902](https://github.com/angular/angular/issues/32902)) ([002a97d](https://github.com/angular/angular/commit/002a97d))
* **ngcc:** handle presence of both `ctorParameters` and `__decorate` ([#32901](https://github.com/angular/angular/issues/32901)) ([747f0cf](https://github.com/angular/angular/commit/747f0cf)) * **ngcc:** handle presence of both `ctorParameters` and `__decorate` ([#32901](https://github.com/angular/angular/issues/32901)) ([747f0cf](https://github.com/angular/angular/commit/747f0cf))
* **ngcc:** make the build-marker error more clear ([#32712](https://github.com/angular/angular/issues/32712)) ([0ea4875](https://github.com/angular/angular/commit/0ea4875)), closes [31354#issuecomment-532080537](https://github.com/angular/angular/issues/31354#issuecomment-532080537) * **ngcc:** make the build-marker error more clear ([#32712](https://github.com/angular/angular/issues/32712)) ([0ea4875](https://github.com/angular/angular/commit/0ea4875)), closes [/github.com/angular/angular/issues/31354#issuecomment-532080537](https://github.com/angular/angular/issues/31354/issues/issuecomment-532080537)
* **upgrade:** fix AngularJsUrlCodec to support Safari ([#32959](https://github.com/angular/angular/issues/32959)) ([39e8ceb](https://github.com/angular/angular/commit/39e8ceb)) * **upgrade:** fix AngularJsUrlCodec to support Safari ([#32959](https://github.com/angular/angular/issues/32959)) ([39e8ceb](https://github.com/angular/angular/commit/39e8ceb))
* **ivy:** ensure `window.ng.getDebugNode` returns debug info for component elements ([#32780](https://github.com/angular/angular/issues/32780)) ([5651fa3](https://github.com/angular/angular/commit/5651fa3)) * **ivy:** ensure `window.ng.getDebugNode` returns debug info for component elements ([#32780](https://github.com/angular/angular/issues/32780)) ([5651fa3](https://github.com/angular/angular/commit/5651fa3))
* **ivy:** ensure multiple map-based bindings do not skip intermediate values ([#32774](https://github.com/angular/angular/issues/32774)) ([86fd571](https://github.com/angular/angular/commit/86fd571)) * **ivy:** ensure multiple map-based bindings do not skip intermediate values ([#32774](https://github.com/angular/angular/issues/32774)) ([86fd571](https://github.com/angular/angular/commit/86fd571))
@ -1464,7 +1540,7 @@ To learn about the release highlights and our CLI-powered automated update workf
* **ivy:** graceful evaluation of unknown or invalid expressions ([#33453](https://github.com/angular/angular/issues/33453)) ([ce30888](https://github.com/angular/angular/commit/ce30888)) * **ivy:** graceful evaluation of unknown or invalid expressions ([#33453](https://github.com/angular/angular/issues/33453)) ([ce30888](https://github.com/angular/angular/commit/ce30888))
* **ivy:** implement unknown element detection in jit mode ([#33419](https://github.com/angular/angular/issues/33419)) ([c83f501](https://github.com/angular/angular/commit/c83f501)) * **ivy:** implement unknown element detection in jit mode ([#33419](https://github.com/angular/angular/issues/33419)) ([c83f501](https://github.com/angular/angular/commit/c83f501))
* add a flag in bootstrap to enable coalesce event change detection to improve performance ([#30533](https://github.com/angular/angular/issues/30533)) ([44623a1](https://github.com/angular/angular/commit/44623a1)) * add a flag in bootstrap to enable coalesce event change detection to improve performance ([#30533](https://github.com/angular/angular/issues/30533)) ([44623a1](https://github.com/angular/angular/commit/44623a1))
* **bazel:** update [@bazel](https://github.com/bazel)/schematics to Bazel 1.0.0 ([#33476](https://github.com/angular/angular/issues/33476)) ([540d104](https://github.com/angular/angular/commit/540d104)), closes [/github.com/angular/angular/pull/33367#issuecomment-547643246](https://github.com/angular/angular/pull/33367#issuecomment-547643246) * **bazel:** update [@bazel](https://github.com/bazel)/schematics to Bazel 1.0.0 ([#33476](https://github.com/angular/angular/issues/33476)) ([540d104](https://github.com/angular/angular/commit/540d104)), closes [/github.com/angular/angular/pull/33367#issuecomment-547643246](https://github.com/angular/angular/pull/33367/issues/issuecomment-547643246)
* **bazel:** update bazel-schematics to use Ivy and new rollup_bundle ([#33435](https://github.com/angular/angular/issues/33435)) ([bf913cc](https://github.com/angular/angular/commit/bf913cc)) * **bazel:** update bazel-schematics to use Ivy and new rollup_bundle ([#33435](https://github.com/angular/angular/issues/33435)) ([bf913cc](https://github.com/angular/angular/commit/bf913cc))
* **ivy:** i18n - support inlining of XTB formatted translation files ([#33444](https://github.com/angular/angular/issues/33444)) ([2c623fd](https://github.com/angular/angular/commit/2c623fd)) * **ivy:** i18n - support inlining of XTB formatted translation files ([#33444](https://github.com/angular/angular/issues/33444)) ([2c623fd](https://github.com/angular/angular/commit/2c623fd))
* **language-service:** add support for text replacement ([#33091](https://github.com/angular/angular/issues/33091)) ([da4eb91](https://github.com/angular/angular/commit/da4eb91)) * **language-service:** add support for text replacement ([#33091](https://github.com/angular/angular/issues/33091)) ([da4eb91](https://github.com/angular/angular/commit/da4eb91))
@ -1506,7 +1582,7 @@ To learn about the release highlights and our CLI-powered automated update workf
* **ivy:** i18n - implement compile-time inlining ([#32881](https://github.com/angular/angular/issues/32881)) ([2cdb3a0](https://github.com/angular/angular/commit/2cdb3a0)) * **ivy:** i18n - implement compile-time inlining ([#32881](https://github.com/angular/angular/issues/32881)) ([2cdb3a0](https://github.com/angular/angular/commit/2cdb3a0))
* **ivy:** i18n - render legacy message ids in `$localize` if requested ([#32937](https://github.com/angular/angular/issues/32937)) ([bcbf3e4](https://github.com/angular/angular/commit/bcbf3e4)) * **ivy:** i18n - render legacy message ids in `$localize` if requested ([#32937](https://github.com/angular/angular/issues/32937)) ([bcbf3e4](https://github.com/angular/angular/commit/bcbf3e4))
* **language-service:** module definitions on directive hover ([#32763](https://github.com/angular/angular/issues/32763)) ([0d186dd](https://github.com/angular/angular/commit/0d186dd)), closes [#32565](https://github.com/angular/angular/issues/32565) * **language-service:** module definitions on directive hover ([#32763](https://github.com/angular/angular/issues/32763)) ([0d186dd](https://github.com/angular/angular/commit/0d186dd)), closes [#32565](https://github.com/angular/angular/issues/32565)
* **ngcc:** expose `--create-ivy-entry-points` option on ivy-ngcc ([#33049](https://github.com/angular/angular/issues/33049)) ([b2b917d](https://github.com/angular/angular/commit/b2b917d)), closes [/github.com/angular/angular/pull/32999#issuecomment-539937368](https://github.com/angular/angular/pull/32999#issuecomment-539937368) * **ngcc:** expose `--create-ivy-entry-points` option on ivy-ngcc ([#33049](https://github.com/angular/angular/issues/33049)) ([b2b917d](https://github.com/angular/angular/commit/b2b917d)), closes [/github.com/angular/angular/pull/32999#issuecomment-539937368](https://github.com/angular/angular/pull/32999/issues/issuecomment-539937368)
* update rxjs peerDependencies minimum requirment to 6.5.3 ([#32812](https://github.com/angular/angular/issues/32812)) ([66658c4](https://github.com/angular/angular/commit/66658c4)) * update rxjs peerDependencies minimum requirment to 6.5.3 ([#32812](https://github.com/angular/angular/issues/32812)) ([66658c4](https://github.com/angular/angular/commit/66658c4))
* **ivy:** support ng-add in localize package ([#32791](https://github.com/angular/angular/issues/32791)) ([e41cbfb](https://github.com/angular/angular/commit/e41cbfb)) * **ivy:** support ng-add in localize package ([#32791](https://github.com/angular/angular/issues/32791)) ([e41cbfb](https://github.com/angular/angular/commit/e41cbfb))
* **language-service:** allow retreiving synchronized analyzed NgModules ([#32779](https://github.com/angular/angular/issues/32779)) ([98feee7](https://github.com/angular/angular/commit/98feee7)) * **language-service:** allow retreiving synchronized analyzed NgModules ([#32779](https://github.com/angular/angular/issues/32779)) ([98feee7](https://github.com/angular/angular/commit/98feee7))
@ -1885,7 +1961,6 @@ This release contains various API docs improvements.
* **language-service:** Eagarly initialize data members ([#31577](https://github.com/angular/angular/issues/31577)) ([0110de2](https://github.com/angular/angular/commit/0110de2)) * **language-service:** Eagarly initialize data members ([#31577](https://github.com/angular/angular/issues/31577)) ([0110de2](https://github.com/angular/angular/commit/0110de2))
* **bazel:** revert location of xi18n outputs to bazel-genfiles ([#31410](https://github.com/angular/angular/issues/31410)) ([1d3e227](https://github.com/angular/angular/commit/1d3e227)) * **bazel:** revert location of xi18n outputs to bazel-genfiles ([#31410](https://github.com/angular/angular/issues/31410)) ([1d3e227](https://github.com/angular/angular/commit/1d3e227))
* **compiler:** give ASTWithSource its own visit method ([#31347](https://github.com/angular/angular/issues/31347)) ([6aaca21](https://github.com/angular/angular/commit/6aaca21)) * **compiler:** give ASTWithSource its own visit method ([#31347](https://github.com/angular/angular/issues/31347)) ([6aaca21](https://github.com/angular/angular/commit/6aaca21))
* **core:** handle `undefined` meta in `injectArgs` ([#31333](https://github.com/angular/angular/issues/31333)) ([80ccd6c](https://github.com/angular/angular/commit/80ccd6c)), closes [CLI #14888](https://github.com/angular/angular-cli/issues/14888)
* **service-worker:** cache opaque responses in data groups with `freshness` strategy ([#30977](https://github.com/angular/angular/issues/30977)) ([d7be38f](https://github.com/angular/angular/commit/d7be38f)), closes [#30968](https://github.com/angular/angular/issues/30968) * **service-worker:** cache opaque responses in data groups with `freshness` strategy ([#30977](https://github.com/angular/angular/issues/30977)) ([d7be38f](https://github.com/angular/angular/commit/d7be38f)), closes [#30968](https://github.com/angular/angular/issues/30968)
* **service-worker:** cache opaque responses when requests exceeds timeout threshold ([#30977](https://github.com/angular/angular/issues/30977)) ([93abc35](https://github.com/angular/angular/commit/93abc35)) * **service-worker:** cache opaque responses when requests exceeds timeout threshold ([#30977](https://github.com/angular/angular/issues/30977)) ([93abc35](https://github.com/angular/angular/commit/93abc35))
@ -1915,7 +1990,6 @@ This release contains various API docs improvements.
* use the correct WTF array to iterate over ([#31208](https://github.com/angular/angular/issues/31208)) ([4aed480](https://github.com/angular/angular/commit/4aed480)) * use the correct WTF array to iterate over ([#31208](https://github.com/angular/angular/issues/31208)) ([4aed480](https://github.com/angular/angular/commit/4aed480))
* **compiler-cli:** Return original sourceFile instead of redirected sourceFile from getSourceFile ([#26036](https://github.com/angular/angular/issues/26036)) ([13dbb98](https://github.com/angular/angular/commit/13dbb98)), closes [#22524](https://github.com/angular/angular/issues/22524) * **compiler-cli:** Return original sourceFile instead of redirected sourceFile from getSourceFile ([#26036](https://github.com/angular/angular/issues/26036)) ([13dbb98](https://github.com/angular/angular/commit/13dbb98)), closes [#22524](https://github.com/angular/angular/issues/22524)
* **core:** export provider interfaces that are part of the public API types ([#31377](https://github.com/angular/angular/issues/31377)) ([bebf089](https://github.com/angular/angular/commit/bebf089)), closes [/github.com/angular/angular/pull/31377#discussion_r299254408](https://github.com/angular/angular/pull/31377/issues/discussion_r299254408) [/github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts#L365-L366](https://github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts/issues/L365-L366) [/github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts#L283-L284](https://github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts/issues/L283-L284) [/github.com/angular/angular/blob/9e34670b2/packages/core/src/di/index.ts#L23](https://github.com/angular/angular/blob/9e34670b2/packages/core/src/di/index.ts/issues/L23)
<a name="8.1.1"></a> <a name="8.1.1"></a>
@ -2093,7 +2167,6 @@ To learn about the release highlights and our CLI-powered automated update workf
### Features ### Features
* add support for TypeScript 3.4 (and drop older versions) ([#29372](https://github.com/angular/angular/issues/29372)) ([ef85336](https://github.com/angular/angular/commit/ef85336)) * add support for TypeScript 3.4 (and drop older versions) ([#29372](https://github.com/angular/angular/issues/29372)) ([ef85336](https://github.com/angular/angular/commit/ef85336))
* **common:** add ability to watch for AngularJS URL updates through `onUrlChange` hook ([#30466](https://github.com/angular/angular/issues/30466)) ([8022d36](https://github.com/angular/angular/commit/8022d36))
* **common:** stricter types for `SlicePipe` ([#30156](https://github.com/angular/angular/issues/30156)) ([722b2fa](https://github.com/angular/angular/commit/722b2fa)) * **common:** stricter types for `SlicePipe` ([#30156](https://github.com/angular/angular/issues/30156)) ([722b2fa](https://github.com/angular/angular/commit/722b2fa))
* **bazel:** use `rbe_autoconfig()` and new container ([#29336](https://github.com/angular/angular/issues/29336)) ([e562acc](https://github.com/angular/angular/commit/e562acc)) * **bazel:** use `rbe_autoconfig()` and new container ([#29336](https://github.com/angular/angular/issues/29336)) ([e562acc](https://github.com/angular/angular/commit/e562acc))
* **common:** add @angular/common/upgrade package for `$location`-related APIs ([#30055](https://github.com/angular/angular/issues/30055)) ([152d99e](https://github.com/angular/angular/commit/152d99e)) * **common:** add @angular/common/upgrade package for `$location`-related APIs ([#30055](https://github.com/angular/angular/issues/30055)) ([152d99e](https://github.com/angular/angular/commit/152d99e))
@ -2210,8 +2283,6 @@ To learn about the release highlights and our CLI-powered automated update workf
* **bazel:** use `//:tsconfig.json` as the default for `ng_module` ([#29670](https://github.com/angular/angular/issues/29670)) ([b14537a](https://github.com/angular/angular/commit/b14537a)) * **bazel:** use `//:tsconfig.json` as the default for `ng_module` ([#29670](https://github.com/angular/angular/issues/29670)) ([b14537a](https://github.com/angular/angular/commit/b14537a))
* **compiler-cli:** ngcc - cope with processing entry-points multiple times ([#29657](https://github.com/angular/angular/issues/29657)) ([6b39c9c](https://github.com/angular/angular/commit/6b39c9c)) * **compiler-cli:** ngcc - cope with processing entry-points multiple times ([#29657](https://github.com/angular/angular/issues/29657)) ([6b39c9c](https://github.com/angular/angular/commit/6b39c9c))
* **core:** static-query schematic should detect static queries in getters. ([#29609](https://github.com/angular/angular/issues/29609)) ([33016b8](https://github.com/angular/angular/commit/33016b8)) * **core:** static-query schematic should detect static queries in getters. ([#29609](https://github.com/angular/angular/issues/29609)) ([33016b8](https://github.com/angular/angular/commit/33016b8))
* **common:** escape query selector used when anchor scrolling ([#29577](https://github.com/angular/angular/issues/29577)) ([7671c73](https://github.com/angular/angular/commit/7671c73)), closes [#28193](https://github.com/angular/angular/issues/28193)
* **router:** adjust setting navigationTransition when a new navigation cancels an existing one ([#29636](https://github.com/angular/angular/issues/29636)) ([e884c0c](https://github.com/angular/angular/commit/e884c0c)), closes [#29389](https://github.com/angular/angular/issues/29389) [#29590](https://github.com/angular/angular/issues/29590)
* **bazel:** allow `ng_module` users to set `createExternalSymbolFactoryReexports` ([#29459](https://github.com/angular/angular/issues/29459)) ([21be0fb](https://github.com/angular/angular/commit/21be0fb)) * **bazel:** allow `ng_module` users to set `createExternalSymbolFactoryReexports` ([#29459](https://github.com/angular/angular/issues/29459)) ([21be0fb](https://github.com/angular/angular/commit/21be0fb))
* **bazel:** workaround problem reading summary files from node_modules ([#29459](https://github.com/angular/angular/issues/29459)) ([769d960](https://github.com/angular/angular/commit/769d960)) * **bazel:** workaround problem reading summary files from node_modules ([#29459](https://github.com/angular/angular/issues/29459)) ([769d960](https://github.com/angular/angular/commit/769d960))
* **compiler:** inherit param types when class has a constructor which takes no declared parameters and delegates up ([#29232](https://github.com/angular/angular/issues/29232)) ([0007564](https://github.com/angular/angular/commit/0007564)) * **compiler:** inherit param types when class has a constructor which takes no declared parameters and delegates up ([#29232](https://github.com/angular/angular/issues/29232)) ([0007564](https://github.com/angular/angular/commit/0007564))
@ -2238,7 +2309,7 @@ To learn about the release highlights and our CLI-powered automated update workf
* **platform-server:** update minimum domino version to latest released ([#28893](https://github.com/angular/angular/issues/28893)) ([79e2ca0](https://github.com/angular/angular/commit/79e2ca0)) * **platform-server:** update minimum domino version to latest released ([#28893](https://github.com/angular/angular/issues/28893)) ([79e2ca0](https://github.com/angular/angular/commit/79e2ca0))
* **router:** removed obsolete TODO comment ([#29085](https://github.com/angular/angular/issues/29085)) ([72ecc45](https://github.com/angular/angular/commit/72ecc45)) * **router:** removed obsolete TODO comment ([#29085](https://github.com/angular/angular/issues/29085)) ([72ecc45](https://github.com/angular/angular/commit/72ecc45))
* **service-worker:** detect new version even if files are identical to an old one ([#26006](https://github.com/angular/angular/issues/26006)) ([586234b](https://github.com/angular/angular/commit/586234b)), closes [#24338](https://github.com/angular/angular/issues/24338) * **service-worker:** detect new version even if files are identical to an old one ([#26006](https://github.com/angular/angular/issues/26006)) ([586234b](https://github.com/angular/angular/commit/586234b)), closes [#24338](https://github.com/angular/angular/issues/24338)
* **service-worker:** ignore passive mixed content requests ([#25994](https://github.com/angular/angular/issues/25994)) ([48214e2](https://github.com/angular/angular/commit/48214e2)), closes [23012#issuecomment-376430187](https://github.com/angular/angular/issues/23012#issuecomment-376430187) [#23012](https://github.com/angular/angular/issues/23012) * **service-worker:** ignore passive mixed content requests ([#25994](https://github.com/angular/angular/issues/25994)) ([48214e2](https://github.com/angular/angular/commit/48214e2)), closes [/github.com/angular/angular/issues/23012#issuecomment-376430187](https://github.com/angular/angular/issues/23012/issues/issuecomment-376430187) [#23012](https://github.com/angular/angular/issues/23012)
* **bazel:** Pin browsers for schematics ([#28913](https://github.com/angular/angular/issues/28913)) ([1145bdb](https://github.com/angular/angular/commit/1145bdb)) * **bazel:** Pin browsers for schematics ([#28913](https://github.com/angular/angular/issues/28913)) ([1145bdb](https://github.com/angular/angular/commit/1145bdb))
* **bazel:** rxjs_umd_modules should always be present ([#28881](https://github.com/angular/angular/issues/28881)) ([9ae14db](https://github.com/angular/angular/commit/9ae14db)) * **bazel:** rxjs_umd_modules should always be present ([#28881](https://github.com/angular/angular/issues/28881)) ([9ae14db](https://github.com/angular/angular/commit/9ae14db))
* **compiler:** use correct variable in invalid function ([#28656](https://github.com/angular/angular/issues/28656)) ([f75acbd](https://github.com/angular/angular/commit/f75acbd)) * **compiler:** use correct variable in invalid function ([#28656](https://github.com/angular/angular/issues/28656)) ([f75acbd](https://github.com/angular/angular/commit/f75acbd))
@ -2300,7 +2371,6 @@ To learn about the release highlights and our CLI-powered automated update workf
* **core:** deprecate integration with the Web Tracing Framework (WTF) ([#30642](https://github.com/angular/angular/issues/30642)) ([b408445](https://github.com/angular/angular/commit/b408445)) * **core:** deprecate integration with the Web Tracing Framework (WTF) ([#30642](https://github.com/angular/angular/issues/30642)) ([b408445](https://github.com/angular/angular/commit/b408445))
* **platform-webworker:** deprecate platform-webworker ([#30642](https://github.com/angular/angular/issues/30642)) ([361f181](https://github.com/angular/angular/commit/361f181)) * **platform-webworker:** deprecate platform-webworker ([#30642](https://github.com/angular/angular/issues/30642)) ([361f181](https://github.com/angular/angular/commit/361f181))
* `TestBed.get()` has two signatures, one which is typed and another which accepts and returns `any`. The signature for `any` is deprecated; all usage of `TestBed.get()` should go through the typed API. This mainly affects string tokens
(which aren't supported) and abstract class tokens. (which aren't supported) and abstract class tokens.
Before: Before:
@ -2453,7 +2523,7 @@ This release contains various API docs improvements.
* **animations:** ensure `position` and `display` styles are handled outside of keyframes/web-animations ([#28911](https://github.com/angular/angular/issues/28911)) ([86981b3](https://github.com/angular/angular/commit/86981b3)), closes [#24923](https://github.com/angular/angular/issues/24923) [#25635](https://github.com/angular/angular/issues/25635) * **animations:** ensure `position` and `display` styles are handled outside of keyframes/web-animations ([#28911](https://github.com/angular/angular/issues/28911)) ([86981b3](https://github.com/angular/angular/commit/86981b3)), closes [#24923](https://github.com/angular/angular/issues/24923) [#25635](https://github.com/angular/angular/issues/25635)
* **router:** removed obsolete TODO comment ([#29085](https://github.com/angular/angular/issues/29085)) ([2a25ac2](https://github.com/angular/angular/commit/2a25ac2)) * **router:** removed obsolete TODO comment ([#29085](https://github.com/angular/angular/issues/29085)) ([2a25ac2](https://github.com/angular/angular/commit/2a25ac2))
* **service-worker:** detect new version even if files are identical to an old one ([#26006](https://github.com/angular/angular/issues/26006)) ([5669333](https://github.com/angular/angular/commit/5669333)), closes [#24338](https://github.com/angular/angular/issues/24338) * **service-worker:** detect new version even if files are identical to an old one ([#26006](https://github.com/angular/angular/issues/26006)) ([5669333](https://github.com/angular/angular/commit/5669333)), closes [#24338](https://github.com/angular/angular/issues/24338)
* **service-worker:** ignore passive mixed content requests ([#25994](https://github.com/angular/angular/issues/25994)) ([b598e88](https://github.com/angular/angular/commit/b598e88)), closes [23012#issuecomment-376430187](https://github.com/angular/angular/issues/23012#issuecomment-376430187) [#23012](https://github.com/angular/angular/issues/23012) * **service-worker:** ignore passive mixed content requests ([#25994](https://github.com/angular/angular/issues/25994)) ([b598e88](https://github.com/angular/angular/commit/b598e88)), closes [/github.com/angular/angular/issues/23012#issuecomment-376430187](https://github.com/angular/angular/issues/23012/issues/issuecomment-376430187) [#23012](https://github.com/angular/angular/issues/23012)
<a name="7.2.7"></a> <a name="7.2.7"></a>
@ -2549,14 +2619,6 @@ This release contains various API docs improvements.
# [8.0.0-beta.0](https://github.com/angular/angular/compare/7.2.0...8.0.0-beta.0) (2019-01-16) # [8.0.0-beta.0](https://github.com/angular/angular/compare/7.2.0...8.0.0-beta.0) (2019-01-16)
### Bug Fixes
### Features
### Performance Improvements ### Performance Improvements
@ -2704,42 +2766,9 @@ This release contains various API docs improvements.
# [7.1.0](https://github.com/angular/angular/compare/7.1.0-rc.0...7.1.0) (2018-11-21) # [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/core to @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 ### Features
* **bazel:** Bazel workspace schematics ([#26971](https://github.com/angular/angular/issues/26971)) ([b07bd30](https://github.com/angular/angular/commit/b07bd30)) * **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> <a name="7.1.0-rc.0"></a>
@ -2842,10 +2871,7 @@ This release contains various API docs improvements.
### Bug Fixes ### 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)) * **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 ### Features
@ -3017,7 +3043,6 @@ Note: the 6.1.5 release on npm accidentally glitched-out midway, so we cut 6.1.6
### Bug Fixes ### Bug Fixes
* **animations:** always render end-state styles for orphaned DOM nodes ([#24236](https://github.com/angular/angular/issues/24236)) ([dc4a3d0](https://github.com/angular/angular/commit/dc4a3d0)) * **animations:** always render end-state styles for orphaned DOM nodes ([#24236](https://github.com/angular/angular/issues/24236)) ([dc4a3d0](https://github.com/angular/angular/commit/dc4a3d0))
* **animations:** set animations styles properly on platform-server ([#24624](https://github.com/angular/angular/issues/24624)) ([0b356d4](https://github.com/angular/angular/commit/0b356d4))
* **animations:** do not throw errors when a destroyed component is animated ([#23836](https://github.com/angular/angular/issues/23836)) ([d2a8687](https://github.com/angular/angular/commit/d2a8687)) * **animations:** do not throw errors when a destroyed component is animated ([#23836](https://github.com/angular/angular/issues/23836)) ([d2a8687](https://github.com/angular/angular/commit/d2a8687))
* **animations:** Fix browser detection logic ([#24188](https://github.com/angular/angular/issues/24188)) ([b492b9e](https://github.com/angular/angular/commit/b492b9e)) * **animations:** Fix browser detection logic ([#24188](https://github.com/angular/angular/issues/24188)) ([b492b9e](https://github.com/angular/angular/commit/b492b9e))
* **animations:** properly clean up queried element styles in safari/edge ([#23633](https://github.com/angular/angular/issues/23633)) ([da9ff25](https://github.com/angular/angular/commit/da9ff25)) * **animations:** properly clean up queried element styles in safari/edge ([#23633](https://github.com/angular/angular/issues/23633)) ([da9ff25](https://github.com/angular/angular/commit/da9ff25))
@ -3029,7 +3054,6 @@ Note: the 6.1.5 release on npm accidentally glitched-out midway, so we cut 6.1.6
* **common:** format fractional seconds ([#24844](https://github.com/angular/angular/issues/24844)) ([0b4d85e](https://github.com/angular/angular/commit/0b4d85e)), closes [#24831](https://github.com/angular/angular/issues/24831) * **common:** format fractional seconds ([#24844](https://github.com/angular/angular/issues/24844)) ([0b4d85e](https://github.com/angular/angular/commit/0b4d85e)), closes [#24831](https://github.com/angular/angular/issues/24831)
* **common:** properly update collection reference in NgForOf ([#24684](https://github.com/angular/angular/issues/24684)) ([ff84c5c](https://github.com/angular/angular/commit/ff84c5c)), closes [#24155](https://github.com/angular/angular/issues/24155) * **common:** properly update collection reference in NgForOf ([#24684](https://github.com/angular/angular/issues/24684)) ([ff84c5c](https://github.com/angular/angular/commit/ff84c5c)), closes [#24155](https://github.com/angular/angular/issues/24155)
* **common:** use correct currency format for locale de-AT ([#24658](https://github.com/angular/angular/issues/24658)) ([dcabb05](https://github.com/angular/angular/commit/dcabb05)), closes [#24609](https://github.com/angular/angular/issues/24609) * **common:** use correct currency format for locale de-AT ([#24658](https://github.com/angular/angular/issues/24658)) ([dcabb05](https://github.com/angular/angular/commit/dcabb05)), closes [#24609](https://github.com/angular/angular/issues/24609)
* **common:** use correct ICU plural for locale mk ([#24659](https://github.com/angular/angular/issues/24659)) ([64a8584](https://github.com/angular/angular/commit/64a8584))
* **compiler:** fix a few non-tree-shakeable code patterns ([#24677](https://github.com/angular/angular/issues/24677)) ([50d4a4f](https://github.com/angular/angular/commit/50d4a4f)) * **compiler:** fix a few non-tree-shakeable code patterns ([#24677](https://github.com/angular/angular/issues/24677)) ([50d4a4f](https://github.com/angular/angular/commit/50d4a4f))
* **compiler:** i18n_extractor now outputs the correct source file name ([#24885](https://github.com/angular/angular/issues/24885)) ([c8ad965](https://github.com/angular/angular/commit/c8ad965)), closes [#24884](https://github.com/angular/angular/issues/24884) * **compiler:** i18n_extractor now outputs the correct source file name ([#24885](https://github.com/angular/angular/issues/24885)) ([c8ad965](https://github.com/angular/angular/commit/c8ad965)), closes [#24884](https://github.com/angular/angular/issues/24884)
* **compiler:** support `.` in import statements. ([#20634](https://github.com/angular/angular/issues/20634)) ([d8f7b29](https://github.com/angular/angular/commit/d8f7b29)), closes [#20363](https://github.com/angular/angular/issues/20363) * **compiler:** support `.` in import statements. ([#20634](https://github.com/angular/angular/issues/20634)) ([d8f7b29](https://github.com/angular/angular/commit/d8f7b29)), closes [#20363](https://github.com/angular/angular/issues/20363)
@ -3065,7 +3089,6 @@ Note: the 6.1.5 release on npm accidentally glitched-out midway, so we cut 6.1.6
* **service-worker:** don't include sourceMappingURL in ngsw-worker ([#24877](https://github.com/angular/angular/issues/24877)) ([8620373](https://github.com/angular/angular/commit/8620373)), closes [#23596](https://github.com/angular/angular/issues/23596) * **service-worker:** don't include sourceMappingURL in ngsw-worker ([#24877](https://github.com/angular/angular/issues/24877)) ([8620373](https://github.com/angular/angular/commit/8620373)), closes [#23596](https://github.com/angular/angular/issues/23596)
* **service-worker:** avoid network requests when looking up hashed resources in cache ([#24127](https://github.com/angular/angular/issues/24127)) ([52d43a9](https://github.com/angular/angular/commit/52d43a9)) * **service-worker:** avoid network requests when looking up hashed resources in cache ([#24127](https://github.com/angular/angular/issues/24127)) ([52d43a9](https://github.com/angular/angular/commit/52d43a9))
* **service-worker:** fix `SwPush.unsubscribe()` ([#24162](https://github.com/angular/angular/issues/24162)) ([3ed2d75](https://github.com/angular/angular/commit/3ed2d75)), closes [#24095](https://github.com/angular/angular/issues/24095) * **service-worker:** fix `SwPush.unsubscribe()` ([#24162](https://github.com/angular/angular/issues/24162)) ([3ed2d75](https://github.com/angular/angular/commit/3ed2d75)), closes [#24095](https://github.com/angular/angular/issues/24095)
* **service-worker:** add badge to NOTIFICATION_OPTION_NAMES ([#23241](https://github.com/angular/angular/issues/23241)) ([fb59b2d](https://github.com/angular/angular/commit/fb59b2d)), closes [#23196](https://github.com/angular/angular/issues/23196)
* **service-worker:** check platformBrowser before accessing navigator.serviceWorker ([#21231](https://github.com/angular/angular/issues/21231)) ([0bdd30e](https://github.com/angular/angular/commit/0bdd30e)) * **service-worker:** check platformBrowser before accessing navigator.serviceWorker ([#21231](https://github.com/angular/angular/issues/21231)) ([0bdd30e](https://github.com/angular/angular/commit/0bdd30e))
* **service-worker:** correctly handle requests with empty `clientId` ([#23625](https://github.com/angular/angular/issues/23625)) ([e0ed59e](https://github.com/angular/angular/commit/e0ed59e)), closes [#23526](https://github.com/angular/angular/issues/23526) * **service-worker:** correctly handle requests with empty `clientId` ([#23625](https://github.com/angular/angular/issues/23625)) ([e0ed59e](https://github.com/angular/angular/commit/e0ed59e)), closes [#23526](https://github.com/angular/angular/issues/23526)
* **service-worker:** deprecate `versionedFiles` in asset-group resources ([#23584](https://github.com/angular/angular/issues/23584)) ([1d378e2](https://github.com/angular/angular/commit/1d378e2)) * **service-worker:** deprecate `versionedFiles` in asset-group resources ([#23584](https://github.com/angular/angular/issues/23584)) ([1d378e2](https://github.com/angular/angular/commit/1d378e2))
@ -3266,8 +3289,6 @@ To learn about the release highlights and our new CLI-powered update workflow fo
* **forms:** multiple validators for array method ([#20766](https://github.com/angular/angular/issues/20766)) ([941e88f](https://github.com/angular/angular/commit/941e88f)), closes [#20665](https://github.com/angular/angular/issues/20665) * **forms:** multiple validators for array method ([#20766](https://github.com/angular/angular/issues/20766)) ([941e88f](https://github.com/angular/angular/commit/941e88f)), closes [#20665](https://github.com/angular/angular/issues/20665)
* **forms:** allow markAsPending to emit events ([#20212](https://github.com/angular/angular/issues/20212)) ([e86b64b](https://github.com/angular/angular/commit/e86b64b)), closes [#17958](https://github.com/angular/angular/issues/17958) * **forms:** allow markAsPending to emit events ([#20212](https://github.com/angular/angular/issues/20212)) ([e86b64b](https://github.com/angular/angular/commit/e86b64b)), closes [#17958](https://github.com/angular/angular/issues/17958)
* **platform-browser:** add token marking which the type of animation module nearest in the injector tree ([#23075](https://github.com/angular/angular/issues/23075)) ([b551f84](https://github.com/angular/angular/commit/b551f84)) * **platform-browser:** add token marking which the type of animation module nearest in the injector tree ([#23075](https://github.com/angular/angular/issues/23075)) ([b551f84](https://github.com/angular/angular/commit/b551f84))
* **platform-browser:** do not throw error when Hammer.js not loaded ([#22257](https://github.com/angular/angular/issues/22257)) ([991300b](https://github.com/angular/angular/commit/991300b)), closes [#16992](https://github.com/angular/angular/issues/16992)
* **platform-browser:** fix [#19604](https://github.com/angular/angular/issues/19604), can config hammerOptions ([#21979](https://github.com/angular/angular/issues/21979)) ([1d571b2](https://github.com/angular/angular/commit/1d571b2))
* **platform-server:** bump Domino to v2.0 ([#22411](https://github.com/angular/angular/issues/22411)) ([d3827a0](https://github.com/angular/angular/commit/d3827a0)) * **platform-server:** bump Domino to v2.0 ([#22411](https://github.com/angular/angular/issues/22411)) ([d3827a0](https://github.com/angular/angular/commit/d3827a0))
* **router:** add navigationSource and restoredState to NavigationStart event ([#21728](https://github.com/angular/angular/issues/21728)) ([c40ae7f](https://github.com/angular/angular/commit/c40ae7f)) * **router:** add navigationSource and restoredState to NavigationStart event ([#21728](https://github.com/angular/angular/issues/21728)) ([c40ae7f](https://github.com/angular/angular/commit/c40ae7f))
* **service-worker:** add support for configuring navigations URLs ([#23339](https://github.com/angular/angular/issues/23339)) ([08325aa](https://github.com/angular/angular/commit/08325aa)), closes [#20404](https://github.com/angular/angular/issues/20404) * **service-worker:** add support for configuring navigations URLs ([#23339](https://github.com/angular/angular/issues/23339)) ([08325aa](https://github.com/angular/angular/commit/08325aa)), closes [#20404](https://github.com/angular/angular/issues/20404)
@ -3486,12 +3507,7 @@ To learn about the release highlights and our new CLI-powered update workflow fo
### Bug Fixes ### Bug Fixes
* **platform-server:** generate correct stylings for camel case names ([#22263](https://github.com/angular/angular/issues/22263)) ([de02a7a](https://github.com/angular/angular/commit/de02a7a)), closes [#19235](https://github.com/angular/angular/issues/19235)
* **router:** don't mutate route configs ([#22358](https://github.com/angular/angular/issues/22358)) ([8f0a064](https://github.com/angular/angular/commit/8f0a064)), closes [#22203](https://github.com/angular/angular/issues/22203)
* **router:** fix URL serialization so special characters are only encoded where needed ([#22337](https://github.com/angular/angular/issues/22337)) ([789a47e](https://github.com/angular/angular/commit/789a47e)), closes [#10280](https://github.com/angular/angular/issues/10280) * **router:** fix URL serialization so special characters are only encoded where needed ([#22337](https://github.com/angular/angular/issues/22337)) ([789a47e](https://github.com/angular/angular/commit/789a47e)), closes [#10280](https://github.com/angular/angular/issues/10280)
* **upgrade:** correctly destroy nested downgraded component ([#22400](https://github.com/angular/angular/issues/22400)) ([4aef9de](https://github.com/angular/angular/commit/4aef9de)), closes [#22392](https://github.com/angular/angular/issues/22392)
* **upgrade:** correctly handle `=` bindings in `@angular/upgrade` ([#22167](https://github.com/angular/angular/issues/22167)) ([6638390](https://github.com/angular/angular/commit/6638390))
* **upgrade:** fix empty transclusion content with AngularJS@>=1.5.8 ([#22167](https://github.com/angular/angular/issues/22167)) ([a9a0e27](https://github.com/angular/angular/commit/a9a0e27)), closes [#22175](https://github.com/angular/angular/issues/22175)
@ -3886,15 +3902,6 @@ Note: Due to an animation fix back in 5.1.1 ([c2b3792](https://github.com/angula
<a name="5.1.0-beta.0"></a> <a name="5.1.0-beta.0"></a>
# [5.1.0-beta.0](https://github.com/angular/angular/compare/5.0.0-rc.4...5.1.0-beta.0) (2017-11-08) # [5.1.0-beta.0](https://github.com/angular/angular/compare/5.0.0-rc.4...5.1.0-beta.0) (2017-11-08)
### Bug Fixes
* **compiler:** don't overwrite missingTranslation's value in JIT ([#19952](https://github.com/angular/angular/issues/19952)) ([799cbb9](https://github.com/angular/angular/commit/799cbb9))
* **compiler:** report a reasonable error with invalid metadata ([#20062](https://github.com/angular/angular/issues/20062)) ([da22c48](https://github.com/angular/angular/commit/da22c48))
* **compiler-cli:** don't report emit diagnostics when `--noEmitOnError` is off ([#20063](https://github.com/angular/angular/issues/20063)) ([8639995](https://github.com/angular/angular/commit/8639995))
* **core:** `__symbol__` should return `__zone_symbol__` without zone.js loaded ([#19541](https://github.com/angular/angular/issues/19541)) ([678d1cf](https://github.com/angular/angular/commit/678d1cf))
* **core:** should support event.stopImmediatePropagation ([#19222](https://github.com/angular/angular/issues/19222)) ([7083791](https://github.com/angular/angular/commit/7083791))
* **platform-browser:** support Symbols in custom `jasmineToString()` method ([#19794](https://github.com/angular/angular/issues/19794)) ([5a6efa7](https://github.com/angular/angular/commit/5a6efa7))
### Features ### Features
* **compiler:** introduce `TestBed.overrideTemplateUsingTestingModule` ([a460066](https://github.com/angular/angular/commit/a460066)), closes [#19815](https://github.com/angular/angular/issues/19815) * **compiler:** introduce `TestBed.overrideTemplateUsingTestingModule` ([a460066](https://github.com/angular/angular/commit/a460066)), closes [#19815](https://github.com/angular/angular/issues/19815)
@ -3930,14 +3937,12 @@ Note: Due to an animation fix back in 5.1.1 ([c2b3792](https://github.com/angula
* **compiler-cli:** add watch mode to `ngc` ([#18818](https://github.com/angular/angular/issues/18818)) ([06d01b2](https://github.com/angular/angular/commit/06d01b2)) * **compiler-cli:** add watch mode to `ngc` ([#18818](https://github.com/angular/angular/issues/18818)) ([06d01b2](https://github.com/angular/angular/commit/06d01b2))
* **compiler-cli:** lower metadata `useValue` and `data` literal fields ([#18905](https://github.com/angular/angular/issues/18905)) ([0e64261](https://github.com/angular/angular/commit/0e64261)) * **compiler-cli:** lower metadata `useValue` and `data` literal fields ([#18905](https://github.com/angular/angular/issues/18905)) ([0e64261](https://github.com/angular/angular/commit/0e64261))
* **compiler:** add representation of placeholders to xliff & xmb ([b3085e9](https://github.com/angular/angular/commit/b3085e9)), closes [#17345](https://github.com/angular/angular/issues/17345) * **compiler:** add representation of placeholders to xliff & xmb ([b3085e9](https://github.com/angular/angular/commit/b3085e9)), closes [#17345](https://github.com/angular/angular/issues/17345)
* **compiler:** allow multiple exportAs names ([#18723](https://github.com/angular/angular/issues/18723)) ([7ec28fe](https://github.com/angular/angular/commit/7ec28fe))
* **compiler:** enabled strict checking of parameters to an `@Injectable` ([#19412](https://github.com/angular/angular/issues/19412)) ([dfb8d21](https://github.com/angular/angular/commit/dfb8d21)) * **compiler:** enabled strict checking of parameters to an `@Injectable` ([#19412](https://github.com/angular/angular/issues/19412)) ([dfb8d21](https://github.com/angular/angular/commit/dfb8d21))
* **compiler:** make `.ngsummary.json` files portable ([2572bf5](https://github.com/angular/angular/commit/2572bf5)) * **compiler:** make `.ngsummary.json` files portable ([2572bf5](https://github.com/angular/angular/commit/2572bf5))
* **compiler:** reuse the TypeScript typecheck for template typechecking. ([#19152](https://github.com/angular/angular/issues/19152)) ([996c7c2](https://github.com/angular/angular/commit/996c7c2)) * **compiler:** reuse the TypeScript typecheck for template typechecking. ([#19152](https://github.com/angular/angular/issues/19152)) ([996c7c2](https://github.com/angular/angular/commit/996c7c2))
* **compiler:** set `enableLegacyTemplate` to false by default ([#18756](https://github.com/angular/angular/issues/18756)) ([56238fe](https://github.com/angular/angular/commit/56238fe)) * **compiler:** set `enableLegacyTemplate` to false by default ([#18756](https://github.com/angular/angular/issues/18756)) ([56238fe](https://github.com/angular/angular/commit/56238fe))
* **compiler:** use typescript for resolving resource paths ([43226cb](https://github.com/angular/angular/commit/43226cb)) * **compiler:** use typescript for resolving resource paths ([43226cb](https://github.com/angular/angular/commit/43226cb))
* **core:** Create StaticInjector which does not depend on Reflect polyfill. ([d9d00bd](https://github.com/angular/angular/commit/d9d00bd)) * **core:** Create StaticInjector which does not depend on Reflect polyfill. ([d9d00bd](https://github.com/angular/angular/commit/d9d00bd))
* **core:** add option to remove blank text nodes from compiled templates ([#18823](https://github.com/angular/angular/issues/18823)) ([b8b551c](https://github.com/angular/angular/commit/b8b551c))
* **core:** support for bootstrap with custom zone ([#17672](https://github.com/angular/angular/issues/17672)) ([344a5ca](https://github.com/angular/angular/commit/344a5ca)) * **core:** support for bootstrap with custom zone ([#17672](https://github.com/angular/angular/issues/17672)) ([344a5ca](https://github.com/angular/angular/commit/344a5ca))
* **forms:** add default updateOn values for groups and arrays ([#18536](https://github.com/angular/angular/issues/18536)) ([ff5c58b](https://github.com/angular/angular/commit/ff5c58b)) * **forms:** add default updateOn values for groups and arrays ([#18536](https://github.com/angular/angular/issues/18536)) ([ff5c58b](https://github.com/angular/angular/commit/ff5c58b))
* **forms:** add options arg to abstract controls ([ebef5e6](https://github.com/angular/angular/commit/ebef5e6)) * **forms:** add options arg to abstract controls ([ebef5e6](https://github.com/angular/angular/commit/ebef5e6))
@ -4296,7 +4301,6 @@ Note: the 4.4.0 release on npm accidentally glitched-out midway, so we cut 4.4.1
* **animations:** properly collect :enter nodes that exist within multi-level DOM trees ([40f77cb](https://github.com/angular/angular/commit/40f77cb)), closes [#17632](https://github.com/angular/angular/issues/17632) * **animations:** properly collect :enter nodes that exist within multi-level DOM trees ([40f77cb](https://github.com/angular/angular/commit/40f77cb)), closes [#17632](https://github.com/angular/angular/issues/17632)
* **animations:** compute removal node height correctly ([185075d](https://github.com/angular/angular/commit/185075d)) * **animations:** compute removal node height correctly ([185075d](https://github.com/angular/angular/commit/185075d))
* **animations:** do not treat a `0` animation state as `void` ([451257a](https://github.com/angular/angular/commit/451257a)) * **animations:** do not treat a `0` animation state as `void` ([451257a](https://github.com/angular/angular/commit/451257a))
* **animations:** properly collect :enter nodes in a partially updated collection ([6ca4692](https://github.com/angular/angular/commit/6ca4692)), closes [#17440](https://github.com/angular/angular/issues/17440)
* **animations:** remove duplicate license header ([e096a85](https://github.com/angular/angular/commit/e096a85)) * **animations:** remove duplicate license header ([e096a85](https://github.com/angular/angular/commit/e096a85))
* **common/http:** document HttpClient, fixing a few other issues ([1855989](https://github.com/angular/angular/commit/1855989)) * **common/http:** document HttpClient, fixing a few other issues ([1855989](https://github.com/angular/angular/commit/1855989))
* **common/http:** don't guess Content-Type for FormData bodies ([#18104](https://github.com/angular/angular/issues/18104)) ([4f1e4ff](https://github.com/angular/angular/commit/4f1e4ff)), closes [#18096](https://github.com/angular/angular/issues/18096) * **common/http:** don't guess Content-Type for FormData bodies ([#18104](https://github.com/angular/angular/issues/18104)) ([4f1e4ff](https://github.com/angular/angular/commit/4f1e4ff)), closes [#18096](https://github.com/angular/angular/issues/18096)
@ -4405,7 +4409,6 @@ Note: the 4.4.0 release on npm accidentally glitched-out midway, so we cut 4.4.1
* **animations:** compute removal node height correctly ([185075d](https://github.com/angular/angular/commit/185075d)) * **animations:** compute removal node height correctly ([185075d](https://github.com/angular/angular/commit/185075d))
* **animations:** do not treat a `0` animation state as `void` ([451257a](https://github.com/angular/angular/commit/451257a)) * **animations:** do not treat a `0` animation state as `void` ([451257a](https://github.com/angular/angular/commit/451257a))
* **animations:** properly collect :enter nodes in a partially updated collection ([6ca4692](https://github.com/angular/angular/commit/6ca4692)), closes [#17440](https://github.com/angular/angular/issues/17440)
* **animations:** remove duplicate license header ([b192dd5](https://github.com/angular/angular/commit/b192dd5)) * **animations:** remove duplicate license header ([b192dd5](https://github.com/angular/angular/commit/b192dd5))
* **forms:** temp roll back breaking change with min/max directives ([b8c39cd](https://github.com/angular/angular/commit/b8c39cd)), closes [#17491](https://github.com/angular/angular/issues/17491) * **forms:** temp roll back breaking change with min/max directives ([b8c39cd](https://github.com/angular/angular/commit/b8c39cd)), closes [#17491](https://github.com/angular/angular/issues/17491)
@ -4641,7 +4644,6 @@ Note: the 4.4.0 release on npm accidentally glitched-out midway, so we cut 4.4.1
* **benchpress:** Update types for TypeScript nullability support ([14669f2](https://github.com/angular/angular/commit/14669f2)) * **benchpress:** Update types for TypeScript nullability support ([14669f2](https://github.com/angular/angular/commit/14669f2))
* **common:** Update types for TypeScript nullability support ([d8b73e4](https://github.com/angular/angular/commit/d8b73e4)) * **common:** Update types for TypeScript nullability support ([d8b73e4](https://github.com/angular/angular/commit/d8b73e4))
* **compiler:** fix build error in xliff2 ([bd704c9](https://github.com/angular/angular/commit/bd704c9)) * **compiler:** fix build error in xliff2 ([bd704c9](https://github.com/angular/angular/commit/bd704c9))
* **compiler:** fix inheritance for AOT with summaries ([#15583](https://github.com/angular/angular/issues/15583)) ([8ef621a](https://github.com/angular/angular/commit/8ef621a))
* **compiler:** ignore calls to unresolved symbols in metadata ([38a7e0d](https://github.com/angular/angular/commit/38a7e0d)), closes [#15969](https://github.com/angular/angular/issues/15969) * **compiler:** ignore calls to unresolved symbols in metadata ([38a7e0d](https://github.com/angular/angular/commit/38a7e0d)), closes [#15969](https://github.com/angular/angular/issues/15969)
* **compiler:** ignore calls to unresolved symbols in metadata ([#15970](https://github.com/angular/angular/issues/15970)) ([ce47d33](https://github.com/angular/angular/commit/ce47d33)), closes [#15969](https://github.com/angular/angular/issues/15969) * **compiler:** ignore calls to unresolved symbols in metadata ([#15970](https://github.com/angular/angular/issues/15970)) ([ce47d33](https://github.com/angular/angular/commit/ce47d33)), closes [#15969](https://github.com/angular/angular/issues/15969)
* **compiler:** Inform user where Quoted error was thrown ([a77b126](https://github.com/angular/angular/commit/a77b126)) * **compiler:** Inform user where Quoted error was thrown ([a77b126](https://github.com/angular/angular/commit/a77b126))
@ -4658,10 +4660,8 @@ Note: the 4.4.0 release on npm accidentally glitched-out midway, so we cut 4.4.1
* **http:** Update types for TypeScript nullability support ([c36ec9b](https://github.com/angular/angular/commit/c36ec9b)) * **http:** Update types for TypeScript nullability support ([c36ec9b](https://github.com/angular/angular/commit/c36ec9b))
* **http:** Update types for TypeScript nullability support ([ec028b8](https://github.com/angular/angular/commit/ec028b8)) * **http:** Update types for TypeScript nullability support ([ec028b8](https://github.com/angular/angular/commit/ec028b8))
* **language-service:** avoid throwing exceptions when reporting metadata errors ([7764c5c](https://github.com/angular/angular/commit/7764c5c)) * **language-service:** avoid throwing exceptions when reporting metadata errors ([7764c5c](https://github.com/angular/angular/commit/7764c5c))
* **language-service:** detect when there isn't a tsconfig.json ([258d539](https://github.com/angular/angular/commit/258d539)), closes [#15874](https://github.com/angular/angular/issues/15874)
* **language-service:** improve resilience to incomplete information ([71a8627](https://github.com/angular/angular/commit/71a8627)) * **language-service:** improve resilience to incomplete information ([71a8627](https://github.com/angular/angular/commit/71a8627))
* **language-service:** infer correct type of `?.` expressions ([0a3a9af](https://github.com/angular/angular/commit/0a3a9af)), closes [#15885](https://github.com/angular/angular/issues/15885) * **language-service:** infer correct type of `?.` expressions ([0a3a9af](https://github.com/angular/angular/commit/0a3a9af)), closes [#15885](https://github.com/angular/angular/issues/15885)
* **language-service:** initialize static reflector correctly ([fe0d02f](https://github.com/angular/angular/commit/fe0d02f)), closes [#15768](https://github.com/angular/angular/issues/15768)
* **language-service:** look for type constructors on canonical symbol ([2ddf3bc](https://github.com/angular/angular/commit/2ddf3bc)) * **language-service:** look for type constructors on canonical symbol ([2ddf3bc](https://github.com/angular/angular/commit/2ddf3bc))
* **language-service:** only use canonical symbols ([5a88d2f](https://github.com/angular/angular/commit/5a88d2f)) * **language-service:** only use canonical symbols ([5a88d2f](https://github.com/angular/angular/commit/5a88d2f))
* **language-service:** parse extended i18n forms ([bde9771](https://github.com/angular/angular/commit/bde9771)) * **language-service:** parse extended i18n forms ([bde9771](https://github.com/angular/angular/commit/bde9771))
@ -4686,7 +4686,6 @@ Note: the 4.4.0 release on npm accidentally glitched-out midway, so we cut 4.4.1
### Features ### Features
* **animations:** Update types for TypeScript nullability support ([38d75d4](https://github.com/angular/angular/commit/38d75d4)), closes [#15870](https://github.com/angular/angular/issues/15870)
* **compiler:** add source files to xmb/xliff translations ([#14705](https://github.com/angular/angular/issues/14705)) ([4054055](https://github.com/angular/angular/commit/4054055)), closes [#14190](https://github.com/angular/angular/issues/14190) * **compiler:** add source files to xmb/xliff translations ([#14705](https://github.com/angular/angular/issues/14705)) ([4054055](https://github.com/angular/angular/commit/4054055)), closes [#14190](https://github.com/angular/angular/issues/14190)
* **compiler:** Implement i18n XLIFF 2.0 serializer ([#14185](https://github.com/angular/angular/issues/14185)) ([09c4cb2](https://github.com/angular/angular/commit/09c4cb2)), closes [#11735](https://github.com/angular/angular/issues/11735) * **compiler:** Implement i18n XLIFF 2.0 serializer ([#14185](https://github.com/angular/angular/issues/14185)) ([09c4cb2](https://github.com/angular/angular/commit/09c4cb2)), closes [#11735](https://github.com/angular/angular/issues/11735)
* **upgrade:** allow setting the angularjs lib at runtime ([#15168](https://github.com/angular/angular/issues/15168)) ([e927aea](https://github.com/angular/angular/commit/e927aea)) * **upgrade:** allow setting the angularjs lib at runtime ([#15168](https://github.com/angular/angular/issues/15168)) ([e927aea](https://github.com/angular/angular/commit/e927aea))
@ -5424,27 +5423,18 @@ returned value being an array.
### Bug Fixes ### Bug Fixes
* **animations:** fix internal jscompiler issue and AOT quoting ([#13798](https://github.com/angular/angular/issues/13798)) ([c2aa981](https://github.com/angular/angular/commit/c2aa981))
* **common:** support numeric value as discrete cases for NgPlural ([#13876](https://github.com/angular/angular/issues/13876)) ([f364557](https://github.com/angular/angular/commit/f364557))
* **compiler:** [i18n] XMB/XTB placeholder names can contain only A-Z, 0-9, _n ([d02eab4](https://github.com/angular/angular/commit/d02eab4)) * **compiler:** [i18n] XMB/XTB placeholder names can contain only A-Z, 0-9, _n ([d02eab4](https://github.com/angular/angular/commit/d02eab4))
* **compiler:** fix regexp to support firefox 31 ([#14082](https://github.com/angular/angular/issues/14082)) ([b2f9d56](https://github.com/angular/angular/commit/b2f9d56)), closes [#14029](https://github.com/angular/angular/issues/14029) [#13900](https://github.com/angular/angular/issues/13900) * **compiler:** fix regexp to support firefox 31 ([#14082](https://github.com/angular/angular/issues/14082)) ([b2f9d56](https://github.com/angular/angular/commit/b2f9d56)), closes [#14029](https://github.com/angular/angular/issues/14029) [#13900](https://github.com/angular/angular/issues/13900)
* **core:** export animation classes required for Renderer impl ([#14002](https://github.com/angular/angular/issues/14002)) ([83361d8](https://github.com/angular/angular/commit/83361d8)), closes [#14001](https://github.com/angular/angular/issues/14001) * **core:** export animation classes required for Renderer impl ([#14002](https://github.com/angular/angular/issues/14002)) ([83361d8](https://github.com/angular/angular/commit/83361d8)), closes [#14001](https://github.com/angular/angular/issues/14001)
* **core:** fix not declared variable in view engine ([#14045](https://github.com/angular/angular/issues/14045)) ([d3a3a8e](https://github.com/angular/angular/commit/d3a3a8e)) * **core:** fix not declared variable in view engine ([#14045](https://github.com/angular/angular/issues/14045)) ([d3a3a8e](https://github.com/angular/angular/commit/d3a3a8e))
* **http:** don't create a blob out of ArrayBuffer when type is application/octet-stream ([#13992](https://github.com/angular/angular/issues/13992)) ([1200cf2](https://github.com/angular/angular/commit/1200cf2)), closes [#13973](https://github.com/angular/angular/issues/13973)
* **router:** enable loadChildren with function in aot ([#13909](https://github.com/angular/angular/issues/13909)) ([635bf02](https://github.com/angular/angular/commit/635bf02)), closes [#11075](https://github.com/angular/angular/issues/11075)
* **router:** routerLinkActive should not throw when not initialized ([#13273](https://github.com/angular/angular/issues/13273)) ([e8ea741](https://github.com/angular/angular/commit/e8ea741)), closes [#13270](https://github.com/angular/angular/issues/13270)
* **upgrade:** detect async downgrade component changes ([#13812](https://github.com/angular/angular/issues/13812)) ([d6382bf](https://github.com/angular/angular/commit/d6382bf)), closes [#6385](https://github.com/angular/angular/issues/6385) [#6385](https://github.com/angular/angular/issues/6385) [#10660](https://github.com/angular/angular/issues/10660) [#12318](https://github.com/angular/angular/issues/12318) [#12034](https://github.com/angular/angular/issues/12034)
* **upgrade/static:** ensure upgraded injector is initialized early enough ([#14065](https://github.com/angular/angular/issues/14065)) ([6152eb2](https://github.com/angular/angular/commit/6152eb2)), closes [#13811](https://github.com/angular/angular/issues/13811) * **upgrade/static:** ensure upgraded injector is initialized early enough ([#14065](https://github.com/angular/angular/issues/14065)) ([6152eb2](https://github.com/angular/angular/commit/6152eb2)), closes [#13811](https://github.com/angular/angular/issues/13811)
### Features ### Features
* **build:** optionally build an ES2015 distro ([#13471](https://github.com/angular/angular/issues/13471)) ([be6c95a](https://github.com/angular/angular/commit/be6c95a))
* **core:** add event support to view engine ([0adb97b](https://github.com/angular/angular/commit/0adb97b)) * **core:** add event support to view engine ([0adb97b](https://github.com/angular/angular/commit/0adb97b))
* **core:** add initial view engine ([#14014](https://github.com/angular/angular/issues/14014)) ([2f87eb5](https://github.com/angular/angular/commit/2f87eb5)) * **core:** add initial view engine ([#14014](https://github.com/angular/angular/issues/14014)) ([2f87eb5](https://github.com/angular/angular/commit/2f87eb5))
* **core:** add pure expression support to view engine ([6541737](https://github.com/angular/angular/commit/6541737)) * **core:** add pure expression support to view engine ([6541737](https://github.com/angular/angular/commit/6541737))
* **core:** Add type information to injector.get() ([#13785](https://github.com/angular/angular/issues/13785)) ([d169c24](https://github.com/angular/angular/commit/d169c24))
* **security:** allow calc and gradient functions. ([#13943](https://github.com/angular/angular/issues/13943)) ([e19bf70](https://github.com/angular/angular/commit/e19bf70))
* **tsc-wrapped:** Support of vinyl like config file was added ([#13987](https://github.com/angular/angular/issues/13987)) ([0c7726d](https://github.com/angular/angular/commit/0c7726d)) * **tsc-wrapped:** Support of vinyl like config file was added ([#13987](https://github.com/angular/angular/issues/13987)) ([0c7726d](https://github.com/angular/angular/commit/0c7726d))
* **upgrade:** Support ng-model in downgraded components ([#10578](https://github.com/angular/angular/issues/10578)) ([e21e9c5](https://github.com/angular/angular/commit/e21e9c5)) * **upgrade:** Support ng-model in downgraded components ([#10578](https://github.com/angular/angular/issues/10578)) ([e21e9c5](https://github.com/angular/angular/commit/e21e9c5))
@ -5972,19 +5962,12 @@ Note: The 2.3.0-beta.0 release also contains all the changes present in the 2.2.
### Features (summary of all features from 2.2.0-beta.0 - 2.2.0-rc.0 releases) ### Features (summary of all features from 2.2.0-beta.0 - 2.2.0-rc.0 releases)
* **common:** support narrow forms for month and weekdays in DatePipe ([#12297](https://github.com/angular/angular/issues/12297)) ([f77ab6a](https://github.com/angular/angular/commit/f77ab6a)), closes [#12294](https://github.com/angular/angular/issues/12294)
* **core:** map 'for' attribute to 'htmlFor' property ([#10546](https://github.com/angular/angular/issues/10546)) ([634b3bb](https://github.com/angular/angular/commit/634b3bb)), closes [#7516](https://github.com/angular/angular/issues/7516) * **core:** map 'for' attribute to 'htmlFor' property ([#10546](https://github.com/angular/angular/issues/10546)) ([634b3bb](https://github.com/angular/angular/commit/634b3bb)), closes [#7516](https://github.com/angular/angular/issues/7516)
* **core:** add the find method to QueryList ([7c16ef9](https://github.com/angular/angular/commit/7c16ef9)) * **core:** add the find method to QueryList ([7c16ef9](https://github.com/angular/angular/commit/7c16ef9))
* **forms:** add hasError and getError to AbstractControlDirective ([#11985](https://github.com/angular/angular/issues/11985)) ([592f40a](https://github.com/angular/angular/commit/592f40a)), closes [#7255](https://github.com/angular/angular/issues/7255)
* **forms:** add ng-pending CSS class during async validation ([#11243](https://github.com/angular/angular/issues/11243)) ([97bc971](https://github.com/angular/angular/commit/97bc971)), closes [#10336](https://github.com/angular/angular/issues/10336)
* **forms:** add emitEvent to AbstractControl methods ([#11949](https://github.com/angular/angular/issues/11949)) ([b9fc090](https://github.com/angular/angular/commit/b9fc090)) * **forms:** add emitEvent to AbstractControl methods ([#11949](https://github.com/angular/angular/issues/11949)) ([b9fc090](https://github.com/angular/angular/commit/b9fc090))
* **forms:** make 'parent' a public property of 'AbstractControl' ([#11855](https://github.com/angular/angular/issues/11855)) ([445e592](https://github.com/angular/angular/commit/445e592))
* **forms:** Validator.pattern accepts a RegExp ([#12323](https://github.com/angular/angular/issues/12323)) ([bf60418](https://github.com/angular/angular/commit/bf60418))
* **router:** add a provider making angular1/angular2 integration easier ([#12769](https://github.com/angular/angular/issues/12769)) ([6e35d13](https://github.com/angular/angular/commit/6e35d13)) * **router:** add a provider making angular1/angular2 integration easier ([#12769](https://github.com/angular/angular/issues/12769)) ([6e35d13](https://github.com/angular/angular/commit/6e35d13))
* **router:** add support for custom url matchers ([7340735](https://github.com/angular/angular/commit/7340735)), closes [#12442](https://github.com/angular/angular/issues/12442) [#12772](https://github.com/angular/angular/issues/12772) * **router:** add support for custom url matchers ([7340735](https://github.com/angular/angular/commit/7340735)), closes [#12442](https://github.com/angular/angular/issues/12442) [#12772](https://github.com/angular/angular/issues/12772)
* **router:** export routerLinkActive w/ isActive property ([c9f58cf](https://github.com/angular/angular/commit/c9f58cf)) * **router:** export routerLinkActive w/ isActive property ([c9f58cf](https://github.com/angular/angular/commit/c9f58cf))
* **router:** add support for ng1/ng2 migration ([#12160](https://github.com/angular/angular/issues/12160)) ([8b9ab44](https://github.com/angular/angular/commit/8b9ab44))
* **upgrade:** add support for AoT compiled upgrade applications ([d6791ff](https://github.com/angular/angular/commit/d6791ff)), closes [#12239](https://github.com/angular/angular/issues/12239)
* **upgrade:** add support for `require` in UpgradeComponent ([fe1d0e2](https://github.com/angular/angular/commit/fe1d0e2)) * **upgrade:** add support for `require` in UpgradeComponent ([fe1d0e2](https://github.com/angular/angular/commit/fe1d0e2))
* **upgrade:** add/improve support for lifecycle hooks in UpgradeComponent ([469010e](https://github.com/angular/angular/commit/469010e)) * **upgrade:** add/improve support for lifecycle hooks in UpgradeComponent ([469010e](https://github.com/angular/angular/commit/469010e))

View File

@ -1,12 +1,72 @@
# Contributor Code of Conduct # Código de Conducta
## Version 0.3b-angular
As contributors and maintainers of the Angular project, we pledge to respect everyone who contributes by posting issues, updating documentation, submitting pull requests, providing feedback in comments, and any other activities. ## 1. Propósito
Communication through any of Angular's channels (GitHub, Gitter, IRC, mailing lists, Google+, Twitter, etc.) must be constructive and never resort to personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct. “Prometemos brindar cortesía y respeto a cualquier persona involucrada en esta comunidad, sin importar el género con el que se identifique, su orientación sexual, limitación física, edad, raza, etnia, religión o nivel de conocimiento. Esperamos que cualquiera que desee contribuir en este proyecto brinde el mismo comportamiento”
We promise to extend courtesy and respect to everyone involved in this project regardless of gender, gender identity, sexual orientation, disability, age, race, ethnicity, religion, or level of experience. We expect anyone contributing to the Angular project to do the same. Bajo ese principio queremos enfocar esta comunidad, una comunidad de respeto por el otro, donde cualquiera que sienta pasión por Angular y desee involucrarse con cualquier tipo de actividad deberá ayudar a mantener una atmósfera de cortesía por el otro, respetando los pensamientos, acciones, ideales y propuestas del otro.
If any member of the community violates this code of conduct, the maintainers of the Angular project may take action, removing issues, comments, and PRs or blocking accounts as deemed appropriate. ## 2. Comportamiento esperado
If you are subject to or witness unacceptable behavior, or have any other concerns, please email us at [conduct@angular.io](mailto:conduct@angular.io). - Evitar usar expresiones o gestos insultantes, humillantes o intimidatorios para referirnos a otros.
- Ejercita la consideración y el respeto en tus comunicaciones y acciones.
- Absténte de adoptar una conducta y un lenguaje degradantes, discriminatorios, abusivos o acosadores.
- Evitar comportamientos que agredan las expresiones de identidad, género, creencias religiosas, acciones que lastimen o los aíslen a otros.
- Evitar comentarios sobre ideas políticas.
- No se toleran conductas físicas y actitudes dirigidas al descrédito personal, físico o emocional de cualquier persona.
- No se toleran chistes y comentarios excluyentes, sexistas y racistas.
- Se rechaza actitudes de hostigamiento.
- Se rechaza el acoso: este se entiende como cualquier tipo de comentario verbal que refuerce discriminación por género, identidad y expresión de género, orientación sexual, discapacidad, apariencia física, tamaño corporal, raza, edad o religión en contextos laborales o sociales.
- No se tolera el contacto físico y/o la atención sexual no deseada.
- Promover la igualdad de oportunidades de formación, educación, intercambio y retroalimentación antes, durante y después de los eventos.
- Intenta colaborar en lugar de generar conflicto.
- Sé consciente de tu entorno y de tus compañeros participantes. Alerta a líderes de la comunidad si notas una situación peligrosa, alguien en apuros, o violaciones de este Código de Conducta, incluso si parecen intrascendentes.
## 3. Comportamiento inaceptable
Comportamientos inaceptables incluyen: intimidación, acoso, abuso, discriminación, comunicación despectiva o degradante o acciones por cualquier participante en nuestra comunidad ya sea virtual, o en las comunicaciones uno-a-uno que se realizan en el contexto de la comunidad. Por favor ser respetuoso con todos.
El acoso incluye: comentarios nocivos o perjudiciales, verbales o escritos relacionados con el género, la orientación sexual, raza, religión, discapacidad; uso inadecuado de desnudos y / o imágenes sexuales en espacios públicos (incluyendo la presentación diapositivas); intimidación deliberada, acecho o seguimiento; fotografías o grabaciones acosadoras; interrupción sostenida de charlas y otros eventos; contacto físico inapropiado, y atención sexual no deseada.
## 4. Consecuencias de comportamiento inaceptable
Se espera que personas a quienes se les solicite que detengan su comportamiento inaceptable lo hagan de manera inmediata esto será válido para cualquier miembro de la comunidad.
En caso de presentarse una violación al código de conducta de manera repetida se tendrá cero tolerancia a este comportamiento por parte de los organizadores.
Si un miembro de la comunidad participa en una conducta inaceptable, los organizadores pueden tomar cualquier acción que consideren apropiada, hasta e incluyendo una prohibición temporal o expulsión permanente de la comunidad, sin previo aviso.
Priorizamos la seguridad de las personas marginadas sobre la comodidad de las personas privilegiadas. Nos reservamos el derecho de no actuar sobre las quejas relacionadas con:
- El "racismo inverso", "sexismo inverso" y "cisfobia".
- Comunicación razonable de límites, como "déjame en paz", "vete" o "no estoy discutiendo esto contigo".
- Al comunicarse en un "tono", no se encuentra agradable.
- Identificando comportamientos o suposiciones racistas, sexistas, cissexistas u opresivas.
## 5. ¿Qué hacer si se incumple el código de conducta?
Si eres víctima o testigo de una conducta inaceptable, o tienes cualquier inquietud, por favor comunícate con el equipo organizador lo antes posible:
- Mensaje directo: Michael Prentice (@splaktar)
- Mensaje directo: Jorge Cano (@jorgeucano)
- Mensaje directo: Andrés Villanueva (@villanuevand)
- Email: [soporte@angular.lat](mailto:soporte@angular.lat)
### ¿Qué pasa después?
- Una vez haya sido notificada el no cumplimiento de la norma, el equipo de liderazgo se reunirán y analizarán el caso.
- Los incidentes presentados se manejarán con discreción.
- Los organizadores se comunicarán con la persona que incumplió la norma y tomarán las medidas respectivas.
- Se realizará un acompañamiento a la persona agredida y se apoyará.
- Si el incidente se hace público, Angular Hispano no se hace responsable de los perjuicios que esto pueda ocasionar en el agresor o el agredido.
## 6. Alcance
Esperamos que todos los participantes de la comunidad (organizadores, voluntarios, contribuyentes pagados o de otro modo; patrocinadores; y otros invitados) se atengan a este Código de Conducta en todos los espacios virtuales y presenciales, así como en todas las comunicaciones de uno-a-uno pertinentes la comunidad.
### Colaboradores
- Alejandra Giraldo
- Vanessa Marely
- Mariano Alvarez
- Andrés Villanueva
- Michael Prentice
- javascript&friends
- Angular
- She Codes Angular
- Colombia dev

359
CONTRIBUTING.en.md Normal file
View File

@ -0,0 +1,359 @@
# Contributing to Angular
We would love for you to contribute to Angular and help make it even better than it is today!
As a contributor, here are the guidelines we would like you to follow:
- [Code of Conduct](#coc)
- [Question or Problem?](#question)
- [Issues and Bugs](#issue)
- [Feature Requests](#feature)
- [Submission Guidelines](#submit)
- [Coding Rules](#rules)
- [Commit Message Guidelines](#commit)
- [Signing the CLA](#cla)
## <a name="coc"></a> Code of Conduct
Help us keep Angular open and inclusive.
Please read and follow our [Code of Conduct][coc].
## <a name="question"></a> Got a Question or Problem?
Do not open issues for general support questions as we want to keep GitHub issues for bug reports and feature requests.
Instead, we recommend using [Stack Overflow](https://stackoverflow.com/questions/tagged/angular) to ask support-related questions. When creating a new question on Stack Overflow, make sure to add the `angular` tag.
Stack Overflow is a much better place to ask questions since:
- there are thousands of people willing to help on Stack Overflow
- questions and answers stay available for public viewing so your question/answer might help someone else
- Stack Overflow's voting system assures that the best answers are prominently visible.
To save your and our time, we will systematically close all issues that are requests for general support and redirect people to Stack Overflow.
If you would like to chat about the question in real-time, you can reach out via [our gitter channel][gitter].
## <a name="issue"></a> Found a Bug?
If you find a bug in the source code, you can help us by [submitting an issue](#submit-issue) to our [GitHub Repository][github].
Even better, you can [submit a Pull Request](#submit-pr) with a fix.
## <a name="feature"></a> Missing a Feature?
You can *request* a new feature by [submitting an issue](#submit-issue) to our GitHub Repository.
If you would like to *implement* a new feature, please consider the size of the change in order to determine the right steps to proceed:
* For a **Major Feature**, first open an issue and outline your proposal so that it can be discussed.
This process allows us to better coordinate our efforts, prevent duplication of work, and help you to craft the change so that it is successfully accepted into the project.
**Note**: Adding a new topic to the documentation, or significantly re-writing a topic, counts as a major feature.
* **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr).
## <a name="submit"></a> Submission Guidelines
### <a name="submit-issue"></a> Submitting an Issue
Before you submit an issue, please search the issue tracker, maybe an issue for your problem already exists and the discussion might inform you of workarounds readily available.
We want to fix all the issues as soon as possible, but before fixing a bug we need to reproduce and confirm it.
In order to reproduce bugs, we require that you provide a minimal reproduction.
Having a minimal reproducible scenario gives us a wealth of important information without going back and forth to you with additional questions.
A minimal reproduction allows us to quickly confirm a bug (or point out a coding problem) as well as confirm that we are fixing the right problem.
We require a minimal reproduction to save maintainers' time and ultimately be able to fix more bugs.
Often, developers find coding problems themselves while preparing a minimal reproduction.
We understand that sometimes it might be hard to extract essential bits of code from a larger codebase but we really need to isolate the problem before we can fix it.
Unfortunately, we are not able to investigate / fix bugs without a minimal reproduction, so if we don't hear back from you, we are going to close an issue that doesn't have enough info to be reproduced.
You can file new issues by selecting from our [new issue templates](https://github.com/angular/angular/issues/new/choose) and filling out the issue template.
### <a name="submit-pr"></a> Submitting a Pull Request (PR)
Before you submit your Pull Request (PR) consider the following guidelines:
1. Search [GitHub](https://github.com/angular/angular/pulls) for an open or closed PR that relates to your submission.
You don't want to duplicate existing efforts.
2. Be sure that an issue describes the problem you're fixing, or documents the design for the feature you'd like to add.
Discussing the design upfront helps to ensure that we're ready to accept your work.
3. Please sign our [Contributor License Agreement (CLA)](#cla) before sending PRs.
We cannot accept code without a signed CLA.
Make sure you author all contributed Git commits with email address associated with your CLA signature.
4. Fork the angular/angular repo.
5. Make your changes in a new git branch:
```shell
git checkout -b my-fix-branch master
```
6. Create your patch, **including appropriate test cases**.
7. Follow our [Coding Rules](#rules).
8. Run the full Angular test suite, as described in the [developer documentation][dev-doc], and ensure that all tests pass.
9. Commit your changes using a descriptive commit message that follows our [commit message conventions](#commit).
Adherence to these conventions is necessary because release notes are automatically generated from these messages.
```shell
git commit -a
```
Note: the optional commit `-a` command line option will automatically "add" and "rm" edited files.
10. Push your branch to GitHub:
```shell
git push origin my-fix-branch
```
11. In GitHub, send a pull request to `angular:master`.
If we ask for changes via code reviews then:
* Make the required updates.
* Re-run the Angular test suites to ensure tests are still passing.
* Rebase your branch and force push to your GitHub repository (this will update your Pull Request):
```shell
git rebase master -i
git push -f
```
That's it! Thank you for your contribution!
#### After your pull request is merged
After your pull request is merged, you can safely delete your branch and pull the changes from the main (upstream) repository:
* Delete the remote branch on GitHub either through the GitHub web UI or your local shell as follows:
```shell
git push origin --delete my-fix-branch
```
* Check out the master branch:
```shell
git checkout master -f
```
* Delete the local branch:
```shell
git branch -D my-fix-branch
```
* Update your master with the latest upstream version:
```shell
git pull --ff upstream master
```
## <a name="rules"></a> Coding Rules
To ensure consistency throughout the source code, keep these rules in mind as you are working:
* All features or bug fixes **must be tested** by one or more specs (unit-tests).
* All public API methods **must be documented**.
* We follow [Google's JavaScript Style Guide][js-style-guide], but wrap all code at **100 characters**.
An automated formatter is available, see [DEVELOPER.md](docs/DEVELOPER.md#clang-format).
## <a name="commit"></a> Commit Message Format
*This specification is inspired and supersedes the [AngularJS commit message format][commit-message-format].*
We have very precise rules over how our Git commit messages must be formatted.
This format leads to **easier to read commit history**.
Each commit message consists of a **header**, a **body**, and a **footer**.
```
<header>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
```
The `header` is mandatory and must conform to the [Commit Message Header](#commit-header) format.
The `body` is mandatory for all commits except for those of scope "docs".
When the body is required it must be at least 20 characters long.
The `footer` is optional.
Any line of the commit message cannot be longer than 100 characters.
#### <a href="commit-header"></a>Commit Message Header
```
<type>(<scope>): <short summary>
│ │ │
│ │ └─⫸ Summary in present tense. Not capitalized. No period at the end.
│ │
│ └─⫸ Commit Scope: animations|bazel|benchpress|common|compiler|compiler-cli|core|
│ elements|forms|http|language-service|localize|platform-browser|
│ platform-browser-dynamic|platform-server|platform-webworker|
│ platform-webworker-dynamic|router|service-worker|upgrade|zone.js|
│ packaging|changelog|dev-infra|docs-infra|migrations|ngcc|ve
└─⫸ Commit Type: build|ci|docs|feat|fix|perf|refactor|style|test
```
The `<type>` and `<summary>` fields are mandatory, the `(<scope>)` field is optional.
##### Type
Must be one of the following:
* **build**: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
* **ci**: Changes to our CI configuration files and scripts (example scopes: Circle, BrowserStack, SauceLabs)
* **docs**: Documentation only changes
* **feat**: A new feature
* **fix**: A bug fix
* **perf**: A code change that improves performance
* **refactor**: A code change that neither fixes a bug nor adds a feature
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
* **test**: Adding missing tests or correcting existing tests
##### Scope
The scope should be the name of the npm package affected (as perceived by the person reading the changelog generated from commit messages).
The following is the list of supported scopes:
* `animations`
* `bazel`
* `benchpress`
* `common`
* `compiler`
* `compiler-cli`
* `core`
* `elements`
* `forms`
* `http`
* `language-service`
* `localize`
* `platform-browser`
* `platform-browser-dynamic`
* `platform-server`
* `platform-webworker`
* `platform-webworker-dynamic`
* `router`
* `service-worker`
* `upgrade`
* `zone.js`
There are currently a few exceptions to the "use package name" rule:
* `packaging`: used for changes that change the npm package layout in all of our packages, e.g. public path changes, package.json changes done to all packages, d.ts file/format changes, changes to bundles, etc.
* `changelog`: used for updating the release notes in CHANGELOG.md
* `dev-infra`: used for dev-infra related changes within the directories /scripts, /tools and /dev-infra
* `docs-infra`: used for docs-app (angular.io) related changes within the /aio directory of the repo
* `migrations`: used for changes to the `ng update` migrations.
* `ngcc`: used for changes to the [Angular Compatibility Compiler](./packages/compiler-cli/ngcc/README.md)
* `ve`: used for changes specific to ViewEngine (legacy compiler/renderer).
* none/empty string: useful for `style`, `test` and `refactor` changes that are done across all packages (e.g. `style: add missing semicolons`) and for docs changes that are not related to a specific package (e.g. `docs: fix typo in tutorial`).
##### Summary
Use the summary field to provide a succinct description of the change:
* use the imperative, present tense: "change" not "changed" nor "changes"
* don't capitalize the first letter
* no dot (.) at the end
#### Commit Message Body
Just as in the summary, use the imperative, present tense: "fix" not "fixed" nor "fixes".
Explain the motivation for the change in the commit message body. This commit message should explain _why_ you are making the change.
You can include a comparison of the previous behavior with the new behavior in order to illustrate the impact of the change.
#### Commit Message Footer
The footer can contain information about breaking changes and is also the place to reference GitHub issues, Jira tickets, and other PRs that this commit closes or is related to.
```
BREAKING CHANGE: <breaking change summary>
<BLANK LINE>
<breaking change description + migration instructions>
<BLANK LINE>
<BLANK LINE>
Fixes #<issue number>
```
Breaking Change section should start with the phrase "BREAKING CHANGE: " followed by a summary of the breaking change, a blank line, and a detailed description of the breaking change that also includes migration instructions.
### Revert commits
If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit.
The content of the commit message body should contain:
- information about the SHA of the commit being reverted in the following format: `This reverts commit <SHA>`,
- a clear description of the reason for reverting the commit message.
## <a name="cla"></a> Signing the CLA
Please sign our Contributor License Agreement (CLA) before sending pull requests. For any code
changes to be accepted, the CLA must be signed. It's a quick process, we promise!
* For individuals, we have a [simple click-through form][individual-cla].
* For corporations, we'll need you to
[print, sign and one of scan+email, fax or mail the form][corporate-cla].
If you have more than one GitHub accounts, or multiple email addresses associated with a single GitHub account, you must sign the CLA using the primary email address of the GitHub account used to author Git commits and send pull requests.
The following documents can help you sort out issues with GitHub accounts and multiple email addresses:
* https://help.github.com/articles/setting-your-commit-email-address-in-git/
* https://stackoverflow.com/questions/37245303/what-does-usera-committed-with-userb-13-days-ago-on-github-mean
* https://help.github.com/articles/about-commit-email-addresses/
* https://help.github.com/articles/blocking-command-line-pushes-that-expose-your-personal-email-address/
[angular-group]: https://groups.google.com/forum/#!forum/angular
[coc]: https://github.com/angular/code-of-conduct/blob/master/CODE_OF_CONDUCT.md
[commit-message-format]: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#
[corporate-cla]: http://code.google.com/legal/corporate-cla-v1.0.html
[dev-doc]: https://github.com/angular/angular/blob/master/docs/DEVELOPER.md
[github]: https://github.com/angular/angular
[gitter]: https://gitter.im/angular/angular
[individual-cla]: http://code.google.com/legal/individual-cla-v1.0.html
[js-style-guide]: https://google.github.io/styleguide/jsguide.html
[jsfiddle]: http://jsfiddle.net
[plunker]: http://plnkr.co/edit
[runnable]: http://runnable.com
[stackoverflow]: http://stackoverflow.com/questions/tagged/angular

View File

@ -1,243 +1,243 @@
# Contributing to Angular # Contribuye a Angular
We would love for you to contribute to Angular and help make it even better than it is today! ¡Nos encantaría que contribuyeras a Angular y que ayudaras a hacerlo aún mejor de lo que es hoy!
As a contributor, here are the guidelines we would like you to follow: Como colaborador, estos son los lineamientos que nos gustaría que siguieras:
- [Code of Conduct](#coc) - [Código de conducta](#coc)
- [Question or Problem?](#question) - [¿Preguntas o problemas?](#question)
- [Issues and Bugs](#issue) - [_Issues_ y _bugs_](#issue)
- [Feature Requests](#feature) - [Solicitud de funcionalidades](#feature)
- [Submission Guidelines](#submit) - [Guía para la creación de issues y PRs](#submit)
- [Coding Rules](#rules) - [Reglas del código](#rules)
- [Commit Message Guidelines](#commit) - [Convención para el mensaje de los _commits_](#commit)
- [Signing the CLA](#cla) - [Firma del Acuerdo de Licencia de Colaborador (CLA)](#cla)
## <a name="coc"></a> Code of Conduct ## <a name="coc"></a> Código de conducta
Help us keep Angular open and inclusive. Ayúdanos a mantener Angular abierto e inclusivo.
Please read and follow our [Code of Conduct][coc]. Por favor lee y sigue nuestro [Código de conducta][coc].
## <a name="question"></a> Got a Question or Problem? ## <a name="question"></a> ¿Tienes alguna pregunta o problema?
Do not open issues for general support questions as we want to keep GitHub issues for bug reports and feature requests. No abras *issues* para preguntas de soporte general ya que queremos mantener los *issues* de GitHub para reporte de *bugs* y solicitud de funcionalidades.
Instead, we recommend using [Stack Overflow](https://stackoverflow.com/questions/tagged/angular) to ask support-related questions. When creating a new question on Stack Overflow, make sure to add the `angular` tag. En su lugar, recomendamos utilizar [Stack Overflow](https://stackoverflow.com/questions/tagged/angular) para hacer preguntas relacionadas con soporte. Al crear una nueva pregunta en Stack Overflow, asegúrate de agregar el etiqueta (tag) de `angular`.
Stack Overflow is a much better place to ask questions since: Stack Overflow es mucho mejor para hacer preguntas ya que:
- there are thousands of people willing to help on Stack Overflow - Hay miles de personas dispuestas a ayudar en preguntas y respuestas de Stack Overflow
- questions and answers stay available for public viewing so your question/answer might help someone else que permanecen disponibles para el público, por lo que tu pregunta o respuesta podría ayudar a otra persona.
- Stack Overflow's voting system assures that the best answers are prominently visible. - El sistema de votación de Stack Overflow asegura que las mejores respuestas sobresalgan y sean visibles.
To save your and our time, we will systematically close all issues that are requests for general support and redirect people to Stack Overflow. Para ahorrar tu tiempo y el nuestro, cerraremos sistemáticamente todos los *issues* que sean solicitudes de soporte general y redirigiremos a las personas a Stack Overflow.
If you would like to chat about the question in real-time, you can reach out via [our gitter channel][gitter]. Si deseas chatear sobre alguna pregunta en tiempo real, puedes hacerlo a través de nuestro [canal de Gitter][gitter].
## <a name="issue"></a> Found a Bug? ## <a name="issue"></a> ¿Encontraste un Bug?
If you find a bug in the source code, you can help us by [submitting an issue](#submit-issue) to our [GitHub Repository][github]. Si encontraste un error en el código fuente, puedes ayudarnos [creando un *issue*](#submit-issue) en nuestro [repositorio de GitHub][github].
Even better, you can [submit a Pull Request](#submit-pr) with a fix. O incluso mejor, puedes [crear un *Pull Request*](#submit-pr) con la solución.
## <a name="feature"></a> Missing a Feature? ## <a name="feature"></a> ¿Falta alguna funcionalidad?
You can *request* a new feature by [submitting an issue](#submit-issue) to our GitHub Repository. Puedes solicitar una nueva funcionalidad [creando un *issue*](#submit-issue) en nuestro repositorio de GitHub.
If you would like to *implement* a new feature, please consider the size of the change in order to determine the right steps to proceed: Si deseas implementar una nueva funcionalidad, por favor considera el tamaño del cambio para determinar los pasos correctos para continuar:
* For a **Major Feature**, first open an issue and outline your proposal so that it can be discussed. * Para un **cambio significativo**, primero abre un *issue* y describe tu propuesta para que pueda ser discutida.
This process allows us to better coordinate our efforts, prevent duplication of work, and help you to craft the change so that it is successfully accepted into the project. Este proceso nos permite coordinar mejor nuestros esfuerzos, evitar trabajo duplicado y ayudarte a diseñar el cambio para que sea aceptado con éxito en el proyecto.
**Note**: Adding a new topic to the documentation, or significantly re-writing a topic, counts as a major feature. **Nota**: Agregar un nuevo tema a la documentación o reescribir significativamente un tema, también cuenta como *cambio significativo*.
* **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr). * **Cambios pequeños** pueden ser elaborados y directamente [creados como un _pull request_](#submit-pr).
## <a name="submit"></a> Submission Guidelines ## <a name="submit"></a> Guía para la creación de issues y PRs
### <a name="submit-issue"></a> Submitting an Issue ### <a name="submit-issue"></a> Creación de _issues_
Before you submit an issue, please search the issue tracker, maybe an issue for your problem already exists and the discussion might inform you of workarounds readily available. Antes de crear un *issue*, por favor busca en el el *issue tracker*, quizá un *issue* para tu problema ya existe y la discusión puede informarte sobre soluciones alternativas disponibles.
We want to fix all the issues as soon as possible, but before fixing a bug we need to reproduce and confirm it. Queremos solucionar todos los problemas lo antes posible, pero antes de corregir un bug necesitamos reproducirlo y confirmarlo.
In order to reproduce bugs, we require that you provide a minimal reproduction. Para reproducir errores, requerimos que proporciones una reproducción mínima.
Having a minimal reproducible scenario gives us a wealth of important information without going back and forth to you with additional questions. Tener un escenario reproducible mínimo nos brinda una gran cantidad de información importante sin tener que ir y venir con preguntas adicionales.
A minimal reproduction allows us to quickly confirm a bug (or point out a coding problem) as well as confirm that we are fixing the right problem. Una reproducción mínima nos permite confirmar rápidamente un bug (o señalar un problema de código), así también confirmar que estamos solucionando el problema correcto.
We require a minimal reproduction to save maintainers' time and ultimately be able to fix more bugs. Requerimos una reproducción mínima para ahorrar tiempo a los encargados del mantenimiento y en última instancia, poder corregir más bugs.
Often, developers find coding problems themselves while preparing a minimal reproduction. A menudo los desarrolladores encuentran problemas de código mientras preparan una reproducción mínima.
We understand that sometimes it might be hard to extract essential bits of code from a larger codebase but we really need to isolate the problem before we can fix it. Entendemos que a veces puede ser difícil extraer porciones esenciales de código de un código más grande, pero realmente necesitamos aislar el problema antes de poder solucionarlo.
Unfortunately, we are not able to investigate / fix bugs without a minimal reproduction, so if we don't hear back from you, we are going to close an issue that doesn't have enough info to be reproduced. Desafortunadamente no podemos investigar/corregir errores sin una reproducción mínima, por lo que si no tenemos tu retroalimentación del bug, vamos a cerrar el *issue* ya que no tiene suficiente información para reproducirse.
You can file new issues by selecting from our [new issue templates](https://github.com/angular/angular/issues/new/choose) and filling out the issue template. Puedes presentar nuevos *issues* seleccionando nuestra [plantilla de _issues_](https://github.com/angular/angular/issues/new/choose) y complentando la plantilla.
### <a name="submit-pr"></a> Submitting a Pull Request (PR) ### <a name="submit-pr"></a> Creación de un Pull Requests (PR)
Before you submit your Pull Request (PR) consider the following guidelines: Antes de crear tu Pull Request (PR) considera los siguientes lineamientos:
1. Search [GitHub](https://github.com/angular/angular/pulls) for an open or closed PR that relates to your submission. 1. Busca en [GitHub](https://github.com/angular/angular/pulls) PRs que estén abiertos o cerrados y que estén relacionados con el que vas a crear.
You don't want to duplicate existing efforts. No deseas duplicar los esfuerzos existentes.
2. Be sure that an issue describes the problem you're fixing, or documents the design for the feature you'd like to add. 2. Asegúrate de que el PR describa el problema que estás solucionando o que documente el diseño de la funcionalidad que deseas agregar.
Discussing the design upfront helps to ensure that we're ready to accept your work. Discutir el diseño por adelantado ayuda a garantizar que estemos listos para aceptar tu trabajo.
3. Please sign our [Contributor License Agreement (CLA)](#cla) before sending PRs. 3. Por favor firma nuestro [Acuerdo de Licencia de Colaborador (CLA)](#cla) antes de crear PRs.
We cannot accept code without a signed CLA. No podemos aceptar el código sin el Acuerdo de Licencia de Colaborador (CLA) firmado.
Make sure you author all contributed Git commits with email address associated with your CLA signature. Asegúrate de crear todas las contribuciones de Git con la dirección de correo electrónico asociada con tu firma del Acuerdo de Licencia de Colaborador (CLA).
4. Fork the angular/angular repo. 4. Haz *fork* del repositorio angular/angular.
5. Make your changes in a new git branch: 5. Haz tus cambios en una nueva rama de Git:
```shell ```shell
git checkout -b my-fix-branch master git checkout -b my-fix-branch master
``` ```
6. Create your patch, **including appropriate test cases**. 6. Crea tu correción, **incluyendo casos de prueba apropiados**.
7. Follow our [Coding Rules](#rules). 7. Sigue nuestras [Reglas de código](#rules).
8. Run the full Angular test suite, as described in the [developer documentation][dev-doc], and ensure that all tests pass. 8. Ejecuta todo el conjunto de pruebas de Angular, tal como está descrito en la [documentación del desarrollador][dev-doc], y asegúrate de que todas las pruebas pasen.
9. Commit your changes using a descriptive commit message that follows our [commit message conventions](#commit). 9. Crea un commit de tus cambios utilizando un mensaje de commit descriptivo que siga nuestra [convención para el mensaje de los commits](#commit).
Adherence to these conventions is necessary because release notes are automatically generated from these messages. Es necesario cumplir con estas convenciones porque las notas de las versiones se generan automáticamente a partir de estos mensajes.
```shell ```shell
git commit -a git commit -a
``` ```
Note: the optional commit `-a` command line option will automatically "add" and "rm" edited files. Nota: la opción de la línea de comandos de Git `-a` automaticamente hará "add" y "rm" a los archivos editados.
10. Push your branch to GitHub: 10. Haz push de tu rama a GitHub:
```shell ```shell
git push origin my-fix-branch git push origin my-fix-branch
``` ```
11. In GitHub, send a pull request to `angular:master`. 11. En GitHub, crea un pull request a `angular:master`.
If we ask for changes via code reviews then: Si solicitamos cambios a través de revisiones de código, sigue las siguientes indicaciones:
* Make the required updates. * Haz los cambios requeridos.
* Re-run the Angular test suites to ensure tests are still passing. * Ejecuta nuevamente el conjunto de pruebas de Angular para asegurar que todas las pruebas aún están pasando.
* Rebase your branch and force push to your GitHub repository (this will update your Pull Request): * Haz rebase de tu rama a la rama master y haz push con la opción `-f` a tu repositorio de Github (esto actualizará tu Pull Request):
```shell ```shell
git rebase master -i git rebase master -i
git push -f git push -f
``` ```
That's it! Thank you for your contribution! ¡Es todo! ¡Muchas gracias por tu contribución!
#### After your pull request is merged #### Después del merge de tu pull request
After your pull request is merged, you can safely delete your branch and pull the changes from the main (upstream) repository: Después de que se hizo merge de tu pull request, puedes eliminar de forma segura tu rama y hacer pull de los cambios del repositorio principal (upstream):
* Delete the remote branch on GitHub either through the GitHub web UI or your local shell as follows: * Elimina la rama remota en GitHub a través de la interfaz de usuario web de GitHub o en tu línea de comandos de la siguiente manera:
```shell ```shell
git push origin --delete my-fix-branch git push origin --delete my-fix-branch
``` ```
* Check out the master branch: * Muévete a la rama master:
```shell ```shell
git checkout master -f git checkout master -f
``` ```
* Delete the local branch: * Elimina tu rama local:
```shell ```shell
git branch -D my-fix-branch git branch -D my-fix-branch
``` ```
* Update your master with the latest upstream version: * Actualiza tu rama master con la última versión del fork (upstream):
```shell ```shell
git pull --ff upstream master git pull --ff upstream master
``` ```
## <a name="rules"></a> Coding Rules ## <a name="rules"></a> Reglas del código
To ensure consistency throughout the source code, keep these rules in mind as you are working: Para garantizar la coherencia en todo el código fuente, ten en cuenta estas reglas mientras trabajas:
* All features or bug fixes **must be tested** by one or more specs (unit-tests). * Todas las funcionalidades o solución de bugs **deben ser probadas** por una o más pruebas (pruebas unitarias).
* All public API methods **must be documented**. * Todos los métodos públicos del API **deben ser documentados**.
* We follow [Google's JavaScript Style Guide][js-style-guide], but wrap all code at **100 characters**. * Seguimos la [guía de estilo JavaScript de Google][js-style-guide], pero cada línea no debe exceder **100 caracteres**.
An automated formatter is available, see [DEVELOPER.md](docs/DEVELOPER.md#clang-format). Un formateador automatizado está disponible, revisar [DEVELOPER.md](docs/DEVELOPER.md#clang-format).
## <a name="commit"></a> Commit Message Format ## <a name="commit"></a> Formato para el mensaje de los commits
*This specification is inspired and supersedes the [AngularJS commit message format][commit-message-format].* *Esta especificación está inspirada y reemplaza el [Formato de mensaje de commits de AngularJS][commit-message-format].*
We have very precise rules over how our Git commit messages must be formatted. Tenemos reglas muy precisas sobre cómo deben formatearse nuestros mensajes de los commits de Git.
This format leads to **easier to read commit history**. Este formato permite tener **un historial de commits más facil de leer**.
Each commit message consists of a **header**, a **body**, and a **footer**. Cada mensaje de un commit consta del **header**, el **body**, y el **footer**.
``` ```
<header> <header>
<BLANK LINE> <LINEA VACIA>
<body> <body>
<BLANK LINE> <LINEA VACIA>
<footer> <footer>
``` ```
The `header` is mandatory and must conform to the [Commit Message Header](#commit-header) format. El `header` es obligatorio y debe ajustarse al formato del [mensaje del header del commit](#commit-header).
The `body` is mandatory for all commits except for those of scope "docs". El `body` es obligatorio para todos los commits excepto los que tenga scope "docs".
When the body is required it must be at least 20 characters long. Cuando el body es requerido debe tener al menos 20 caracteres.
The `footer` is optional. El `footer` es opcional.
Any line of the commit message cannot be longer than 100 characters. Cualquier línea del mensaje del commit no puede tener más de 100 caracteres.
#### <a href="commit-header"></a>Commit Message Header #### <a href="commit-header"></a>Mensaje del header del commit
``` ```
<type>(<scope>): <short summary> <tipo>(<alcance>): <resumen>
│ │ │ │ │ │
│ │ └─⫸ Summary in present tense. Not capitalized. No period at the end. │ │ └─⫸ Resumen corto escrito en modo imperativo, tiempo presente. Sin mayúsculas. Sin punto final.
│ │ │ │
│ └─⫸ Commit Scope: animations|bazel|benchpress|common|compiler|compiler-cli|core| │ └─⫸ Alcance del commit: animations|bazel|benchpress|common|compiler|compiler-cli|core|
│ elements|forms|http|language-service|localize|platform-browser| │ elements|forms|http|language-service|localize|platform-browser|
│ platform-browser-dynamic|platform-server|platform-webworker| │ platform-browser-dynamic|platform-server|platform-webworker|
│ platform-webworker-dynamic|router|service-worker|upgrade|zone.js| │ platform-webworker-dynamic|router|service-worker|upgrade|zone.js|
│ packaging|changelog|dev-infra|docs-infra|migrations|ngcc|ve │ packaging|changelog|dev-infra|docs-infra|migrations|ngcc|ve
└─⫸ Commit Type: build|ci|docs|feat|fix|perf|refactor|style|test └─⫸ Tipo de commit: build|ci|docs|feat|fix|perf|refactor|style|test
``` ```
The `<type>` and `<summary>` fields are mandatory, the `(<scope>)` field is optional. El `<tipo>` y `<resumen>` son obligatorios, el `(<alcance>)` es opcional.
##### Type ##### Tipo
Must be one of the following: El tipo debe ser uno de los siguientes:
* **build**: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm) * **build**: cambios que afectan el sistema de compilación o dependencias externas (ejemplos de scopes: gulp, broccoli, npm)
* **ci**: Changes to our CI configuration files and scripts (example scopes: Circle, BrowserStack, SauceLabs) * **ci**: cambios en nuestros archivos y scripts de configuración de CI (ejemplos de scopes: Circle, BrowserStack, SauceLabs)
* **docs**: Documentation only changes * **docs**: cambios en la documentación
* **feat**: A new feature * **feat**: una nueva funcionalidad
* **fix**: A bug fix * **fix**: una solución de un bug
* **perf**: A code change that improves performance * **perf**: un cambio de código que mejora el rendimiento.
* **refactor**: A code change that neither fixes a bug nor adds a feature * **refactor**: un cambio de código que no corrige ningún error ni agrega ninguna funcionalidad
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc) * **style**: cambios que no afectan el significado del código (espacios en blanco, formato, falta de punto y coma, etc.)
* **test**: Adding missing tests or correcting existing tests * **test**: se agregan pruebas faltantes o se corrigen pruebas existentes
##### Scope ##### Alcance
The scope should be the name of the npm package affected (as perceived by the person reading the changelog generated from commit messages). El alcance debe ser el nombre del paquete npm afectado (tal como lo percibe la persona que lee el registro de cambios generado a partir de los mensajes de commit).
The following is the list of supported scopes: La siguiente es la lista de alcances permitidos:
* `animations` * `animations`
* `bazel` * `bazel`
@ -261,80 +261,73 @@ The following is the list of supported scopes:
* `upgrade` * `upgrade`
* `zone.js` * `zone.js`
There are currently a few exceptions to the "use package name" rule: Actualmente hay algunas excepciones a la regla "usar el nombre de paquete":
* `packaging`: used for changes that change the npm package layout in all of our packages, e.g. public path changes, package.json changes done to all packages, d.ts file/format changes, changes to bundles, etc. * `packaging`: usado para cambios que cambian el diseño de los paquetes de npm en todos nuestros paquetes. Ejemplos: cambios de la ruta públic, package.json cambios hechos a todos los paquetes, cambios a archivos o formatos d.ts, cambios a bundles, etc.
* `changelog`: used for updating the release notes in CHANGELOG.md * `changelog`: utilizado para actualizar las notas de la versión en CHANGELOG.md
* `dev-infra`: used for dev-infra related changes within the directories /scripts, /tools and /dev-infra * `dev-infra`: utilizado para cambios relacionados con dev-infra dentro de los directorios /scripts, /tools y /dev-infra
* `docs-infra`: used for docs-app (angular.io) related changes within the /aio directory of the repo * `docs-infra`: utilizado para cambios relacionados con la documentación (angular.io) dentro del directorio /aio del repositorio
* `migrations`: used for changes to the `ng update` migrations. * `migrations`: utilizado para los cambios en las migraciones `ng update`.
* `ngcc`: used for changes to the [Angular Compatibility Compiler](./packages/compiler-cli/ngcc/README.md) * `ngcc`: usado para los cambios del [Compilador de compatibilidad de Angular](./packages/compiler-cli/ngcc/README.md)
* `ve`: used for changes specific to ViewEngine (legacy compiler/renderer). * `ve`: utilizado para cambios específicos de ViewEngine (legacy compiler/renderer).
* none/empty string: useful for `style`, `test` and `refactor` changes that are done across all packages (e.g. `style: add missing semicolons`) and for docs changes that are not related to a specific package (e.g. `docs: fix typo in tutorial`). * alcance vacío: útil para cambios de `style`, `test` y `refactor` que se realizan en todos los paquetes (ejemplo: `style: add missing semicolons`) y para cambios de la documentación que no están relacionados a un paquete en específico(ejemplo: `docs: corrige error gramatical en el tutorial`).
##### Summary ##### Resumen
Use the summary field to provide a succinct description of the change: Usa el campo resumen para proporcionar una descripción breve del cambio:
* use the imperative, present tense: "change" not "changed" nor "changes" * usa el modo imperativo, tiempo presente: "cambia" no "cambió" o "cambios"
* don't capitalize the first letter * no debe de contener ninguna letra mayúscula
* no dot (.) at the end * no debe de conter punto (.) al final
#### Commit Message Body #### Mensaje del cuerpo del commit
Just as in the summary, use the imperative, present tense: "fix" not "fixed" nor "fixes". Tal como en el resumen, usa el modo imperativo, tiempo presente: "cambia" no "cambió" o "cambios".
Explain the motivation for the change in the commit message body. This commit message should explain _why_ you are making the change. Explica la razón del cambio en el el mensaje del cuerpo del commit. Este mensaje de confirmación debe explicar _por qué_ está realizando el cambio.
You can include a comparison of the previous behavior with the new behavior in order to illustrate the impact of the change. Puedes incluir una comparación del comportamiento anterior con el nuevo comportamiento para ilustrar el impacto del cambio.
#### Commit Message Footer #### Mensaje del footer del commit
The footer can contain information about breaking changes and is also the place to reference GitHub issues, Jira tickets, and other PRs that this commit closes or is related to. El footer puede contener información sobre cambios significativos y también es el lugar para hacer referencia a issues de GitHub, tickets de Jira y otros PRs que están relacionados con el commit.
``` ```
BREAKING CHANGE: <breaking change summary> CAMBIO SIGNIFICATIVO: <resumen del cambio significativo>
<BLANK LINE> <LINEA VACIA>
<breaking change description + migration instructions> <descripción del cambio significativo + instrucciones para la migración>
<BLANK LINE> <LINEA VACIA>
<BLANK LINE> <LINEA VACIA>
Fixes #<issue number> Fix #<issue número>
``` ```
Breaking Change section should start with the phrase "BREAKING CHANGE: " followed by a summary of the breaking change, a blank line, and a detailed description of the breaking change that also includes migration instructions. La sección de cambios significativos debería comenzar con la frase "CAMBIO SIGNIFICATIVO: " seguido de un resumen del cambio significativo, una línea en blanco y una descripción detallada del cambio significativo que también incluya instrucciones de migración.
### Revert commits ### Revirtiendo commits
If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit. Si el commit revierte un commit previo, el commit debería comenzar con `revert: `, seguido por el header del commit revertido.
The content of the commit message body should contain: El contenido del mensaje del commit debería contener:
- information about the SHA of the commit being reverted in the following format: `This reverts commit <SHA>`, - Información sobre el SHA del commit que se revierte en el siguiente formato: `Esto revierte el commit <SHA>`,
- a clear description of the reason for reverting the commit message. - Una descripción clara de la razón para revertir el mensaje del _commit_.
## <a name="cla"></a> Signing the CLA ## <a name="cla"></a> Firma del Acuerdo de Licencia de Colaborador (CLA)
Please sign our Contributor License Agreement (CLA) before sending pull requests. For any code Por favor firma nuestro Acuerdo de Licencia de Colaborador (CLA) cuando creas tu primer pull request. Para que cualquier cambio de código sea aceptado, el Acuerdo de Licencia de Colaborador (CLA) debe ser firmado. Es un proceso rápido con nuestro CLA assistant que está integrado con nuestro CI.
changes to be accepted, the CLA must be signed. It's a quick process, we promise!
* For individuals, we have a [simple click-through form][individual-cla]. Los siguientes documentos pueden ayudarte a resolver problemas con cuentas de GitHub y múltiples direcciones de correo electrónico:
* For corporations, we'll need you to
[print, sign and one of scan+email, fax or mail the form][corporate-cla].
If you have more than one GitHub accounts, or multiple email addresses associated with a single GitHub account, you must sign the CLA using the primary email address of the GitHub account used to author Git commits and send pull requests.
The following documents can help you sort out issues with GitHub accounts and multiple email addresses:
* https://help.github.com/articles/setting-your-commit-email-address-in-git/ * https://help.github.com/articles/setting-your-commit-email-address-in-git/
* https://stackoverflow.com/questions/37245303/what-does-usera-committed-with-userb-13-days-ago-on-github-mean * https://stackoverflow.com/questions/37245303/what-does-usera-committed-with-userb-13-days-ago-on-github-mean

26
README.en.md Normal file
View File

@ -0,0 +1,26 @@
[![CircleCI](https://circleci.com/gh/angular/angular/tree/master.svg?style=shield)](https://circleci.com/gh/angular/workflows/angular/tree/master)
[![Join the chat at https://gitter.im/angular/angular](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/angular/angular?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![npm version](https://badge.fury.io/js/%40angular%2Fcore.svg)](https://www.npmjs.com/@angular/core)
# Angular
Angular is a development platform for building mobile and desktop web applications using TypeScript/JavaScript and other languages.
## Quickstart
[Get started in 5 minutes][quickstart].
## Changelog
[Learn about the latest improvements][changelog].
## Want to help?
Want to file a bug, contribute some code, or improve documentation? Excellent! Read up on our
guidelines for [contributing][contributing] and then check out one of our issues in the [hotlist: community-help](https://github.com/angular/angular/labels/hotlist%3A%20community-help).
[contributing]: https://github.com/angular/angular/blob/master/CONTRIBUTING.md
[quickstart]: https://angular.io/start
[changelog]: https://github.com/angular/angular/blob/master/CHANGELOG.md
[ng]: https://angular.io

View File

@ -1,26 +1,25 @@
[![CircleCI](https://circleci.com/gh/angular/angular/tree/master.svg?style=shield)](https://circleci.com/gh/angular/workflows/angular/tree/master) # Angular en español
[![Join the chat at https://gitter.im/angular/angular](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/angular/angular?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![npm version](https://badge.fury.io/js/%40angular%2Fcore.svg)](https://www.npmjs.com/@angular/core)
Angular es una plataforma de desarrollo para construir aplicaciones web y móviles que usa
TypeScript/JavaScript y otros lenguajes de programación.
# Angular ## ¿Quieres ayudar?
Angular is a development platform for building mobile and desktop web applications using TypeScript/JavaScript and other languages. ### Documentación en español
## Quickstart ¿Quieres mejorar la documentación? ¡Excelente! Lee nuestras pautas para
[colaborar](CONTRIBUTING.md) y luego revisa algunos de nuestras
[issues](https://github.com/angular-hispano/angular/issues).
[Get started in 5 minutes][quickstart]. ### El framework
## Changelog La colaboración para corregir errores y agregar funciones en el framework debe realizarse en inglés a través
del repositorio [angular/angular](https://github.com/angular/angular) upstream.
[Learn about the latest improvements][changelog]. ## Guía rápida
## Want to help? [Comienza a usarlo en 5 minutos](https://docs.angular.lat/start).
Want to file a bug, contribute some code, or improve documentation? Excellent! Read up on our ## Registro de cambios (Changelog)
guidelines for [contributing][contributing] and then check out one of our issues in the [hotlist: community-help](https://github.com/angular/angular/labels/hotlist%3A%20community-help).
[contributing]: https://github.com/angular/angular/blob/master/CONTRIBUTING.md [Últimas mejoras realizadas](CHANGELOG.md).
[quickstart]: https://angular.io/start
[changelog]: https://github.com/angular/angular/blob/master/CHANGELOG.md
[ng]: https://angular.io

View File

@ -1,140 +1,131 @@
# Angular documentation project (https://angular.io) # Proyecto de documentación Angular (https://docs.angular.lat)
Everything in this folder is part of the documentation project. This includes Todo en esta carpeta es parte del proyecto de documentación. Esto incluye:
* the web site for displaying the documentation * El sitio web para mostrar la documentación
* the dgeni configuration for converting source files to rendered files that can be viewed in the web site. * La configuración de dgeni para convertir los archivos de origen a archivos renderizados que se pueden vizualizar en el sitio web.
* the tooling for setting up examples for development; and generating live-example and zip files from the examples. * Las herramientas para establecer ejemplos para el desarrollo; y generar archivos en tiempo real y archivos zip desde los ejemplos.
## Developer tasks ## Tareas de desarrollador
We use [Yarn](https://yarnpkg.com) to manage the dependencies and to run build tasks. Nosotros usamos [Yarn](https://yarnpkg.com) para gestionar las dependencias y crear tareas de compilación.
You should run all these tasks from the `angular/aio` folder. Debes ejecutar todas estas tareas desde la carpeta `angular/aio`.
Here are the most important tasks you might need to use: Aquí están las tareas más importantes que podrías necesitar usar:
* `yarn` - install all the dependencies. * `yarn` - instalar todas las dependencias.
* `yarn setup` - install all the dependencies, boilerplate, stackblitz, zips and run dgeni on the docs. * `yarn setup` - instalar todas las dependencias, boilerplate, stackblitz, zips y ejecuta dgeni en los documentos.
* `yarn setup-local` - same as `setup`, but build the Angular packages from the source code and use these locally built versions (instead of the ones fetched from npm) for aio and docs examples boilerplate. * `yarn setup-local` - igual que `setup`, pero crea los paquetes de Angular a partir del código y usa estas versiones construidas localmente (en lugar de las recuperadas desde npm) para aio y ejemplos de documentos boilerplate.
* `yarn build` - create a production build of the application (after installing dependencies, boilerplate, etc). * `yarn build` - crear una compilación de producción de la aplicación (después de instalar dependencias, boilerplate, etc).
* `yarn build-local` - same as `build`, but use `setup-local` instead of `setup`. * `yarn build-local` - igual que `build`, pero usa `setup-local` en lugar de `setup`.
* `yarn build-local-with-viewengine` - same as `build-local`, but in addition also turns on `ViewEngine` (pre-Ivy) mode in aio. * `yarn build-local-with-viewengine` - igual que `build-local`, pero además también enciende el modo `ViewEngine` (pre-Ivy) en aio.
(Note: To turn on `ViewEngine` mode in docs examples, see `yarn boilerplate:add:viewengine` below.) (Nota: Encender el modo `ViewEngine` en ejemplos de documentos, ver `yarn boilerplate:add:viewengine` abajo.)
* `yarn start` - run a development web server that watches the files; then builds the doc-viewer and reloads the page, as necessary. * `yarn start` - ejecutar un servidor web de desarrollo que observa los archivos; luego crea el doc-viewer y vuelve a cargar la página, según sea necesario.
* `yarn serve-and-sync` - run both the `docs-watch` and `start` in the same console. * `yarn serve-and-sync` - ejecutar ambos, el `docs-watch` y `start` en la misma consola.
* `yarn lint` - check that the doc-viewer code follows our style rules. * `yarn lint` - comprobar que el código del doc-viewer sigue nuestras reglas de estilo.
* `yarn test` - watch all the source files, for the doc-viewer, and run all the unit tests when any change. * `yarn test` - observar todos los archivos de origen, para el doc-viewer, y ejecuta todas las pruebas unitarias cuando haya algún cambio.
* `yarn test --watch=false` - run all the unit tests once. * `yarn test --watch=false` -ejecutar todas las pruebas unitarias una sola vez.
* `yarn e2e` - run all the e2e tests for the doc-viewer. * `yarn e2e` - ejecutar todas las pruebas de e2e para el doc-viewer.
* `yarn docs` - generate all the docs from the source files. * `yarn docs` - generar toda la documentación desde los archivos fuente.
* `yarn docs-watch` - watch the Angular source and the docs files and run a short-circuited doc-gen for the docs that changed. * `yarn docs-watch` - observar el código Angular, los archivos de documentación y ejecutar un 'doc-gen' en corto circuito para los documentos que fueron cambiados.
* `yarn docs-lint` - check that the doc gen code follows our style rules. * `yarn docs-lint` - comprobar que el código del documento generado sigue nuestras reglas de estilo.
* `yarn docs-test` - run the unit tests for the doc generation code. * `yarn docs-test` - ejecutar las pruebas unitarias para el código de generación de doc.
* `yarn boilerplate:add` - generate all the boilerplate code for the examples, so that they can be run locally. * `yarn boilerplate:add` - generar todo el código boilerplate para los ejemplos, para que puedan ejecutarse localmente.
* `yarn boilerplate:add:viewengine` - same as `boilerplate:add` but also turns on `ViewEngine` (pre-Ivy) mode. * `yarn boilerplate:add:viewengine` - igual que `boilerplate:add` pero también enciende el modo `ViewEngine` (pre-Ivy).
* `yarn boilerplate:remove` - remove all the boilerplate code that was added via `yarn boilerplate:add`. * `yarn boilerplate:remove` - eliminar todo el código boilerplate que fue añadido a través`yarn boilerplate:add`.
* `yarn generate-stackblitz` - generate the stackblitz files that are used by the `live-example` tags in the docs. * `yarn generate-stackblitz` - generar los archivos stackblitz que están usados por la etiqueta `live-example` en documentos.
* `yarn generate-zips` - generate the zip files from the examples. Zip available via the `live-example` tags in the docs. * `yarn generate-zips` - generar los archivos zip desde los ejemplos. Zip está disponible a través de la etiqueta `live-example` en los documentos.
* `yarn example-e2e` - run all e2e tests for examples. Available options: * `yarn example-e2e` - ejecutar todas las pruebas e2e para ejemplos. Opciones disponibles:
- `--setup`: generate boilerplate, force webdriver update & other setup, then run tests. - `--setup`: generar boilerplate, forzar la actualización del controlador web y otras configuraciones, luego ejecutar las pruebas.
- `--local`: run e2e tests with the local version of Angular contained in the "dist" folder. - `--local`: ejecutar pruebas e2e con la versión local de Angular contenida en la carpeta "dist".
_Requires `--setup` in order to take effect._ _Requiere `--setup` para que surta efecto._
- `--viewengine`: run e2e tests in `ViewEngine` (pre-Ivy) mode. - `--viewengine`: ejecutar pruebas e2e en modo `ViewEngine` (pre-Ivy).
- `--filter=foo`: limit e2e tests to those containing the word "foo". - `--filter=foo`: limitar pruebas e2e a las que contienen la palabra "foo".
> **Note for Windows users** > **Nota para usuarios Windows**
> >
> Setting up the examples involves creating some [symbolic links](https://en.wikipedia.org/wiki/Symbolic_link) (see [here](./tools/examples/README.md#symlinked-node_modules) for details). On Windows, this requires to either have [Developer Mode enabled](https://blogs.windows.com/windowsdeveloper/2016/12/02/symlinks-windows-10) (supported on Windows 10 or newer) or run the setup commands as administrator. > Configurar los ejemplos implica crear algunos [enlaces simbólicos](https://es.wikipedia.org/wiki/Enlace_simb%C3%B3lico) (ver [Aquí](./tools/examples/README.md#symlinked-node_modules) para más detalles). En Windows, esto requiere tener [Habilitado el Modo de desarrollador ](https://blogs.windows.com/windowsdeveloper/2016/12/02/symlinks-windows-10) (compatible con Windows 10 o más reciente) o ejecutar los comandos de configuración cómo administrador.
> >
> The affected commands are: > Los comandos afectados son:
> - `yarn setup` / `yarn setup-*` > - `yarn setup` / `yarn setup-*`
> - `yarn build` / `yarn build-*` > - `yarn build` / `yarn build-*`
> - `yarn boilerplate:add` > - `yarn boilerplate:add`
> - `yarn example-e2e --setup` > - `yarn example-e2e --setup`
## Using ServiceWorker locally ## Usando ServiceWorker localmente
Running `yarn start` (even when explicitly targeting production mode) does not set up the Ejecutando `yarn start` (incluso cuando se apunta explícitamente al modo de producción) no configura el
ServiceWorker. If you want to test the ServiceWorker locally, you can use `yarn build` and then ServiceWorker. Si quieres probar el ServiceWorker localmente, puedes usar `yarn build` y luego
serve the files in `dist/` with `yarn http-server dist -p 4200`. ejecutar los archivos en `dist/` con `yarn http-server dist -p 4200`.
## Guide to authoring ## Guía de autoría
Existen dos tipos de contenido en la documentación:
There are two types of content in the documentation: * **Documentación de API**: descripciones de los módulos, clases, interfaces, decoradores, etc que son parte de la plataforma Angular.
La documentacion de API está generada directamente desde el código fuente.
El código fuente está contenido en archivos TypeScript , almacenados en la carpeta `angular/packages`.
Cada elemento de la API puede tener un comentario anterior, el cual contiene etiquetas y contenido de estilos JSDoc.
El contenido está escrito en markdown.
* **API docs**: descriptions of the modules, classes, interfaces, decorators, etc that make up the Angular platform. * **Otro contenido**: guias, tutoriales, y otro material de marketing.
API docs are generated directly from the source code. Todos los demás contenidos se escriben utilizando markdown en archivos de texto, ubicados en la carpeta `angular/aio/content`.
The source code is contained in TypeScript files, located in the `angular/packages` folder. Más específicamente, hay subcarpetas que contienen tipos particulares de contenido: guías, tutoriales y marketing.
Each API item may have a preceding comment, which contains JSDoc style tags and content.
The content is written in markdown.
* **Other content**: guides, tutorials, and other marketing material. * **Ejempos de código**: los ejemplos de código deben ser comprobables para garantizar su precisión.
All other content is written using markdown in text files, located in the `angular/aio/content` folder. Además, nuestros ejemplos tienen un aspecto específico y permiten al usuario copiar el código fuente. Para mayor
More specifically, there are sub-folders that contain particular types of content: guides, tutorial and marketing. ejemplos se representan en una interfaz con pestañas (e.g. template, HTML, y TypeScript en pestañas separadas). Adicionalmente, algunos son ejemplos en acción, que proporcionan enlaces donde se puede editar el código, ejecutar, y/o descargar. Para obtener más detalles sobre cómo trabajar con ejemplos de código, lea los [fragmentos de código](https://docs.angular.lat/guide/docs-style-guide#code-snippets), [código fuente de marcado ](https://docs.angular.lat/guide/docs-style-guide#source-code-markup), y [ ejemplos en acción ](https://docs.angular.lat/guide/docs-style-guide#live-examples) paginas de los [ autores de guías de estilo ](https://docs.angular.lat/guide/docs-style-guide).
* **Code examples**: code examples need to be testable to ensure their accuracy. Usamos la herramienta [dgeni](https://github.com/angular/dgeni) para convertir estos archivos en docs que se pueden ver en el doc-viewer.
Also, our examples have a specific look and feel and allow the user to copy the source code. For larger Las [guías de estilo para Autores](https://docs.angular.lat/guide/docs-style-guide) prescriben pautas para
examples they are rendered in a tabbed interface (e.g. template, HTML, and TypeScript on separate escribir páginas de guía, explica cómo usar la documentación de clases y componentes, y cómo marcar el código fuente para producir fragmentos de código.
tabs). Additionally, some are live examples, which provide links where the code can be edited, executed, and/or downloaded. For details on working with code examples, please read the [Code snippets](https://angular.io/guide/docs-style-guide#code-snippets), [Source code markup](https://angular.io/guide/docs-style-guide#source-code-markup), and [Live examples](https://angular.io/guide/docs-style-guide#live-examples) pages of the [Authors Style Guide](https://angular.io/guide/docs-style-guide).
We use the [dgeni](https://github.com/angular/dgeni) tool to convert these files into docs that can be viewed in the doc-viewer. ### Generando documentos completos
The [Authors Style Guide](https://angular.io/guide/docs-style-guide) prescribes guidelines for La principal tarea para generar los documentos es `yarn docs`. Esto procesará todos los archivos fuente (API y otros), extrayendo la documentación y generando archivos JSON que pueden ser consumidos por el doc-viewer.
writing guide pages, explains how to use the documentation classes and components, and how to markup sample source code to produce code snippets.
### Generating the complete docs ### Generación parcial de doc para editores
The main task for generating the docs is `yarn docs`. This will process all the source files (API and other), La generación completa de documentos puede llevar hasta un minuto. Eso es demasiado lento para la creación y edición eficiente de documentos.
extracting the documentation and generating JSON files that can be consumed by the doc-viewer.
### Partial doc generation for editors Puedes ealizar pequeños cambios en un editor inteligente que muestre un markdown con formato:
>En VS Code, _Cmd-K, V_ abre la vista previa de markdown en el panel lateral; _Cmd-B_ alterna la barra izquierda
Full doc generation can take up to one minute. That's too slow for efficient document creation and editing. Puedes también mirar los cambios que se muestran correctamente en el doc-viewer
con un tiempo de ciclo rápido de edición / visualización.
You can make small changes in a smart editor that displays formatted markdown: Para este propósito, usa la tarea `yarn docs-watch`, que observa los cambios en los archivos de origen y solo vuelve a procesar los archivos necesarios para generar los documentos relacionados con el archivo que ha cambiado.
>In VS Code, _Cmd-K, V_ opens markdown preview in side pane; _Cmd-B_ toggles left sidebar Dado que esta tarea tiene accesos directos, es mucho más rápido (a menudo menos de 1 segundo) pero no producirá contenido de fidelidad completa. Por ejemplo, los enlaces a otros documentoss y ejemplos de código pueden no mostrarse correctamente. Esto se nota especialmente en los enlaces a otros documentos y en los ejemplos incrustados, que no siempre se representan correctamente.
You also want to see those changes displayed properly in the doc viewer La configuración general es la siguiente:
with a quick, edit/view cycle time.
For this purpose, use the `yarn docs-watch` task, which watches for changes to source files and only * Abrir una terminal, estar seguro que las dependencias están instaladas; ejecutar una generación inicial del doc; luego iniciar el doc-viewer:
re-processes the files necessary to generate the docs that are related to the file that has changed.
Since this task takes shortcuts, it is much faster (often less than 1 second) but it won't produce full
fidelity content. For example, links to other docs and code examples may not render correctly. This is
most particularly noticed in links to other docs and in the embedded examples, which may not always render
correctly.
The general setup is as follows:
* Open a terminal, ensure the dependencies are installed; run an initial doc generation; then start the doc-viewer:
```bash ```bash
yarn setup yarn setup
yarn start yarn start
``` ```
* Open a second terminal and start watching the docs * Abrir una segunda terminal e iniciar el observador de documentos.
```bash ```bash
yarn docs-watch yarn docs-watch
``` ```
>Alternatively, try the consolidated `serve-and-sync` command that builds, watches and serves in the same terminal window >Alternativamente, prueba el comando fusionado `serve-and-sync` que crea, observa y ejecuta en la misma ventana de la terminal
```bash ```bash
yarn serve-and-sync yarn serve-and-sync
``` ```
* Open a browser at https://localhost:4200/ and navigate to the document on which you want to work. * Abre un navegador con la siguiente dirección https://localhost:4200/ y navega hasta el documento en el que quieras trabajar.
You can automatically open the browser by using `yarn start -o` in the first terminal. Puedes automáticamente abrir el navegador utilizando `yarn start -o` en la primera terminal.
* Make changes to the page's associated doc or example files. Every time a file is saved, the doc will * Realiza cambios en la página de documentación asociada o en los archivos de ejemplo. Cada vez que un archivo es guardado, la documentación se regenerará, la aplicación se reconstruirá y la página se volverá a cargar.
be regenerated, the app will rebuild and the page will reload.
* If you get a build error complaining about examples or any other odd behavior, be sure to consult *Si recibes un error de compilación acerca de los ejemplos o cualquier otro error, asegúrate de consultar las
the [Authors Style Guide](https://angular.io/guide/docs-style-guide). [guías de estilo para Autores](https://angular.io/guide/docs-style-guide) para más información.

View File

@ -1,31 +1,31 @@
import { TestBed, async } from '@angular/core/testing'; import { TestBed, waitForAsync } from '@angular/core/testing';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { TemplateModule } from './template/template.module';
import { ReactiveModule } from './reactive/reactive.module'; import { ReactiveModule } from './reactive/reactive.module';
import { TemplateModule } from './template/template.module';
describe('AppComponent', () => { describe('AppComponent', () => {
beforeEach(waitForAsync(() => {
beforeEach(async(() => { TestBed
TestBed.configureTestingModule({ .configureTestingModule({
imports: [ReactiveModule, TemplateModule], imports: [ReactiveModule, TemplateModule],
declarations: [ declarations: [AppComponent],
AppComponent })
], .compileComponents();
}).compileComponents();
})); }));
it('should create the app', async(() => { it('should create the app', waitForAsync(() => {
const fixture = TestBed.createComponent(AppComponent); const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance; const app = fixture.componentInstance;
expect(app).toBeTruthy(); expect(app).toBeTruthy();
})); }));
it('should render title', async(() => { it('should render title', waitForAsync(() => {
const fixture = TestBed.createComponent(AppComponent); const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges(); fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement; const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain('Forms Overview'); expect(compiled.querySelector('h1').textContent).toContain('Forms Overview');
})); }));
}); });

View File

@ -1,19 +1,18 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { ReactiveFormsModule } from '@angular/forms'; import { ReactiveFormsModule } from '@angular/forms';
import { FavoriteColorComponent } from './favorite-color.component';
import { createNewEvent } from '../../shared/utils'; import { createNewEvent } from '../../shared/utils';
import { FavoriteColorComponent } from './favorite-color.component';
describe('Favorite Color Component', () => { describe('Favorite Color Component', () => {
let component: FavoriteColorComponent; let component: FavoriteColorComponent;
let fixture: ComponentFixture<FavoriteColorComponent>; let fixture: ComponentFixture<FavoriteColorComponent>;
beforeEach(async(() => { beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({ TestBed
imports: [ ReactiveFormsModule ], .configureTestingModule(
declarations: [ FavoriteColorComponent ] {imports: [ReactiveFormsModule], declarations: [FavoriteColorComponent]})
}) .compileComponents();
.compileComponents();
})); }));
beforeEach(() => { beforeEach(() => {

View File

@ -1,19 +1,16 @@
import { async, ComponentFixture, TestBed, tick, fakeAsync } from '@angular/core/testing'; import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
import { FavoriteColorComponent } from './favorite-color.component';
import { createNewEvent } from '../../shared/utils'; import { createNewEvent } from '../../shared/utils';
import { FavoriteColorComponent } from './favorite-color.component';
describe('FavoriteColorComponent', () => { describe('FavoriteColorComponent', () => {
let component: FavoriteColorComponent; let component: FavoriteColorComponent;
let fixture: ComponentFixture<FavoriteColorComponent>; let fixture: ComponentFixture<FavoriteColorComponent>;
beforeEach(async(() => { beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({imports: [FormsModule], declarations: [FavoriteColorComponent]})
imports: [ FormsModule ], .compileComponents();
declarations: [ FavoriteColorComponent ]
})
.compileComponents();
})); }));
beforeEach(() => { beforeEach(() => {
@ -28,29 +25,29 @@ describe('FavoriteColorComponent', () => {
// #docregion model-to-view // #docregion model-to-view
it('should update the favorite color on the input field', fakeAsync(() => { it('should update the favorite color on the input field', fakeAsync(() => {
component.favoriteColor = 'Blue'; component.favoriteColor = 'Blue';
fixture.detectChanges(); fixture.detectChanges();
tick(); tick();
const input = fixture.nativeElement.querySelector('input'); const input = fixture.nativeElement.querySelector('input');
expect(input.value).toBe('Blue'); expect(input.value).toBe('Blue');
})); }));
// #enddocregion model-to-view // #enddocregion model-to-view
// #docregion view-to-model // #docregion view-to-model
it('should update the favorite color in the component', fakeAsync(() => { it('should update the favorite color in the component', fakeAsync(() => {
const input = fixture.nativeElement.querySelector('input'); const input = fixture.nativeElement.querySelector('input');
const event = createNewEvent('input'); const event = createNewEvent('input');
input.value = 'Red'; input.value = 'Red';
input.dispatchEvent(event); input.dispatchEvent(event);
fixture.detectChanges(); fixture.detectChanges();
expect(component.favoriteColor).toEqual('Red'); expect(component.favoriteColor).toEqual('Red');
})); }));
// #enddocregion view-to-model // #enddocregion view-to-model
}); });

View File

@ -1,4 +1,4 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { MyLibComponent } from './my-lib.component'; import { MyLibComponent } from './my-lib.component';
@ -6,11 +6,8 @@ describe('MyLibComponent', () => {
let component: MyLibComponent; let component: MyLibComponent;
let fixture: ComponentFixture<MyLibComponent>; let fixture: ComponentFixture<MyLibComponent>;
beforeEach(async(() => { beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({declarations: [MyLibComponent]}).compileComponents();
declarations: [ MyLibComponent ]
})
.compileComponents();
})); }));
beforeEach(() => { beforeEach(() => {

View File

@ -1,19 +1,16 @@
import { AppComponent } from './app.component';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core'; import { DebugElement } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { AppComponent } from './app.component';
describe('AppComponent', () => { describe('AppComponent', () => {
let de: DebugElement; let de: DebugElement;
let comp: AppComponent; let comp: AppComponent;
let fixture: ComponentFixture<AppComponent>; let fixture: ComponentFixture<AppComponent>;
beforeEach(async(() => { beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({declarations: [AppComponent]}).compileComponents();
declarations: [ AppComponent ]
})
.compileComponents();
})); }));
beforeEach(() => { beforeEach(() => {
@ -22,12 +19,11 @@ describe('AppComponent', () => {
de = fixture.debugElement.query(By.css('h1')); de = fixture.debugElement.query(By.css('h1'));
}); });
it('should create component', () => expect(comp).toBeDefined() ); it('should create component', () => expect(comp).toBeDefined());
it('should have expected <h1> text', () => { it('should have expected <h1> text', () => {
fixture.detectChanges(); fixture.detectChanges();
const h1 = de.nativeElement; const h1 = de.nativeElement;
expect(h1.textContent).toMatch(/angular/i, expect(h1.textContent).toMatch(/angular/i, '<h1> should say something about "Angular"');
'<h1> should say something about "Angular"');
}); });
}); });

View File

@ -11,7 +11,7 @@
<!-- Polyfills --> <!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script> <script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script> <script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script> <script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.js"></script> <script src="systemjs.config.js"></script>
<script> <script>

View File

@ -1,6 +1,6 @@
// #docplaster // #docplaster
// #docregion // #docregion
import { TestBed, async } from '@angular/core/testing'; import { TestBed, waitForAsync } from '@angular/core/testing';
// #enddocregion // #enddocregion
import { AppComponent } from './app-initial.component'; import { AppComponent } from './app-initial.component';
/* /*
@ -12,29 +12,29 @@ describe('AppComponent', () => {
*/ */
describe('AppComponent (initial CLI version)', () => { describe('AppComponent (initial CLI version)', () => {
// #docregion // #docregion
beforeEach(async(() => { beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({ TestBed
declarations: [ .configureTestingModule({
AppComponent declarations: [AppComponent],
], })
}).compileComponents(); .compileComponents();
}));
it('should create the app', async(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
}));
it(`should have as title 'app'`, async(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app.title).toEqual('app');
}));
it('should render title', async(() => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!');
})); }));
it('should create the app', waitForAsync(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
}));
it(`should have as title 'app'`, waitForAsync(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app.title).toEqual('app');
}));
it('should render title', waitForAsync(() => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!');
}));
}); });
// #enddocregion // #enddocregion
@ -43,16 +43,13 @@ import { DebugElement } from '@angular/core';
import { ComponentFixture } from '@angular/core/testing'; import { ComponentFixture } from '@angular/core/testing';
describe('AppComponent (initial CLI version - as it should be)', () => { describe('AppComponent (initial CLI version - as it should be)', () => {
let app: AppComponent; let app: AppComponent;
let de: DebugElement; let de: DebugElement;
let fixture: ComponentFixture<AppComponent>; let fixture: ComponentFixture<AppComponent>;
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [ declarations: [AppComponent],
AppComponent
],
}); });
fixture = TestBed.createComponent(AppComponent); fixture = TestBed.createComponent(AppComponent);
@ -70,7 +67,6 @@ describe('AppComponent (initial CLI version - as it should be)', () => {
it('should render title in an h1 tag', () => { it('should render title in an h1 tag', () => {
fixture.detectChanges(); fixture.detectChanges();
expect(de.nativeElement.querySelector('h1').textContent) expect(de.nativeElement.querySelector('h1').textContent).toContain('Welcome to app!');
.toContain('Welcome to app!');
}); });
}); });

View File

@ -1,7 +1,7 @@
// For more examples: // For more examples:
// https://github.com/angular/angular/blob/master/modules/@angular/router/test/integration.spec.ts // https://github.com/angular/angular/blob/master/modules/@angular/router/test/integration.spec.ts
import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; import { waitForAsync, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { asyncData } from '../testing'; import { asyncData } from '../testing';
@ -21,9 +21,9 @@ import { AppModule } from './app.module';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { AboutComponent } from './about/about.component'; import { AboutComponent } from './about/about.component';
import { DashboardComponent } from './dashboard/dashboard.component'; import { DashboardComponent } from './dashboard/dashboard.component';
import { TwainService } from './twain/twain.service';
import { HeroService, TestHeroService } from './model/testing/test-hero.service'; import { HeroService, TestHeroService } from './model/testing/test-hero.service';
import { TwainService } from './twain/twain.service';
let comp: AppComponent; let comp: AppComponent;
let fixture: ComponentFixture<AppComponent>; let fixture: ComponentFixture<AppComponent>;
@ -32,54 +32,51 @@ let router: Router;
let location: SpyLocation; let location: SpyLocation;
describe('AppComponent & RouterTestingModule', () => { describe('AppComponent & RouterTestingModule', () => {
beforeEach(waitForAsync(() => {
beforeEach(async(() => { TestBed
TestBed.configureTestingModule({ .configureTestingModule({
imports: [ imports: [
AppModule, AppModule,
RouterTestingModule.withRoutes(routes), RouterTestingModule.withRoutes(routes),
], ],
providers: [ providers: [{provide: HeroService, useClass: TestHeroService}]
{ provide: HeroService, useClass: TestHeroService } })
] .compileComponents();
})
.compileComponents();
})); }));
it('should navigate to "Dashboard" immediately', fakeAsync(() => { it('should navigate to "Dashboard" immediately', fakeAsync(() => {
createComponent(); createComponent();
tick(); // wait for async data to arrive tick(); // wait for async data to arrive
expectPathToBe('/dashboard', 'after initialNavigation()'); expectPathToBe('/dashboard', 'after initialNavigation()');
expectElementOf(DashboardComponent); expectElementOf(DashboardComponent);
})); }));
it('should navigate to "About" on click', fakeAsync(() => { it('should navigate to "About" on click', fakeAsync(() => {
createComponent(); createComponent();
click(page.aboutLinkDe); click(page.aboutLinkDe);
// page.aboutLinkDe.nativeElement.click(); // ok but fails in phantom // page.aboutLinkDe.nativeElement.click(); // ok but fails in phantom
advance(); advance();
expectPathToBe('/about'); expectPathToBe('/about');
expectElementOf(AboutComponent); expectElementOf(AboutComponent);
})); }));
it('should navigate to "About" w/ browser location URL change', fakeAsync(() => { it('should navigate to "About" w/ browser location URL change', fakeAsync(() => {
createComponent(); createComponent();
location.simulateHashChange('/about'); location.simulateHashChange('/about');
// location.go('/about'); // also works ... except, perhaps, in Stackblitz // location.go('/about'); // also works ... except, perhaps, in Stackblitz
advance(); advance();
expectPathToBe('/about'); expectPathToBe('/about');
expectElementOf(AboutComponent); expectElementOf(AboutComponent);
})); }));
// Can't navigate to lazy loaded modules with this technique // Can't navigate to lazy loaded modules with this technique
xit('should navigate to "Heroes" on click (not working yet)', fakeAsync(() => { xit('should navigate to "Heroes" on click (not working yet)', fakeAsync(() => {
createComponent(); createComponent();
page.heroesLinkDe.nativeElement.click(); page.heroesLinkDe.nativeElement.click();
advance(); advance();
expectPathToBe('/heroes'); expectPathToBe('/heroes');
})); }));
}); });
@ -94,37 +91,37 @@ let loader: SpyNgModuleFactoryLoader;
///////// Can't get lazy loaded Heroes to work yet ///////// Can't get lazy loaded Heroes to work yet
xdescribe('AppComponent & Lazy Loading (not working yet)', () => { xdescribe('AppComponent & Lazy Loading (not working yet)', () => {
beforeEach(waitForAsync(() => {
beforeEach(async(() => { TestBed
TestBed.configureTestingModule({ .configureTestingModule({
imports: [ imports: [
AppModule, AppModule,
RouterTestingModule.withRoutes(routes), RouterTestingModule.withRoutes(routes),
], ],
}) })
.compileComponents(); .compileComponents();
})); }));
beforeEach(fakeAsync(() => { beforeEach(fakeAsync(() => {
createComponent(); createComponent();
loader = TestBed.inject(NgModuleFactoryLoader) as SpyNgModuleFactoryLoader; loader = TestBed.inject(NgModuleFactoryLoader) as SpyNgModuleFactoryLoader;
loader.stubbedModules = { expected: HeroModule }; loader.stubbedModules = {expected: HeroModule};
router.resetConfig([{path: 'heroes', loadChildren: 'expected'}]); router.resetConfig([{path: 'heroes', loadChildren: 'expected'}]);
})); }));
it('should navigate to "Heroes" on click', async(() => { it('should navigate to "Heroes" on click', waitForAsync(() => {
page.heroesLinkDe.nativeElement.click(); page.heroesLinkDe.nativeElement.click();
advance(); advance();
expectPathToBe('/heroes'); expectPathToBe('/heroes');
expectElementOf(HeroListComponent); expectElementOf(HeroListComponent);
})); }));
it('can navigate to "Heroes" w/ browser location URL change', fakeAsync(() => { it('can navigate to "Heroes" w/ browser location URL change', fakeAsync(() => {
location.go('/heroes'); location.go('/heroes');
advance(); advance();
expectPathToBe('/heroes'); expectPathToBe('/heroes');
expectElementOf(HeroListComponent); expectElementOf(HeroListComponent);
})); }));
}); });
////// Helpers ///////// ////// Helpers /////////
@ -134,9 +131,9 @@ xdescribe('AppComponent & Lazy Loading (not working yet)', () => {
* Wait a tick, then detect changes, and tick again * Wait a tick, then detect changes, and tick again
*/ */
function advance(): void { function advance(): void {
tick(); // wait while navigating tick(); // wait while navigating
fixture.detectChanges(); // update view fixture.detectChanges(); // update view
tick(); // wait for async data to arrive tick(); // wait for async data to arrive
} }
function createComponent() { function createComponent() {
@ -148,8 +145,8 @@ function createComponent() {
router = injector.get(Router); router = injector.get(Router);
router.initialNavigation(); router.initialNavigation();
spyOn(injector.get(TwainService), 'getQuote') spyOn(injector.get(TwainService), 'getQuote')
// fake fast async observable // fake fast async observable
.and.returnValue(asyncData('Test Quote')); .and.returnValue(asyncData('Test Quote'));
advance(); advance();
page = new Page(); page = new Page();
@ -168,14 +165,14 @@ class Page {
constructor() { constructor() {
const links = fixture.debugElement.queryAll(By.directive(RouterLinkWithHref)); const links = fixture.debugElement.queryAll(By.directive(RouterLinkWithHref));
this.aboutLinkDe = links[2]; this.aboutLinkDe = links[2];
this.dashboardLinkDe = links[0]; this.dashboardLinkDe = links[0];
this.heroesLinkDe = links[1]; this.heroesLinkDe = links[1];
// for debugging // for debugging
this.comp = comp; this.comp = comp;
this.fixture = fixture; this.fixture = fixture;
this.router = router; this.router = router;
} }
} }

View File

@ -1,66 +1,70 @@
// #docplaster // #docplaster
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { Component, DebugElement, NO_ERRORS_SCHEMA } from '@angular/core'; import { Component, DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { RouterLinkDirectiveStub } from '../testing'; import { RouterLinkDirectiveStub } from '../testing';
import { AppComponent } from './app.component';
// #docregion component-stubs // #docregion component-stubs
@Component({selector: 'app-banner', template: ''}) @Component({selector: 'app-banner', template: ''})
class BannerStubComponent {} class BannerStubComponent {
}
@Component({selector: 'router-outlet', template: ''}) @Component({selector: 'router-outlet', template: ''})
class RouterOutletStubComponent { } class RouterOutletStubComponent {
}
@Component({selector: 'app-welcome', template: ''}) @Component({selector: 'app-welcome', template: ''})
class WelcomeStubComponent {} class WelcomeStubComponent {
}
// #enddocregion component-stubs // #enddocregion component-stubs
let comp: AppComponent; let comp: AppComponent;
let fixture: ComponentFixture<AppComponent>; let fixture: ComponentFixture<AppComponent>;
describe('AppComponent & TestModule', () => { describe('AppComponent & TestModule', () => {
beforeEach(async(() => { beforeEach(waitForAsync(() => {
// #docregion testbed-stubs // #docregion testbed-stubs
TestBed.configureTestingModule({ TestBed
declarations: [ .configureTestingModule({
AppComponent, declarations: [
RouterLinkDirectiveStub, AppComponent, RouterLinkDirectiveStub, BannerStubComponent, RouterOutletStubComponent,
BannerStubComponent, WelcomeStubComponent
RouterOutletStubComponent, ]
WelcomeStubComponent })
] // #enddocregion testbed-stubs
}) .compileComponents()
// #enddocregion testbed-stubs .then(() => {
.compileComponents().then(() => { fixture = TestBed.createComponent(AppComponent);
fixture = TestBed.createComponent(AppComponent); comp = fixture.componentInstance;
comp = fixture.componentInstance; });
});
})); }));
tests(); tests();
}); });
//////// Testing w/ NO_ERRORS_SCHEMA ////// //////// Testing w/ NO_ERRORS_SCHEMA //////
describe('AppComponent & NO_ERRORS_SCHEMA', () => { describe('AppComponent & NO_ERRORS_SCHEMA', () => {
beforeEach(async(() => { beforeEach(waitForAsync(() => {
// #docregion no-errors-schema, mixed-setup // #docregion no-errors-schema, mixed-setup
TestBed.configureTestingModule({ TestBed
declarations: [ .configureTestingModule({
AppComponent, declarations: [
// #enddocregion no-errors-schema AppComponent,
BannerStubComponent, // #enddocregion no-errors-schema
// #docregion no-errors-schema BannerStubComponent,
RouterLinkDirectiveStub // #docregion no-errors-schema
], RouterLinkDirectiveStub
schemas: [ NO_ERRORS_SCHEMA ] ],
}) schemas: [NO_ERRORS_SCHEMA]
// #enddocregion no-errors-schema, mixed-setup })
.compileComponents().then(() => { // #enddocregion no-errors-schema, mixed-setup
fixture = TestBed.createComponent(AppComponent); .compileComponents()
comp = fixture.componentInstance; .then(() => {
}); fixture = TestBed.createComponent(AppComponent);
comp = fixture.componentInstance;
});
})); }));
tests(); tests();
}); });
@ -72,30 +76,23 @@ import { AppModule } from './app.module';
import { AppRoutingModule } from './app-routing.module'; import { AppRoutingModule } from './app-routing.module';
describe('AppComponent & AppModule', () => { describe('AppComponent & AppModule', () => {
beforeEach(waitForAsync(() => {
TestBed
.configureTestingModule({imports: [AppModule]})
beforeEach(async(() => { // Get rid of app's Router configuration otherwise many failures.
// Doing so removes Router declarations; add the Router stubs
.overrideModule(AppModule, {
remove: {imports: [AppRoutingModule]},
add: {declarations: [RouterLinkDirectiveStub, RouterOutletStubComponent]}
})
TestBed.configureTestingModule({ .compileComponents()
imports: [ AppModule ]
})
// Get rid of app's Router configuration otherwise many failures. .then(() => {
// Doing so removes Router declarations; add the Router stubs fixture = TestBed.createComponent(AppComponent);
.overrideModule(AppModule, { comp = fixture.componentInstance;
remove: { });
imports: [ AppRoutingModule ]
},
add: {
declarations: [ RouterLinkDirectiveStub, RouterOutletStubComponent ]
}
})
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(AppComponent);
comp = fixture.componentInstance;
});
})); }));
tests(); tests();
@ -107,11 +104,10 @@ function tests() {
// #docregion test-setup // #docregion test-setup
beforeEach(() => { beforeEach(() => {
fixture.detectChanges(); // trigger initial data binding fixture.detectChanges(); // trigger initial data binding
// find DebugElements with an attached RouterLinkStubDirective // find DebugElements with an attached RouterLinkStubDirective
linkDes = fixture.debugElement linkDes = fixture.debugElement.queryAll(By.directive(RouterLinkDirectiveStub));
.queryAll(By.directive(RouterLinkDirectiveStub));
// get attached link directive instances // get attached link directive instances
// using each DebugElement's injector // using each DebugElement's injector
@ -132,8 +128,8 @@ function tests() {
}); });
it('can click Heroes link in template', () => { it('can click Heroes link in template', () => {
const heroesLinkDe = linkDes[1]; // heroes link DebugElement const heroesLinkDe = linkDes[1]; // heroes link DebugElement
const heroesLink = routerLinks[1]; // heroes link directive const heroesLink = routerLinks[1]; // heroes link directive
expect(heroesLink.navigatedTo).toBeNull('should not have navigated yet'); expect(heroesLink.navigatedTo).toBeNull('should not have navigated yet');

View File

@ -1,6 +1,6 @@
// #docplaster // #docplaster
// #docregion import-async // #docregion import-async
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
// #enddocregion import-async // #enddocregion import-async
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core'; import { DebugElement } from '@angular/core';
@ -14,11 +14,12 @@ describe('BannerComponent (external files)', () => {
describe('Two beforeEach', () => { describe('Two beforeEach', () => {
// #docregion async-before-each // #docregion async-before-each
beforeEach(async(() => { beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({ TestBed
declarations: [ BannerComponent ], .configureTestingModule({
}) declarations: [BannerComponent],
.compileComponents(); // compile template and css })
.compileComponents(); // compile template and css
})); }));
// #enddocregion async-before-each // #enddocregion async-before-each
@ -26,7 +27,7 @@ describe('BannerComponent (external files)', () => {
// #docregion sync-before-each // #docregion sync-before-each
beforeEach(() => { beforeEach(() => {
fixture = TestBed.createComponent(BannerComponent); fixture = TestBed.createComponent(BannerComponent);
component = fixture.componentInstance; // BannerComponent test instance component = fixture.componentInstance; // BannerComponent test instance
h1 = fixture.nativeElement.querySelector('h1'); h1 = fixture.nativeElement.querySelector('h1');
}); });
// #enddocregion sync-before-each // #enddocregion sync-before-each
@ -36,16 +37,17 @@ describe('BannerComponent (external files)', () => {
describe('One beforeEach', () => { describe('One beforeEach', () => {
// #docregion one-before-each // #docregion one-before-each
beforeEach(async(() => { beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({ TestBed
declarations: [ BannerComponent ], .configureTestingModule({
}) declarations: [BannerComponent],
.compileComponents() })
.then(() => { .compileComponents()
fixture = TestBed.createComponent(BannerComponent); .then(() => {
component = fixture.componentInstance; fixture = TestBed.createComponent(BannerComponent);
h1 = fixture.nativeElement.querySelector('h1'); component = fixture.componentInstance;
}); h1 = fixture.nativeElement.querySelector('h1');
});
})); }));
// #enddocregion one-before-each // #enddocregion one-before-each
@ -69,4 +71,3 @@ describe('BannerComponent (external files)', () => {
}); });
} }
}); });

View File

@ -1,14 +1,16 @@
// #docplaster // #docplaster
// #docregion import-by // #docregion import-by
import { By } from '@angular/platform-browser';
// #enddocregion import-by // #enddocregion import-by
// #docregion import-debug-element // #docregion import-debug-element
import { DebugElement } from '@angular/core'; import { DebugElement } from '@angular/core';
// #enddocregion import-debug-element // #enddocregion import-debug-element
// #docregion v1 // #docregion v1
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
// #enddocregion v1 // #enddocregion v1
import { BannerComponent } from './banner-initial.component'; import { BannerComponent } from './banner-initial.component';
/* /*
// #docregion v1 // #docregion v1
import { BannerComponent } from './banner.component'; import { BannerComponent } from './banner.component';
@ -17,15 +19,12 @@ describe('BannerComponent', () => {
// #enddocregion v1 // #enddocregion v1
*/ */
describe('BannerComponent (initial CLI generated)', () => { describe('BannerComponent (initial CLI generated)', () => {
// #docregion v1 // #docregion v1
let component: BannerComponent; let component: BannerComponent;
let fixture: ComponentFixture<BannerComponent>; let fixture: ComponentFixture<BannerComponent>;
beforeEach(async(() => { beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({declarations: [BannerComponent]}).compileComponents();
declarations: [ BannerComponent ]
})
.compileComponents();
})); }));
beforeEach(() => { beforeEach(() => {
@ -44,9 +43,7 @@ describe('BannerComponent (initial CLI generated)', () => {
describe('BannerComponent (minimal)', () => { describe('BannerComponent (minimal)', () => {
it('should create', () => { it('should create', () => {
// #docregion configureTestingModule // #docregion configureTestingModule
TestBed.configureTestingModule({ TestBed.configureTestingModule({declarations: [BannerComponent]});
declarations: [ BannerComponent ]
});
// #enddocregion configureTestingModule // #enddocregion configureTestingModule
// #docregion createComponent // #docregion createComponent
const fixture = TestBed.createComponent(BannerComponent); const fixture = TestBed.createComponent(BannerComponent);
@ -65,9 +62,7 @@ describe('BannerComponent (with beforeEach)', () => {
let fixture: ComponentFixture<BannerComponent>; let fixture: ComponentFixture<BannerComponent>;
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({declarations: [BannerComponent]});
declarations: [ BannerComponent ]
});
fixture = TestBed.createComponent(BannerComponent); fixture = TestBed.createComponent(BannerComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
}); });

View File

@ -1,22 +1,21 @@
// #docplaster // #docplaster
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core'; import { DebugElement } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { addMatchers, click } from '../../testing'; import { addMatchers, click } from '../../testing';
import { Hero } from '../model/hero'; import { Hero } from '../model/hero';
import { DashboardHeroComponent } from './dashboard-hero.component'; import { DashboardHeroComponent } from './dashboard-hero.component';
beforeEach( addMatchers ); beforeEach(addMatchers);
describe('DashboardHeroComponent class only', () => { describe('DashboardHeroComponent class only', () => {
// #docregion class-only // #docregion class-only
it('raises the selected event when clicked', () => { it('raises the selected event when clicked', () => {
const comp = new DashboardHeroComponent(); const comp = new DashboardHeroComponent();
const hero: Hero = { id: 42, name: 'Test' }; const hero: Hero = {id: 42, name: 'Test'};
comp.hero = hero; comp.hero = hero;
comp.selected.subscribe((selectedHero: Hero) => expect(selectedHero).toBe(hero)); comp.selected.subscribe((selectedHero: Hero) => expect(selectedHero).toBe(hero));
@ -26,33 +25,31 @@ describe('DashboardHeroComponent class only', () => {
}); });
describe('DashboardHeroComponent when tested directly', () => { describe('DashboardHeroComponent when tested directly', () => {
let comp: DashboardHeroComponent; let comp: DashboardHeroComponent;
let expectedHero: Hero; let expectedHero: Hero;
let fixture: ComponentFixture<DashboardHeroComponent>; let fixture: ComponentFixture<DashboardHeroComponent>;
let heroDe: DebugElement; let heroDe: DebugElement;
let heroEl: HTMLElement; let heroEl: HTMLElement;
beforeEach(async(() => { beforeEach(waitForAsync(() => {
// #docregion setup, config-testbed // #docregion setup, config-testbed
TestBed.configureTestingModule({ TestBed
declarations: [ DashboardHeroComponent ] .configureTestingModule({declarations: [DashboardHeroComponent]})
}) // #enddocregion setup, config-testbed
// #enddocregion setup, config-testbed .compileComponents();
.compileComponents();
})); }));
beforeEach(() => { beforeEach(() => {
// #docregion setup // #docregion setup
fixture = TestBed.createComponent(DashboardHeroComponent); fixture = TestBed.createComponent(DashboardHeroComponent);
comp = fixture.componentInstance; comp = fixture.componentInstance;
// find the hero's DebugElement and element // find the hero's DebugElement and element
heroDe = fixture.debugElement.query(By.css('.hero')); heroDe = fixture.debugElement.query(By.css('.hero'));
heroEl = heroDe.nativeElement; heroEl = heroDe.nativeElement;
// mock the hero supplied by the parent component // mock the hero supplied by the parent component
expectedHero = { id: 42, name: 'Test Name' }; expectedHero = {id: 42, name: 'Test Name'};
// simulate the parent setting the input property with that hero // simulate the parent setting the input property with that hero
comp.hero = expectedHero; comp.hero = expectedHero;
@ -96,8 +93,8 @@ describe('DashboardHeroComponent when tested directly', () => {
let selectedHero: Hero; let selectedHero: Hero;
comp.selected.subscribe((hero: Hero) => selectedHero = hero); comp.selected.subscribe((hero: Hero) => selectedHero = hero);
click(heroDe); // click helper with DebugElement click(heroDe); // click helper with DebugElement
click(heroEl); // click helper with native element click(heroEl); // click helper with native element
expect(selectedHero).toBe(expectedHero); expect(selectedHero).toBe(expectedHero);
}); });
@ -111,22 +108,21 @@ describe('DashboardHeroComponent when inside a test host', () => {
let fixture: ComponentFixture<TestHostComponent>; let fixture: ComponentFixture<TestHostComponent>;
let heroEl: HTMLElement; let heroEl: HTMLElement;
beforeEach(async(() => { beforeEach(waitForAsync(() => {
// #docregion test-host-setup // #docregion test-host-setup
TestBed.configureTestingModule({ TestBed
declarations: [ DashboardHeroComponent, TestHostComponent ] .configureTestingModule({declarations: [DashboardHeroComponent, TestHostComponent]})
}) // #enddocregion test-host-setup
// #enddocregion test-host-setup .compileComponents();
.compileComponents();
})); }));
beforeEach(() => { beforeEach(() => {
// #docregion test-host-setup // #docregion test-host-setup
// create TestHostComponent instead of DashboardHeroComponent // create TestHostComponent instead of DashboardHeroComponent
fixture = TestBed.createComponent(TestHostComponent); fixture = TestBed.createComponent(TestHostComponent);
testHost = fixture.componentInstance; testHost = fixture.componentInstance;
heroEl = fixture.nativeElement.querySelector('.hero'); heroEl = fixture.nativeElement.querySelector('.hero');
fixture.detectChanges(); // trigger initial data binding fixture.detectChanges(); // trigger initial data binding
// #enddocregion test-host-setup // #enddocregion test-host-setup
}); });
@ -155,8 +151,10 @@ import { Component } from '@angular/core';
</dashboard-hero>` </dashboard-hero>`
}) })
class TestHostComponent { class TestHostComponent {
hero: Hero = {id: 42, name: 'Test Name' }; hero: Hero = {id: 42, name: 'Test Name'};
selectedHero: Hero; selectedHero: Hero;
onSelected(hero: Hero) { this.selectedHero = hero; } onSelected(hero: Hero) {
this.selectedHero = hero;
}
} }
// #enddocregion test-host // #enddocregion test-host

View File

@ -1,6 +1,5 @@
// #docplaster // #docplaster
import { async, inject, ComponentFixture, TestBed import { ComponentFixture, inject, TestBed, waitForAsync } from '@angular/core/testing';
} from '@angular/core/testing';
import { addMatchers, asyncData, click } from '../../testing'; import { addMatchers, asyncData, click } from '../../testing';
import { HeroService } from '../model/hero.service'; import { HeroService } from '../model/hero.service';
@ -12,7 +11,7 @@ import { Router } from '@angular/router';
import { DashboardComponent } from './dashboard.component'; import { DashboardComponent } from './dashboard.component';
import { DashboardModule } from './dashboard.module'; import { DashboardModule } from './dashboard.module';
beforeEach ( addMatchers ); beforeEach(addMatchers);
let comp: DashboardComponent; let comp: DashboardComponent;
let fixture: ComponentFixture<DashboardComponent>; let fixture: ComponentFixture<DashboardComponent>;
@ -21,9 +20,7 @@ let fixture: ComponentFixture<DashboardComponent>;
describe('DashboardComponent (deep)', () => { describe('DashboardComponent (deep)', () => {
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({imports: [DashboardModule]});
imports: [ DashboardModule ]
});
}); });
compileAndCreate(); compileAndCreate();
@ -43,10 +40,8 @@ import { NO_ERRORS_SCHEMA } from '@angular/core';
describe('DashboardComponent (shallow)', () => { describe('DashboardComponent (shallow)', () => {
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule(
declarations: [ DashboardComponent ], {declarations: [DashboardComponent], schemas: [NO_ERRORS_SCHEMA]});
schemas: [NO_ERRORS_SCHEMA]
});
}); });
compileAndCreate(); compileAndCreate();
@ -63,25 +58,26 @@ describe('DashboardComponent (shallow)', () => {
/** Add TestBed providers, compile, and create DashboardComponent */ /** Add TestBed providers, compile, and create DashboardComponent */
function compileAndCreate() { function compileAndCreate() {
// #docregion compile-and-create-body // #docregion compile-and-create-body
beforeEach(async(() => { beforeEach(waitForAsync(() => {
// #docregion router-spy // #docregion router-spy
const routerSpy = jasmine.createSpyObj('Router', ['navigateByUrl']); const routerSpy = jasmine.createSpyObj('Router', ['navigateByUrl']);
const heroServiceSpy = jasmine.createSpyObj('HeroService', ['getHeroes']); const heroServiceSpy = jasmine.createSpyObj('HeroService', ['getHeroes']);
TestBed.configureTestingModule({ TestBed
providers: [ .configureTestingModule({
{ provide: HeroService, useValue: heroServiceSpy }, providers: [
{ provide: Router, useValue: routerSpy } {provide: HeroService, useValue: heroServiceSpy}, {provide: Router, useValue: routerSpy}
] ]
}) })
// #enddocregion router-spy // #enddocregion router-spy
.compileComponents().then(() => { .compileComponents()
fixture = TestBed.createComponent(DashboardComponent); .then(() => {
comp = fixture.componentInstance; fixture = TestBed.createComponent(DashboardComponent);
comp = fixture.componentInstance;
// getHeroes spy returns observable of test heroes // getHeroes spy returns observable of test heroes
heroServiceSpy.getHeroes.and.returnValue(asyncData(getTestHeroes())); heroServiceSpy.getHeroes.and.returnValue(asyncData(getTestHeroes()));
}); });
// #enddocregion compile-and-create-body // #enddocregion compile-and-create-body
})); }));
} }
@ -93,23 +89,20 @@ function compileAndCreate() {
function tests(heroClick: () => void) { function tests(heroClick: () => void) {
it('should NOT have heroes before ngOnInit', () => { it('should NOT have heroes before ngOnInit', () => {
expect(comp.heroes.length).toBe(0, expect(comp.heroes.length).toBe(0, 'should not have heroes before ngOnInit');
'should not have heroes before ngOnInit');
}); });
it('should NOT have heroes immediately after ngOnInit', () => { it('should NOT have heroes immediately after ngOnInit', () => {
fixture.detectChanges(); // runs initial lifecycle hooks fixture.detectChanges(); // runs initial lifecycle hooks
expect(comp.heroes.length).toBe(0, expect(comp.heroes.length).toBe(0, 'should not have heroes until service promise resolves');
'should not have heroes until service promise resolves');
}); });
describe('after get dashboard heroes', () => { describe('after get dashboard heroes', () => {
let router: Router; let router: Router;
// Trigger component so it gets heroes and binds to them // Trigger component so it gets heroes and binds to them
beforeEach(async(() => { beforeEach(waitForAsync(() => {
router = fixture.debugElement.injector.get(Router); router = fixture.debugElement.injector.get(Router);
fixture.detectChanges(); // runs ngOnInit -> getHeroes fixture.detectChanges(); // runs ngOnInit -> getHeroes
fixture.whenStable() // No need for the `lastPromise` hack! fixture.whenStable() // No need for the `lastPromise` hack!
@ -117,8 +110,8 @@ function tests(heroClick: () => void) {
})); }));
it('should HAVE heroes', () => { it('should HAVE heroes', () => {
expect(comp.heroes.length).toBeGreaterThan(0, expect(comp.heroes.length)
'should have heroes after service promise resolves'); .toBeGreaterThan(0, 'should have heroes after service promise resolves');
}); });
it('should DISPLAY heroes', () => { it('should DISPLAY heroes', () => {
@ -130,8 +123,7 @@ function tests(heroClick: () => void) {
// #docregion navigate-test // #docregion navigate-test
it('should tell ROUTER to navigate when hero clicked', () => { it('should tell ROUTER to navigate when hero clicked', () => {
heroClick(); // trigger click on first inner <div class="hero">
heroClick(); // trigger click on first inner <div class="hero">
// args passed to router.navigateByUrl() spy // args passed to router.navigateByUrl() spy
const spy = router.navigateByUrl as jasmine.Spy; const spy = router.navigateByUrl as jasmine.Spy;
@ -139,10 +131,8 @@ function tests(heroClick: () => void) {
// expecting to navigate to id of the component's first hero // expecting to navigate to id of the component's first hero
const id = comp.heroes[0].id; const id = comp.heroes[0].id;
expect(navArgs).toBe('/heroes/' + id, expect(navArgs).toBe('/heroes/' + id, 'should nav to HeroDetail for first hero');
'should nav to HeroDetail for first hero');
}); });
// #enddocregion navigate-test // #enddocregion navigate-test
}); });
} }

View File

@ -1,18 +1,23 @@
// tslint:disable-next-line:no-unused-variable // tslint:disable-next-line:no-unused-variable
import { async, fakeAsync, tick } from '@angular/core/testing'; import { fakeAsync, tick, waitForAsync } from '@angular/core/testing';
import { interval, of } from 'rxjs'; import { interval, of } from 'rxjs';
import { delay, take } from 'rxjs/operators'; import { delay, take } from 'rxjs/operators';
describe('Angular async helper', () => { describe('Angular async helper', () => {
describe('async', () => { describe('async', () => {
let actuallyDone = false; let actuallyDone = false;
beforeEach(() => { actuallyDone = false; }); beforeEach(() => {
actuallyDone = false;
});
afterEach(() => { expect(actuallyDone).toBe(true, 'actuallyDone should be true'); }); afterEach(() => {
expect(actuallyDone).toBe(true, 'actuallyDone should be true');
});
it('should run normal test', () => { actuallyDone = true; }); it('should run normal test', () => {
actuallyDone = true;
});
it('should run normal async test', (done: DoneFn) => { it('should run normal async test', (done: DoneFn) => {
setTimeout(() => { setTimeout(() => {
@ -21,39 +26,50 @@ describe('Angular async helper', () => {
}, 0); }, 0);
}); });
it('should run async test with task', it('should run async test with task', waitForAsync(() => {
async(() => { setTimeout(() => { actuallyDone = true; }, 0); })); setTimeout(() => {
actuallyDone = true;
}, 0);
}));
it('should run async test with task', async(() => { it('should run async test with task', waitForAsync(() => {
const id = setInterval(() => { const id = setInterval(() => {
actuallyDone = true; actuallyDone = true;
clearInterval(id); clearInterval(id);
}, 100); }, 100);
})); }));
it('should run async test with successful promise', async(() => { it('should run async test with successful promise', waitForAsync(() => {
const p = new Promise(resolve => { setTimeout(resolve, 10); }); const p = new Promise(resolve => {
p.then(() => { actuallyDone = true; }); setTimeout(resolve, 10);
});
p.then(() => {
actuallyDone = true;
});
})); }));
it('should run async test with failed promise', async(() => { it('should run async test with failed promise', waitForAsync(() => {
const p = new Promise((resolve, reject) => { setTimeout(reject, 10); }); const p = new Promise((resolve, reject) => {
p.catch(() => { actuallyDone = true; }); setTimeout(reject, 10);
});
p.catch(() => {
actuallyDone = true;
});
})); }));
// Use done. Can also use async or fakeAsync. // Use done. Can also use async or fakeAsync.
it('should run async test with successful delayed Observable', (done: DoneFn) => { it('should run async test with successful delayed Observable', (done: DoneFn) => {
const source = of (true).pipe(delay(10)); const source = of(true).pipe(delay(10));
source.subscribe(val => actuallyDone = true, err => fail(err), done); source.subscribe(val => actuallyDone = true, err => fail(err), done);
}); });
it('should run async test with successful delayed Observable', async(() => { it('should run async test with successful delayed Observable', waitForAsync(() => {
const source = of (true).pipe(delay(10)); const source = of(true).pipe(delay(10));
source.subscribe(val => actuallyDone = true, err => fail(err)); source.subscribe(val => actuallyDone = true, err => fail(err));
})); }));
it('should run async test with successful delayed Observable', fakeAsync(() => { it('should run async test with successful delayed Observable', fakeAsync(() => {
const source = of (true).pipe(delay(10)); const source = of(true).pipe(delay(10));
source.subscribe(val => actuallyDone = true, err => fail(err)); source.subscribe(val => actuallyDone = true, err => fail(err));
tick(10); tick(10);
@ -64,7 +80,9 @@ describe('Angular async helper', () => {
// #docregion fake-async-test-tick // #docregion fake-async-test-tick
it('should run timeout callback with delay after call tick with millis', fakeAsync(() => { it('should run timeout callback with delay after call tick with millis', fakeAsync(() => {
let called = false; let called = false;
setTimeout(() => { called = true; }, 100); setTimeout(() => {
called = true;
}, 100);
tick(100); tick(100);
expect(called).toBe(true); expect(called).toBe(true);
})); }));
@ -73,7 +91,9 @@ describe('Angular async helper', () => {
// #docregion fake-async-test-tick-new-macro-task-sync // #docregion fake-async-test-tick-new-macro-task-sync
it('should run new macro task callback with delay after call tick with millis', it('should run new macro task callback with delay after call tick with millis',
fakeAsync(() => { fakeAsync(() => {
function nestedTimer(cb: () => any): void { setTimeout(() => setTimeout(() => cb())); } function nestedTimer(cb: () => any): void {
setTimeout(() => setTimeout(() => cb()));
}
const callback = jasmine.createSpy('callback'); const callback = jasmine.createSpy('callback');
nestedTimer(callback); nestedTimer(callback);
expect(callback).not.toHaveBeenCalled(); expect(callback).not.toHaveBeenCalled();
@ -86,7 +106,9 @@ describe('Angular async helper', () => {
// #docregion fake-async-test-tick-new-macro-task-async // #docregion fake-async-test-tick-new-macro-task-async
it('should not run new macro task callback with delay after call tick with millis', it('should not run new macro task callback with delay after call tick with millis',
fakeAsync(() => { fakeAsync(() => {
function nestedTimer(cb: () => any): void { setTimeout(() => setTimeout(() => cb())); } function nestedTimer(cb: () => any): void {
setTimeout(() => setTimeout(() => cb()));
}
const callback = jasmine.createSpy('callback'); const callback = jasmine.createSpy('callback');
nestedTimer(callback); nestedTimer(callback);
expect(callback).not.toHaveBeenCalled(); expect(callback).not.toHaveBeenCalled();
@ -112,7 +134,9 @@ describe('Angular async helper', () => {
// need to add `import 'zone.js/dist/zone-patch-rxjs-fake-async' // need to add `import 'zone.js/dist/zone-patch-rxjs-fake-async'
// to patch rxjs scheduler // to patch rxjs scheduler
let result = null; let result = null;
of ('hello').pipe(delay(1000)).subscribe(v => { result = v; }); of('hello').pipe(delay(1000)).subscribe(v => {
result = v;
});
expect(result).toBeNull(); expect(result).toBeNull();
tick(1000); tick(1000);
expect(result).toBe('hello'); expect(result).toBe('hello');
@ -133,12 +157,18 @@ describe('Angular async helper', () => {
describe('use jasmine.clock()', () => { describe('use jasmine.clock()', () => {
// need to config __zone_symbol__fakeAsyncPatchLock flag // need to config __zone_symbol__fakeAsyncPatchLock flag
// before loading zone.js/dist/zone-testing // before loading zone.js/dist/zone-testing
beforeEach(() => { jasmine.clock().install(); }); beforeEach(() => {
afterEach(() => { jasmine.clock().uninstall(); }); jasmine.clock().install();
});
afterEach(() => {
jasmine.clock().uninstall();
});
it('should auto enter fakeAsync', () => { it('should auto enter fakeAsync', () => {
// is in fakeAsync now, don't need to call fakeAsync(testFn) // is in fakeAsync now, don't need to call fakeAsync(testFn)
let called = false; let called = false;
setTimeout(() => { called = true; }, 100); setTimeout(() => {
called = true;
}, 100);
jasmine.clock().tick(100); jasmine.clock().tick(100);
expect(called).toBe(true); expect(called).toBe(true);
}); });
@ -152,7 +182,7 @@ describe('Angular async helper', () => {
} }
// need to config __zone_symbol__supportWaitUnResolvedChainedPromise flag // need to config __zone_symbol__supportWaitUnResolvedChainedPromise flag
// before loading zone.js/dist/zone-testing // before loading zone.js/dist/zone-testing
it('should wait until promise.then is called', async(() => { it('should wait until promise.then is called', waitForAsync(() => {
let finished = false; let finished = false;
new Promise((res, rej) => { new Promise((res, rej) => {
jsonp('localhost:8080/jsonp', () => { jsonp('localhost:8080/jsonp', () => {
@ -168,5 +198,4 @@ describe('Angular async helper', () => {
})); }));
}); });
// #enddocregion async-test-promise-then // #enddocregion async-test-promise-then
}); });

View File

@ -24,17 +24,18 @@ import { FormsModule } from '@angular/forms';
// Forms symbols imported only for a specific test below // Forms symbols imported only for a specific test below
import { NgModel, NgControl } from '@angular/forms'; import { NgModel, NgControl } from '@angular/forms';
import { async, ComponentFixture, fakeAsync, inject, TestBed, tick import {
ComponentFixture, fakeAsync, inject, TestBed, tick, waitForAsync
} from '@angular/core/testing'; } from '@angular/core/testing';
import { addMatchers, newEvent, click } from '../../testing'; import { addMatchers, newEvent, click } from '../../testing';
export class NotProvided extends ValueService { /* example below */} export class NotProvided extends ValueService { /* example below */ }
beforeEach( addMatchers ); beforeEach(addMatchers);
describe('demo (with TestBed):', () => { describe('demo (with TestBed):', () => {
//////// Service Tests ///////////// //////// Service Tests /////////////
// #docregion ValueService // #docregion ValueService
describe('ValueService', () => { describe('ValueService', () => {
@ -64,13 +65,13 @@ describe('demo (with TestBed):', () => {
// #enddocregion testbed-get-w-null // #enddocregion testbed-get-w-null
}); });
it('test should wait for ValueService.getPromiseValue', async(() => { it('test should wait for ValueService.getPromiseValue', waitForAsync(() => {
service.getPromiseValue().then( service.getPromiseValue().then(
value => expect(value).toBe('promise value') value => expect(value).toBe('promise value')
); );
})); }));
it('test should wait for ValueService.getObservableValue', async(() => { it('test should wait for ValueService.getObservableValue', waitForAsync(() => {
service.getObservableValue().subscribe( service.getObservableValue().subscribe(
value => expect(value).toBe('observable value') value => expect(value).toBe('observable value')
); );
@ -150,7 +151,7 @@ describe('demo (with TestBed):', () => {
TestBed.configureTestingModule({ providers: [ValueService] }); TestBed.configureTestingModule({ providers: [ValueService] });
}); });
beforeEach(async(inject([ValueService], (service: ValueService) => { beforeEach(waitForAsync(inject([ValueService], (service: ValueService) => {
service.getPromiseValue().then(value => serviceValue = value); service.getPromiseValue().then(value => serviceValue = value);
}))); })));
@ -159,11 +160,11 @@ describe('demo (with TestBed):', () => {
}); });
}); });
/////////// Component Tests ////////////////// /////////// Component Tests //////////////////
describe('TestBed component tests', () => { describe('TestBed component tests', () => {
beforeEach(async(() => { beforeEach(waitForAsync(() => {
TestBed TestBed
.configureTestingModule({ .configureTestingModule({
imports: [DemoModule], imports: [DemoModule],
@ -235,7 +236,7 @@ describe('demo (with TestBed):', () => {
// #docregion ButtonComp // #docregion ButtonComp
it('should support clicking a button', () => { it('should support clicking a button', () => {
const fixture = TestBed.createComponent(LightswitchComponent); const fixture = TestBed.createComponent(LightswitchComponent);
const btn = fixture.debugElement.query(By.css('button')); const btn = fixture.debugElement.query(By.css('button'));
const span = fixture.debugElement.query(By.css('span')).nativeElement; const span = fixture.debugElement.query(By.css('span')).nativeElement;
fixture.detectChanges(); fixture.detectChanges();
@ -248,7 +249,7 @@ describe('demo (with TestBed):', () => {
// #enddocregion ButtonComp // #enddocregion ButtonComp
// ngModel is async so we must wait for it with promise-based `whenStable` // ngModel is async so we must wait for it with promise-based `whenStable`
it('should support entering text in input box (ngModel)', async(() => { it('should support entering text in input box (ngModel)', waitForAsync(() => {
const expectedOrigName = 'John'; const expectedOrigName = 'John';
const expectedNewName = 'Sally'; const expectedNewName = 'Sally';
@ -278,10 +279,10 @@ describe('demo (with TestBed):', () => {
input.dispatchEvent(newEvent('input')); input.dispatchEvent(newEvent('input'));
return fixture.whenStable(); return fixture.whenStable();
}) })
.then(() => { .then(() => {
expect(comp.name).toBe(expectedNewName, expect(comp.name).toBe(expectedNewName,
`After ngModel updates the model, comp.name should be ${expectedNewName} `); `After ngModel updates the model, comp.name should be ${expectedNewName} `);
}); });
})); }));
// fakeAsync version of ngModel input test enables sync test style // fakeAsync version of ngModel input test enables sync test style
@ -327,9 +328,9 @@ describe('demo (with TestBed):', () => {
const fixture = TestBed.createComponent(ReversePipeComponent); const fixture = TestBed.createComponent(ReversePipeComponent);
fixture.detectChanges(); fixture.detectChanges();
const comp = fixture.componentInstance; const comp = fixture.componentInstance;
const input = fixture.debugElement.query(By.css('input')).nativeElement as HTMLInputElement; const input = fixture.debugElement.query(By.css('input')).nativeElement as HTMLInputElement;
const span = fixture.debugElement.query(By.css('span')).nativeElement as HTMLElement; const span = fixture.debugElement.query(By.css('span')).nativeElement as HTMLElement;
// simulate user entering new name in input // simulate user entering new name in input
input.value = inputText; input.value = inputText;
@ -381,12 +382,12 @@ describe('demo (with TestBed):', () => {
expect(el.styles.color).toBe(comp.color, 'color style'); expect(el.styles.color).toBe(comp.color, 'color style');
expect(el.styles.width).toBe(comp.width + 'px', 'width style'); expect(el.styles.width).toBe(comp.width + 'px', 'width style');
// #enddocregion dom-attributes // #enddocregion dom-attributes
// Removed on 12/02/2016 when ceased public discussion of the `Renderer`. Revive in future? // Removed on 12/02/2016 when ceased public discussion of the `Renderer`. Revive in future?
// expect(el.properties['customProperty']).toBe(true, 'customProperty'); // expect(el.properties['customProperty']).toBe(true, 'customProperty');
// #docregion dom-attributes // #docregion dom-attributes
}); });
// #enddocregion dom-attributes // #enddocregion dom-attributes
@ -400,10 +401,10 @@ describe('demo (with TestBed):', () => {
const fixture = TestBed.configureTestingModule({ const fixture = TestBed.configureTestingModule({
declarations: [Child1Component], declarations: [Child1Component],
}) })
.overrideComponent(Child1Component, { .overrideComponent(Child1Component, {
set: { template: '<span>Fake</span>' } set: { template: '<span>Fake</span>' }
}) })
.createComponent(Child1Component); .createComponent(Child1Component);
fixture.detectChanges(); fixture.detectChanges();
expect(fixture).toHaveText('Fake'); expect(fixture).toHaveText('Fake');
@ -413,14 +414,14 @@ describe('demo (with TestBed):', () => {
const fixture = TestBed.configureTestingModule({ const fixture = TestBed.configureTestingModule({
declarations: [TestProvidersComponent], declarations: [TestProvidersComponent],
}) })
.overrideComponent(TestProvidersComponent, { .overrideComponent(TestProvidersComponent, {
remove: { providers: [ValueService]}, remove: { providers: [ValueService] },
add: { providers: [{ provide: ValueService, useClass: FakeValueService }] }, add: { providers: [{ provide: ValueService, useClass: FakeValueService }] },
// Or replace them all (this component has only one provider) // Or replace them all (this component has only one provider)
// set: { providers: [{ provide: ValueService, useClass: FakeValueService }] }, // set: { providers: [{ provide: ValueService, useClass: FakeValueService }] },
}) })
.createComponent(TestProvidersComponent); .createComponent(TestProvidersComponent);
fixture.detectChanges(); fixture.detectChanges();
expect(fixture).toHaveText('injected value: faked value', 'text'); expect(fixture).toHaveText('injected value: faked value', 'text');
@ -436,14 +437,14 @@ describe('demo (with TestBed):', () => {
const fixture = TestBed.configureTestingModule({ const fixture = TestBed.configureTestingModule({
declarations: [TestViewProvidersComponent], declarations: [TestViewProvidersComponent],
}) })
.overrideComponent(TestViewProvidersComponent, { .overrideComponent(TestViewProvidersComponent, {
// remove: { viewProviders: [ValueService]}, // remove: { viewProviders: [ValueService]},
// add: { viewProviders: [{ provide: ValueService, useClass: FakeValueService }] }, // add: { viewProviders: [{ provide: ValueService, useClass: FakeValueService }] },
// Or replace them all (this component has only one viewProvider) // Or replace them all (this component has only one viewProvider)
set: { viewProviders: [{ provide: ValueService, useClass: FakeValueService }] }, set: { viewProviders: [{ provide: ValueService, useClass: FakeValueService }] },
}) })
.createComponent(TestViewProvidersComponent); .createComponent(TestViewProvidersComponent);
fixture.detectChanges(); fixture.detectChanges();
expect(fixture).toHaveText('injected value: faked value'); expect(fixture).toHaveText('injected value: faked value');
@ -453,20 +454,20 @@ describe('demo (with TestBed):', () => {
// TestComponent is parent of TestProvidersComponent // TestComponent is parent of TestProvidersComponent
@Component({ template: '<my-service-comp></my-service-comp>' }) @Component({ template: '<my-service-comp></my-service-comp>' })
class TestComponent {} class TestComponent { }
// 3 levels of ValueService provider: module, TestCompomponent, TestProvidersComponent // 3 levels of ValueService provider: module, TestCompomponent, TestProvidersComponent
const fixture = TestBed.configureTestingModule({ const fixture = TestBed.configureTestingModule({
declarations: [TestComponent, TestProvidersComponent], declarations: [TestComponent, TestProvidersComponent],
providers: [ValueService] providers: [ValueService]
}) })
.overrideComponent(TestComponent, { .overrideComponent(TestComponent, {
set: { providers: [{ provide: ValueService, useValue: {} }] } set: { providers: [{ provide: ValueService, useValue: {} }] }
}) })
.overrideComponent(TestProvidersComponent, { .overrideComponent(TestProvidersComponent, {
set: { providers: [{ provide: ValueService, useClass: FakeValueService }] } set: { providers: [{ provide: ValueService, useClass: FakeValueService }] }
}) })
.createComponent(TestComponent); .createComponent(TestComponent);
let testBedProvider: ValueService; let testBedProvider: ValueService;
let tcProvider: ValueService; let tcProvider: ValueService;
@ -489,10 +490,10 @@ describe('demo (with TestBed):', () => {
const fixture = TestBed.configureTestingModule({ const fixture = TestBed.configureTestingModule({
declarations: [ShellComponent, NeedsContentComponent, Child1Component, Child2Component, Child3Component], declarations: [ShellComponent, NeedsContentComponent, Child1Component, Child2Component, Child3Component],
}) })
.overrideComponent(ShellComponent, { .overrideComponent(ShellComponent, {
set: { set: {
selector: 'test-shell', selector: 'test-shell',
template: ` template: `
<needs-content #nc> <needs-content #nc>
<child-1 #content text="My"></child-1> <child-1 #content text="My"></child-1>
<child-2 #content text="dog"></child-2> <child-2 #content text="dog"></child-2>
@ -501,9 +502,9 @@ describe('demo (with TestBed):', () => {
<div #content>!</div> <div #content>!</div>
</needs-content> </needs-content>
` `
} }
}) })
.createComponent(ShellComponent); .createComponent(ShellComponent);
fixture.detectChanges(); fixture.detectChanges();
@ -615,7 +616,7 @@ describe('demo (with TestBed):', () => {
}); });
// must be async test to see child flow to parent // must be async test to see child flow to parent
it('changed child value flows to parent', async(() => { it('changed child value flows to parent', waitForAsync(() => {
fixture.detectChanges(); fixture.detectChanges();
getChild(); getChild();
@ -625,14 +626,14 @@ describe('demo (with TestBed):', () => {
// Wait one JS engine turn! // Wait one JS engine turn!
setTimeout(() => resolve(), 0); setTimeout(() => resolve(), 0);
}) })
.then(() => { .then(() => {
fixture.detectChanges(); fixture.detectChanges();
expect(child.ngOnChangesCounter).toBe(2, expect(child.ngOnChangesCounter).toBe(2,
'expected 2 changes: initial value and changed value'); 'expected 2 changes: initial value and changed value');
expect(parent.parentValue).toBe('bar', expect(parent.parentValue).toBe('bar',
'parentValue should eq changed parent value'); 'parentValue should eq changed parent value');
}); });
})); }));

View File

@ -1,8 +1,5 @@
// #docplaster // #docplaster
import { import { ComponentFixture, fakeAsync, inject, TestBed, tick, waitForAsync } from '@angular/core/testing';
async, ComponentFixture, fakeAsync, inject, TestBed, tick
} from '@angular/core/testing';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { import {
@ -36,59 +33,54 @@ describe('HeroDetailComponent', () => {
function overrideSetup() { function overrideSetup() {
// #docregion hds-spy // #docregion hds-spy
class HeroDetailServiceSpy { class HeroDetailServiceSpy {
testHero: Hero = {id: 42, name: 'Test Hero' }; testHero: Hero = {id: 42, name: 'Test Hero'};
/* emit cloned test hero */ /* emit cloned test hero */
getHero = jasmine.createSpy('getHero').and.callFake( getHero = jasmine.createSpy('getHero').and.callFake(
() => asyncData(Object.assign({}, this.testHero)) () => asyncData(Object.assign({}, this.testHero)));
);
/* emit clone of test hero, with changes merged in */ /* emit clone of test hero, with changes merged in */
saveHero = jasmine.createSpy('saveHero').and.callFake( saveHero = jasmine.createSpy('saveHero')
(hero: Hero) => asyncData(Object.assign(this.testHero, hero)) .and.callFake((hero: Hero) => asyncData(Object.assign(this.testHero, hero)));
);
} }
// #enddocregion hds-spy // #enddocregion hds-spy
// the `id` value is irrelevant because ignored by service stub // the `id` value is irrelevant because ignored by service stub
beforeEach(() => activatedRoute.setParamMap({ id: 99999 })); beforeEach(() => activatedRoute.setParamMap({id: 99999}));
// #docregion setup-override // #docregion setup-override
beforeEach(async(() => { beforeEach(waitForAsync(() => {
const routerSpy = createRouterSpy(); const routerSpy = createRouterSpy();
TestBed.configureTestingModule({ TestBed
imports: [ HeroModule ], .configureTestingModule({
providers: [ imports: [HeroModule],
{ provide: ActivatedRoute, useValue: activatedRoute }, providers: [
{ provide: Router, useValue: routerSpy}, {provide: ActivatedRoute, useValue: activatedRoute},
{provide: Router, useValue: routerSpy},
// #enddocregion setup-override // #enddocregion setup-override
// HeroDetailService at this level is IRRELEVANT! // HeroDetailService at this level is IRRELEVANT!
{ provide: HeroDetailService, useValue: {} } {provide: HeroDetailService, useValue: {}}
// #docregion setup-override // #docregion setup-override
] ]
}) })
// Override component's own provider // Override component's own provider
// #docregion override-component-method // #docregion override-component-method
.overrideComponent(HeroDetailComponent, { .overrideComponent(
set: { HeroDetailComponent,
providers: [ {set: {providers: [{provide: HeroDetailService, useClass: HeroDetailServiceSpy}]}})
{ provide: HeroDetailService, useClass: HeroDetailServiceSpy } // #enddocregion override-component-method
]
}
})
// #enddocregion override-component-method
.compileComponents(); .compileComponents();
})); }));
// #enddocregion setup-override // #enddocregion setup-override
// #docregion override-tests // #docregion override-tests
let hdsSpy: HeroDetailServiceSpy; let hdsSpy: HeroDetailServiceSpy;
beforeEach(async(() => { beforeEach(waitForAsync(() => {
createComponent(); createComponent();
// get the component's injected HeroDetailServiceSpy // get the component's injected HeroDetailServiceSpy
hdsSpy = fixture.debugElement.injector.get(HeroDetailService) as any; hdsSpy = fixture.debugElement.injector.get(HeroDetailService) as any;
@ -103,33 +95,32 @@ function overrideSetup() {
}); });
it('should save stub hero change', fakeAsync(() => { it('should save stub hero change', fakeAsync(() => {
const origName = hdsSpy.testHero.name; const origName = hdsSpy.testHero.name;
const newName = 'New Name'; const newName = 'New Name';
page.nameInput.value = newName; page.nameInput.value = newName;
page.nameInput.dispatchEvent(newEvent('input')); // tell Angular page.nameInput.dispatchEvent(newEvent('input')); // tell Angular
expect(component.hero.name).toBe(newName, 'component hero has new name'); expect(component.hero.name).toBe(newName, 'component hero has new name');
expect(hdsSpy.testHero.name).toBe(origName, 'service hero unchanged before save'); expect(hdsSpy.testHero.name).toBe(origName, 'service hero unchanged before save');
click(page.saveBtn); click(page.saveBtn);
expect(hdsSpy.saveHero.calls.count()).toBe(1, 'saveHero called once'); expect(hdsSpy.saveHero.calls.count()).toBe(1, 'saveHero called once');
tick(); // wait for async save to complete tick(); // wait for async save to complete
expect(hdsSpy.testHero.name).toBe(newName, 'service hero has new name after save'); expect(hdsSpy.testHero.name).toBe(newName, 'service hero has new name after save');
expect(page.navigateSpy.calls.any()).toBe(true, 'router.navigate called'); expect(page.navigateSpy.calls.any()).toBe(true, 'router.navigate called');
})); }));
// #enddocregion override-tests // #enddocregion override-tests
it('fixture injected service is not the component injected service', it('fixture injected service is not the component injected service',
// inject gets the service from the fixture // inject gets the service from the fixture
inject([HeroDetailService], (fixtureService: HeroDetailService) => { inject([HeroDetailService], (fixtureService: HeroDetailService) => {
// use `fixture.debugElement.injector` to get service from component
const componentService = fixture.debugElement.injector.get(HeroDetailService);
// use `fixture.debugElement.injector` to get service from component expect(fixtureService).not.toBe(componentService, 'service injected from fixture');
const componentService = fixture.debugElement.injector.get(HeroDetailService); }));
expect(fixtureService).not.toBe(componentService, 'service injected from fixture');
}));
} }
//////////////////// ////////////////////
@ -139,21 +130,22 @@ const firstHero = getTestHeroes()[0];
function heroModuleSetup() { function heroModuleSetup() {
// #docregion setup-hero-module // #docregion setup-hero-module
beforeEach(async(() => { beforeEach(waitForAsync(() => {
const routerSpy = createRouterSpy(); const routerSpy = createRouterSpy();
TestBed.configureTestingModule({ TestBed
imports: [ HeroModule ], .configureTestingModule({
// #enddocregion setup-hero-module imports: [HeroModule],
// declarations: [ HeroDetailComponent ], // NO! DOUBLE DECLARATION // #enddocregion setup-hero-module
// #docregion setup-hero-module // declarations: [ HeroDetailComponent ], // NO! DOUBLE DECLARATION
providers: [ // #docregion setup-hero-module
{ provide: ActivatedRoute, useValue: activatedRoute }, providers: [
{ provide: HeroService, useClass: TestHeroService }, {provide: ActivatedRoute, useValue: activatedRoute},
{ provide: Router, useValue: routerSpy}, {provide: HeroService, useClass: TestHeroService},
] {provide: Router, useValue: routerSpy},
}) ]
.compileComponents(); })
.compileComponents();
})); }));
// #enddocregion setup-hero-module // #enddocregion setup-hero-module
@ -161,17 +153,17 @@ function heroModuleSetup() {
describe('when navigate to existing hero', () => { describe('when navigate to existing hero', () => {
let expectedHero: Hero; let expectedHero: Hero;
beforeEach(async(() => { beforeEach(waitForAsync(() => {
expectedHero = firstHero; expectedHero = firstHero;
activatedRoute.setParamMap({ id: expectedHero.id }); activatedRoute.setParamMap({id: expectedHero.id});
createComponent(); createComponent();
})); }));
// #docregion selected-tests // #docregion selected-tests
it('should display that hero\'s name', () => { it('should display that hero\'s name', () => {
expect(page.nameDisplay.textContent).toBe(expectedHero.name); expect(page.nameDisplay.textContent).toBe(expectedHero.name);
}); });
// #enddocregion route-good-id // #enddocregion route-good-id
it('should navigate when click cancel', () => { it('should navigate when click cancel', () => {
click(page.cancelBtn); click(page.cancelBtn);
@ -190,10 +182,10 @@ function heroModuleSetup() {
}); });
it('should navigate when click save and save resolves', fakeAsync(() => { it('should navigate when click save and save resolves', fakeAsync(() => {
click(page.saveBtn); click(page.saveBtn);
tick(); // wait for async save to complete tick(); // wait for async save to complete
expect(page.navigateSpy.calls.any()).toBe(true, 'router.navigate called'); expect(page.navigateSpy.calls.any()).toBe(true, 'router.navigate called');
})); }));
// #docregion title-case-pipe // #docregion title-case-pipe
it('should convert hero name to Title Case', () => { it('should convert hero name to Title Case', () => {
@ -215,14 +207,14 @@ function heroModuleSetup() {
expect(nameDisplay.textContent).toBe('Quick Brown Fox'); expect(nameDisplay.textContent).toBe('Quick Brown Fox');
}); });
// #enddocregion title-case-pipe // #enddocregion title-case-pipe
// #enddocregion selected-tests // #enddocregion selected-tests
// #docregion route-good-id // #docregion route-good-id
}); });
// #enddocregion route-good-id // #enddocregion route-good-id
// #docregion route-no-id // #docregion route-no-id
describe('when navigate with no hero id', () => { describe('when navigate with no hero id', () => {
beforeEach(async( createComponent )); beforeEach(waitForAsync(createComponent));
it('should have hero.id === 0', () => { it('should have hero.id === 0', () => {
expect(component.hero.id).toBe(0); expect(component.hero.id).toBe(0);
@ -236,8 +228,8 @@ function heroModuleSetup() {
// #docregion route-bad-id // #docregion route-bad-id
describe('when navigate to non-existent hero id', () => { describe('when navigate to non-existent hero id', () => {
beforeEach(async(() => { beforeEach(waitForAsync(() => {
activatedRoute.setParamMap({ id: 99999 }); activatedRoute.setParamMap({id: 99999});
createComponent(); createComponent();
})); }));
@ -253,11 +245,10 @@ function heroModuleSetup() {
let service: HeroDetailService; let service: HeroDetailService;
fixture = TestBed.createComponent(HeroDetailComponent); fixture = TestBed.createComponent(HeroDetailComponent);
expect( expect(
// Throws because `inject` only has access to TestBed's injector // Throws because `inject` only has access to TestBed's injector
// which is an ancestor of the component's injector // which is an ancestor of the component's injector
inject([HeroDetailService], (hds: HeroDetailService) => service = hds ) inject([HeroDetailService], (hds: HeroDetailService) => service = hds))
) .toThrowError(/No provider for HeroDetailService/);
.toThrowError(/No provider for HeroDetailService/);
// get `HeroDetailService` with component's own injector // get `HeroDetailService` with component's own injector
service = fixture.debugElement.injector.get(HeroDetailService); service = fixture.debugElement.injector.get(HeroDetailService);
@ -270,30 +261,31 @@ import { FormsModule } from '@angular/forms';
import { TitleCasePipe } from '../shared/title-case.pipe'; import { TitleCasePipe } from '../shared/title-case.pipe';
function formsModuleSetup() { function formsModuleSetup() {
// #docregion setup-forms-module // #docregion setup-forms-module
beforeEach(async(() => { beforeEach(waitForAsync(() => {
const routerSpy = createRouterSpy(); const routerSpy = createRouterSpy();
TestBed.configureTestingModule({ TestBed
imports: [ FormsModule ], .configureTestingModule({
declarations: [ HeroDetailComponent, TitleCasePipe ], imports: [FormsModule],
providers: [ declarations: [HeroDetailComponent, TitleCasePipe],
{ provide: ActivatedRoute, useValue: activatedRoute }, providers: [
{ provide: HeroService, useClass: TestHeroService }, {provide: ActivatedRoute, useValue: activatedRoute},
{ provide: Router, useValue: routerSpy}, {provide: HeroService, useClass: TestHeroService},
] {provide: Router, useValue: routerSpy},
}) ]
.compileComponents(); })
.compileComponents();
})); }));
// #enddocregion setup-forms-module // #enddocregion setup-forms-module
it('should display 1st hero\'s name', async(() => { it('should display 1st hero\'s name', waitForAsync(() => {
const expectedHero = firstHero; const expectedHero = firstHero;
activatedRoute.setParamMap({ id: expectedHero.id }); activatedRoute.setParamMap({id: expectedHero.id});
createComponent().then(() => { createComponent().then(() => {
expect(page.nameDisplay.textContent).toBe(expectedHero.name); expect(page.nameDisplay.textContent).toBe(expectedHero.name);
}); });
})); }));
} }
/////////////////////// ///////////////////////
@ -301,29 +293,30 @@ import { SharedModule } from '../shared/shared.module';
function sharedModuleSetup() { function sharedModuleSetup() {
// #docregion setup-shared-module // #docregion setup-shared-module
beforeEach(async(() => { beforeEach(waitForAsync(() => {
const routerSpy = createRouterSpy(); const routerSpy = createRouterSpy();
TestBed.configureTestingModule({ TestBed
imports: [ SharedModule ], .configureTestingModule({
declarations: [ HeroDetailComponent ], imports: [SharedModule],
providers: [ declarations: [HeroDetailComponent],
{ provide: ActivatedRoute, useValue: activatedRoute }, providers: [
{ provide: HeroService, useClass: TestHeroService }, {provide: ActivatedRoute, useValue: activatedRoute},
{ provide: Router, useValue: routerSpy}, {provide: HeroService, useClass: TestHeroService},
] {provide: Router, useValue: routerSpy},
}) ]
.compileComponents(); })
.compileComponents();
})); }));
// #enddocregion setup-shared-module // #enddocregion setup-shared-module
it('should display 1st hero\'s name', async(() => { it('should display 1st hero\'s name', waitForAsync(() => {
const expectedHero = firstHero; const expectedHero = firstHero;
activatedRoute.setParamMap({ id: expectedHero.id }); activatedRoute.setParamMap({id: expectedHero.id});
createComponent().then(() => { createComponent().then(() => {
expect(page.nameDisplay.textContent).toBe(expectedHero.name); expect(page.nameDisplay.textContent).toBe(expectedHero.name);
}); });
})); }));
} }
/////////// Helpers ///// /////////// Helpers /////
@ -347,11 +340,21 @@ function createComponent() {
// #docregion page // #docregion page
class Page { class Page {
// getter properties wait to query the DOM until called. // getter properties wait to query the DOM until called.
get buttons() { return this.queryAll<HTMLButtonElement>('button'); } get buttons() {
get saveBtn() { return this.buttons[0]; } return this.queryAll<HTMLButtonElement>('button');
get cancelBtn() { return this.buttons[1]; } }
get nameDisplay() { return this.query<HTMLElement>('span'); } get saveBtn() {
get nameInput() { return this.query<HTMLInputElement>('input'); } return this.buttons[0];
}
get cancelBtn() {
return this.buttons[1];
}
get nameDisplay() {
return this.query<HTMLElement>('span');
}
get nameInput() {
return this.query<HTMLInputElement>('input');
}
gotoListSpy: jasmine.Spy; gotoListSpy: jasmine.Spy;
navigateSpy: jasmine.Spy; navigateSpy: jasmine.Spy;

View File

@ -1,4 +1,4 @@
import { async, ComponentFixture, fakeAsync, TestBed, tick import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync
} from '@angular/core/testing'; } from '@angular/core/testing';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
@ -7,13 +7,12 @@ import { DebugElement } from '@angular/core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { addMatchers, newEvent } from '../../testing'; import { addMatchers, newEvent } from '../../testing';
import { HeroService } from '../model/hero.service';
import { getTestHeroes, TestHeroService } from '../model/testing/test-hero.service'; import { getTestHeroes, TestHeroService } from '../model/testing/test-hero.service';
import { HeroModule } from './hero.module'; import { HeroModule } from './hero.module';
import { HeroListComponent } from './hero-list.component'; import { HeroListComponent } from './hero-list.component';
import { HighlightDirective } from '../shared/highlight.directive'; import { HighlightDirective } from '../shared/highlight.directive';
import { HeroService } from '../model/hero.service';
const HEROES = getTestHeroes(); const HEROES = getTestHeroes();
@ -24,20 +23,20 @@ let page: Page;
/////// Tests ////// /////// Tests //////
describe('HeroListComponent', () => { describe('HeroListComponent', () => {
beforeEach(waitForAsync(() => {
beforeEach(async(() => {
addMatchers(); addMatchers();
const routerSpy = jasmine.createSpyObj('Router', ['navigate']); const routerSpy = jasmine.createSpyObj('Router', ['navigate']);
TestBed.configureTestingModule({ TestBed
imports: [HeroModule], .configureTestingModule({
providers: [ imports: [HeroModule],
{ provide: HeroService, useClass: TestHeroService }, providers: [
{ provide: Router, useValue: routerSpy} {provide: HeroService, useClass: TestHeroService},
] {provide: Router, useValue: routerSpy}
}) ]
.compileComponents() })
.then(createComponent); .compileComponents()
.then(createComponent);
})); }));
it('should display heroes', () => { it('should display heroes', () => {
@ -52,36 +51,35 @@ describe('HeroListComponent', () => {
}); });
it('should select hero on click', fakeAsync(() => { it('should select hero on click', fakeAsync(() => {
const expectedHero = HEROES[1]; const expectedHero = HEROES[1];
const li = page.heroRows[1]; const li = page.heroRows[1];
li.dispatchEvent(newEvent('click')); li.dispatchEvent(newEvent('click'));
tick(); tick();
// `.toEqual` because selectedHero is clone of expectedHero; see FakeHeroService // `.toEqual` because selectedHero is clone of expectedHero; see FakeHeroService
expect(comp.selectedHero).toEqual(expectedHero); expect(comp.selectedHero).toEqual(expectedHero);
})); }));
it('should navigate to selected hero detail on click', fakeAsync(() => { it('should navigate to selected hero detail on click', fakeAsync(() => {
const expectedHero = HEROES[1]; const expectedHero = HEROES[1];
const li = page.heroRows[1]; const li = page.heroRows[1];
li.dispatchEvent(newEvent('click')); li.dispatchEvent(newEvent('click'));
tick(); tick();
// should have navigated // should have navigated
expect(page.navSpy.calls.any()).toBe(true, 'navigate called'); expect(page.navSpy.calls.any()).toBe(true, 'navigate called');
// composed hero detail will be URL like 'heroes/42' // composed hero detail will be URL like 'heroes/42'
// expect link array with the route path and hero id // expect link array with the route path and hero id
// first argument to router.navigate is link array // first argument to router.navigate is link array
const navArgs = page.navSpy.calls.first().args[0]; const navArgs = page.navSpy.calls.first().args[0];
expect(navArgs[0]).toContain('heroes', 'nav to heroes detail URL'); expect(navArgs[0]).toContain('heroes', 'nav to heroes detail URL');
expect(navArgs[1]).toBe(expectedHero.id, 'expected hero.id'); expect(navArgs[1]).toBe(expectedHero.id, 'expected hero.id');
}));
}));
it('should find `HighlightDirective` with `By.directive', () => { it('should find `HighlightDirective` with `By.directive', () => {
// #docregion by // #docregion by
// Can find DebugElement either by css selector or by directive // Can find DebugElement either by css selector or by directive
const h2 = fixture.debugElement.query(By.css('h2')); const h2 = fixture.debugElement.query(By.css('h2'));
const directive = fixture.debugElement.query(By.directive(HighlightDirective)); const directive = fixture.debugElement.query(By.directive(HighlightDirective));
// #enddocregion by // #enddocregion by
expect(h2).toBe(directive); expect(h2).toBe(directive);

View File

@ -1,6 +1,7 @@
// #docplaster // #docplaster
// #docregion without-toBlob-macrotask // #docregion without-toBlob-macrotask
import { TestBed, async, tick, fakeAsync } from '@angular/core/testing'; import { fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing';
import { CanvasComponent } from './canvas.component'; import { CanvasComponent } from './canvas.component';
describe('CanvasComponent', () => { describe('CanvasComponent', () => {
@ -10,29 +11,29 @@ describe('CanvasComponent', () => {
(window as any).__zone_symbol__FakeAsyncTestMacroTask = [ (window as any).__zone_symbol__FakeAsyncTestMacroTask = [
{ {
source: 'HTMLCanvasElement.toBlob', source: 'HTMLCanvasElement.toBlob',
callbackArgs: [{ size: 200 }], callbackArgs: [{size: 200}],
}, },
]; ];
}); });
// #enddocregion enable-toBlob-macrotask // #enddocregion enable-toBlob-macrotask
// #docregion without-toBlob-macrotask // #docregion without-toBlob-macrotask
beforeEach(async(() => { beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({ TestBed
declarations: [ .configureTestingModule({
CanvasComponent declarations: [CanvasComponent],
], })
}).compileComponents(); .compileComponents();
})); }));
it('should be able to generate blob data from canvas', fakeAsync(() => { it('should be able to generate blob data from canvas', fakeAsync(() => {
const fixture = TestBed.createComponent(CanvasComponent); const fixture = TestBed.createComponent(CanvasComponent);
const canvasComp = fixture.componentInstance; const canvasComp = fixture.componentInstance;
fixture.detectChanges(); fixture.detectChanges();
expect(canvasComp.blobSize).toBe(0); expect(canvasComp.blobSize).toBe(0);
tick(); tick();
expect(canvasComp.blobSize).toBeGreaterThan(0); expect(canvasComp.blobSize).toBeGreaterThan(0);
})); }));
}); });
// #enddocregion without-toBlob-macrotask // #enddocregion without-toBlob-macrotask

View File

@ -1,14 +1,13 @@
// #docplaster // #docplaster
import { async, fakeAsync, ComponentFixture, TestBed, tick } from '@angular/core/testing'; import { fakeAsync, ComponentFixture, TestBed, tick, waitForAsync } from '@angular/core/testing';
import { asyncData, asyncError } from '../../testing'; import { asyncData, asyncError } from '../../testing';
import { of, throwError } from 'rxjs'; import { of, throwError } from 'rxjs';
import { last } from 'rxjs/operators'; import { last } from 'rxjs/operators';
import { TwainService } from './twain.service';
import { TwainComponent } from './twain.component'; import { TwainComponent } from './twain.component';
import { TwainService } from './twain.service';
describe('TwainComponent', () => { describe('TwainComponent', () => {
let component: TwainComponent; let component: TwainComponent;
@ -32,14 +31,12 @@ describe('TwainComponent', () => {
// Create a fake TwainService object with a `getQuote()` spy // Create a fake TwainService object with a `getQuote()` spy
const twainService = jasmine.createSpyObj('TwainService', ['getQuote']); const twainService = jasmine.createSpyObj('TwainService', ['getQuote']);
// Make the spy return a synchronous Observable with the test data // Make the spy return a synchronous Observable with the test data
getQuoteSpy = twainService.getQuote.and.returnValue( of(testQuote) ); getQuoteSpy = twainService.getQuote.and.returnValue(of(testQuote));
// #enddocregion spy // #enddocregion spy
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [ TwainComponent ], declarations: [TwainComponent],
providers: [ providers: [{provide: TwainService, useValue: twainService}]
{ provide: TwainService, useValue: twainService }
]
}); });
fixture = TestBed.createComponent(TwainComponent); fixture = TestBed.createComponent(TwainComponent);
@ -58,7 +55,7 @@ describe('TwainComponent', () => {
// The quote would not be immediately available if the service were truly async. // The quote would not be immediately available if the service were truly async.
// #docregion sync-test // #docregion sync-test
it('should show quote after component initialized', () => { it('should show quote after component initialized', () => {
fixture.detectChanges(); // onInit() fixture.detectChanges(); // onInit()
// sync spy result shows testQuote immediately after init // sync spy result shows testQuote immediately after init
expect(quoteEl.textContent).toBe(testQuote); expect(quoteEl.textContent).toBe(testQuote);
@ -71,20 +68,19 @@ describe('TwainComponent', () => {
// Use `fakeAsync` because the component error calls `setTimeout` // Use `fakeAsync` because the component error calls `setTimeout`
// #docregion error-test // #docregion error-test
it('should display error when TwainService fails', fakeAsync(() => { it('should display error when TwainService fails', fakeAsync(() => {
// tell spy to return an error observable // tell spy to return an error observable
getQuoteSpy.and.returnValue( getQuoteSpy.and.returnValue(throwError('TwainService test failure'));
throwError('TwainService test failure'));
fixture.detectChanges(); // onInit() fixture.detectChanges(); // onInit()
// sync spy errors immediately after init // sync spy errors immediately after init
tick(); // flush the component's setTimeout() tick(); // flush the component's setTimeout()
fixture.detectChanges(); // update errorMessage within setTimeout() fixture.detectChanges(); // update errorMessage within setTimeout()
expect(errorMessage()).toMatch(/test failure/, 'should display error'); expect(errorMessage()).toMatch(/test failure/, 'should display error');
expect(quoteEl.textContent).toBe('...', 'should show placeholder'); expect(quoteEl.textContent).toBe('...', 'should show placeholder');
})); }));
// #enddocregion error-test // #enddocregion error-test
}); });
@ -113,28 +109,28 @@ describe('TwainComponent', () => {
// #docregion fake-async-test // #docregion fake-async-test
it('should show quote after getQuote (fakeAsync)', fakeAsync(() => { it('should show quote after getQuote (fakeAsync)', fakeAsync(() => {
fixture.detectChanges(); // ngOnInit() fixture.detectChanges(); // ngOnInit()
expect(quoteEl.textContent).toBe('...', 'should show placeholder'); expect(quoteEl.textContent).toBe('...', 'should show placeholder');
tick(); // flush the observable to get the quote tick(); // flush the observable to get the quote
fixture.detectChanges(); // update view fixture.detectChanges(); // update view
expect(quoteEl.textContent).toBe(testQuote, 'should show quote'); expect(quoteEl.textContent).toBe(testQuote, 'should show quote');
expect(errorMessage()).toBeNull('should not show error'); expect(errorMessage()).toBeNull('should not show error');
})); }));
// #enddocregion fake-async-test // #enddocregion fake-async-test
// #docregion async-test // #docregion async-test
it('should show quote after getQuote (async)', async(() => { it('should show quote after getQuote (async)', waitForAsync(() => {
fixture.detectChanges(); // ngOnInit() fixture.detectChanges(); // ngOnInit()
expect(quoteEl.textContent).toBe('...', 'should show placeholder'); expect(quoteEl.textContent).toBe('...', 'should show placeholder');
fixture.whenStable().then(() => { // wait for async getQuote fixture.whenStable().then(() => { // wait for async getQuote
fixture.detectChanges(); // update view with quote fixture.detectChanges(); // update view with quote
expect(quoteEl.textContent).toBe(testQuote); expect(quoteEl.textContent).toBe(testQuote);
expect(errorMessage()).toBeNull('should not show error'); expect(errorMessage()).toBeNull('should not show error');
}); });
})); }));
// #enddocregion async-test // #enddocregion async-test
@ -142,8 +138,8 @@ describe('TwainComponent', () => {
it('should show last quote (quote done)', (done: DoneFn) => { it('should show last quote (quote done)', (done: DoneFn) => {
fixture.detectChanges(); fixture.detectChanges();
component.quote.pipe( last() ).subscribe(() => { component.quote.pipe(last()).subscribe(() => {
fixture.detectChanges(); // update view with quote fixture.detectChanges(); // update view with quote
expect(quoteEl.textContent).toBe(testQuote); expect(quoteEl.textContent).toBe(testQuote);
expect(errorMessage()).toBeNull('should not show error'); expect(errorMessage()).toBeNull('should not show error');
done(); done();
@ -157,7 +153,7 @@ describe('TwainComponent', () => {
// the spy's most recent call returns the observable with the test quote // the spy's most recent call returns the observable with the test quote
getQuoteSpy.calls.mostRecent().returnValue.subscribe(() => { getQuoteSpy.calls.mostRecent().returnValue.subscribe(() => {
fixture.detectChanges(); // update view with quote fixture.detectChanges(); // update view with quote
expect(quoteEl.textContent).toBe(testQuote); expect(quoteEl.textContent).toBe(testQuote);
expect(errorMessage()).toBeNull('should not show error'); expect(errorMessage()).toBeNull('should not show error');
done(); done();
@ -167,16 +163,16 @@ describe('TwainComponent', () => {
// #docregion async-error-test // #docregion async-error-test
it('should display error when TwainService fails', fakeAsync(() => { it('should display error when TwainService fails', fakeAsync(() => {
// tell spy to return an async error observable // tell spy to return an async error observable
getQuoteSpy.and.returnValue(asyncError<string>('TwainService test failure')); getQuoteSpy.and.returnValue(asyncError<string>('TwainService test failure'));
fixture.detectChanges(); fixture.detectChanges();
tick(); // component shows error after a setTimeout() tick(); // component shows error after a setTimeout()
fixture.detectChanges(); // update error message fixture.detectChanges(); // update error message
expect(errorMessage()).toMatch(/test failure/, 'should display error'); expect(errorMessage()).toMatch(/test failure/, 'should display error');
expect(quoteEl.textContent).toBe('...', 'should show placeholder'); expect(quoteEl.textContent).toBe('...', 'should show placeholder');
})); }));
// #enddocregion async-error-test // #enddocregion async-error-test
}); });
}); });

View File

@ -1,12 +1,12 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { DashboardComponent } from './dashboard.component';
import { HeroSearchComponent } from '../hero-search/hero-search.component';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { of } from 'rxjs'; import { of } from 'rxjs';
import { HEROES } from '../mock-heroes';
import { HeroSearchComponent } from '../hero-search/hero-search.component';
import { HeroService } from '../hero.service'; import { HeroService } from '../hero.service';
import { HEROES } from '../mock-heroes';
import { DashboardComponent } from './dashboard.component';
describe('DashboardComponent', () => { describe('DashboardComponent', () => {
let component: DashboardComponent; let component: DashboardComponent;
@ -14,23 +14,16 @@ describe('DashboardComponent', () => {
let heroService; let heroService;
let getHeroesSpy; let getHeroesSpy;
beforeEach(async(() => { beforeEach(waitForAsync(() => {
heroService = jasmine.createSpyObj('HeroService', ['getHeroes']); heroService = jasmine.createSpyObj('HeroService', ['getHeroes']);
getHeroesSpy = heroService.getHeroes.and.returnValue( of(HEROES) ); getHeroesSpy = heroService.getHeroes.and.returnValue(of(HEROES));
TestBed.configureTestingModule({ TestBed
declarations: [ .configureTestingModule({
DashboardComponent, declarations: [DashboardComponent, HeroSearchComponent],
HeroSearchComponent imports: [RouterTestingModule.withRoutes([])],
], providers: [{provide: HeroService, useValue: heroService}]
imports: [ })
RouterTestingModule.withRoutes([]) .compileComponents();
],
providers: [
{ provide: HeroService, useValue: heroService }
]
})
.compileComponents();
})); }));
beforeEach(() => { beforeEach(() => {
@ -47,12 +40,11 @@ describe('DashboardComponent', () => {
expect(fixture.nativeElement.querySelector('h3').textContent).toEqual('Top Heroes'); expect(fixture.nativeElement.querySelector('h3').textContent).toEqual('Top Heroes');
}); });
it('should call heroService', async(() => { it('should call heroService', waitForAsync(() => {
expect(getHeroesSpy.calls.any()).toBe(true); expect(getHeroesSpy.calls.any()).toBe(true);
})); }));
it('should display 4 links', async(() => {
expect(fixture.nativeElement.querySelectorAll('a').length).toEqual(4);
}));
it('should display 4 links', waitForAsync(() => {
expect(fixture.nativeElement.querySelectorAll('a').length).toEqual(4);
}));
}); });

View File

@ -1,4 +1,4 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit, Input } from '@angular/core';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { Location } from '@angular/common'; import { Location } from '@angular/common';
@ -11,7 +11,7 @@ import { HeroService } from '../hero.service';
styleUrls: [ './hero-detail.component.css' ] styleUrls: [ './hero-detail.component.css' ]
}) })
export class HeroDetailComponent implements OnInit { export class HeroDetailComponent implements OnInit {
hero: Hero; @Input() hero: Hero;
constructor( constructor(
private route: ActivatedRoute, private route: ActivatedRoute,

View File

@ -12,7 +12,7 @@
<!-- Polyfills --> <!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script> <script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script> <script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script> <script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.1.js"></script> <script src="systemjs.config.1.js"></script>

View File

@ -12,7 +12,7 @@
<!-- Polyfills --> <!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script> <script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script> <script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script> <script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.1.js"></script> <script src="systemjs.config.1.js"></script>

View File

@ -12,7 +12,7 @@
<!-- Polyfills --> <!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script> <script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script> <script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script> <script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.1.js"></script> <script src="systemjs.config.1.js"></script>

View File

@ -12,7 +12,7 @@
<!-- Polyfills --> <!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script> <script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script> <script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script> <script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.1.js"></script> <script src="systemjs.config.1.js"></script>

View File

@ -12,7 +12,7 @@
<!-- Polyfills --> <!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script> <script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script> <script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script> <script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.1.js"></script> <script src="systemjs.config.1.js"></script>

View File

@ -12,7 +12,7 @@
<!-- Polyfills --> <!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script> <script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script> <script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script> <script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.1.js"></script> <script src="systemjs.config.1.js"></script>

View File

@ -12,7 +12,7 @@
<!-- Polyfills --> <!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script> <script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script> <script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script> <script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.1.js"></script> <script src="systemjs.config.1.js"></script>

View File

@ -12,7 +12,7 @@
<!-- Polyfills --> <!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script> <script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script> <script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script> <script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.1.js"></script> <script src="systemjs.config.1.js"></script>

View File

@ -12,7 +12,7 @@
<!-- Polyfills --> <!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script> <script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script> <script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script> <script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.1.js"></script> <script src="systemjs.config.1.js"></script>

View File

@ -26,7 +26,7 @@
<script src="phone-detail/phone-detail.module.js"></script> <script src="phone-detail/phone-detail.module.js"></script>
<script src="/node_modules/core-js/client/shim.min.js"></script> <script src="/node_modules/core-js/client/shim.min.js"></script>
<script src="/node_modules/zone.js/dist/zone.min.js"></script> <script src="/node_modules/zone.js/bundles/zone.umd.min.js"></script>
<script>window.module = 'aot';</script> <script>window.module = 'aot';</script>
</head> </head>

View File

@ -1,22 +1,16 @@
// #docregion // #docregion
// #docregion activatedroute // #docregion activatedroute
import { TestBed, waitForAsync } from '@angular/core/testing';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
// #enddocregion activatedroute // #enddocregion activatedroute
import { Observable, of } from 'rxjs'; import { Observable, of } from 'rxjs';
import { async, TestBed } from '@angular/core/testing';
import { PhoneDetailComponent } from './phone-detail.component'; import { PhoneDetailComponent } from './phone-detail.component';
import { Phone, PhoneData } from '../core/phone/phone.service'; import { Phone, PhoneData } from '../core/phone/phone.service';
import { CheckmarkPipe } from '../core/checkmark/checkmark.pipe'; import { CheckmarkPipe } from '../core/checkmark/checkmark.pipe';
function xyzPhoneData(): PhoneData { function xyzPhoneData(): PhoneData {
return { return {name: 'phone xyz', snippet: '', images: ['image/url1.png', 'image/url2.png']};
name: 'phone xyz',
snippet: '',
images: ['image/url1.png', 'image/url2.png']
};
} }
class MockPhone { class MockPhone {
@ -34,10 +28,9 @@ class ActivatedRouteMock {
// #enddocregion activatedroute // #enddocregion activatedroute
describe('PhoneDetailComponent', () => { describe('PhoneDetailComponent', () => {
// #docregion activatedroute // #docregion activatedroute
beforeEach(async(() => { beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [ CheckmarkPipe, PhoneDetailComponent ], declarations: [ CheckmarkPipe, PhoneDetailComponent ],
providers: [ providers: [
@ -55,5 +48,4 @@ describe('PhoneDetailComponent', () => {
const compiled = fixture.debugElement.nativeElement; const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain(xyzPhoneData().name); expect(compiled.querySelector('h1').textContent).toContain(xyzPhoneData().name);
}); });
}); });

View File

@ -1,13 +1,14 @@
/* tslint:disable */ /* tslint:disable */
// #docregion // #docregion
import { NO_ERRORS_SCHEMA } from '@angular/core'; import {SpyLocation} from '@angular/common/testing';
import { ActivatedRoute } from '@angular/router'; import {NO_ERRORS_SCHEMA} from '@angular/core';
import { Observable, of } from 'rxjs'; import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import {ActivatedRoute} from '@angular/router';
import { SpyLocation } from '@angular/common/testing'; import {Observable, of} from 'rxjs';
import { PhoneListComponent } from './phone-list.component'; import {Phone, PhoneData} from '../core/phone/phone.service';
import { Phone, PhoneData } from '../core/phone/phone.service';
import {PhoneListComponent} from './phone-list.component';
class ActivatedRouteMock { class ActivatedRouteMock {
constructor(public snapshot: any) {} constructor(public snapshot: any) {}
@ -16,8 +17,7 @@ class ActivatedRouteMock {
class MockPhone { class MockPhone {
query(): Observable<PhoneData[]> { query(): Observable<PhoneData[]> {
return of([ return of([
{name: 'Nexus S', snippet: '', images: []}, {name: 'Nexus S', snippet: '', images: []}, {name: 'Motorola DROID', snippet: '', images: []}
{name: 'Motorola DROID', snippet: '', images: []}
]); ]);
} }
} }
@ -25,18 +25,18 @@ class MockPhone {
let fixture: ComponentFixture<PhoneListComponent>; let fixture: ComponentFixture<PhoneListComponent>;
describe('PhoneList', () => { describe('PhoneList', () => {
beforeEach(waitForAsync(() => {
beforeEach(async(() => { TestBed
TestBed.configureTestingModule({ .configureTestingModule({
declarations: [ PhoneListComponent ], declarations: [PhoneListComponent],
providers: [ providers: [
{ provide: ActivatedRoute, useValue: new ActivatedRouteMock({ params: { 'phoneId': 1 } }) }, {provide: ActivatedRoute, useValue: new ActivatedRouteMock({params: {'phoneId': 1}})},
{ provide: Location, useClass: SpyLocation }, {provide: Location, useClass: SpyLocation},
{ provide: Phone, useClass: MockPhone }, {provide: Phone, useClass: MockPhone},
], ],
schemas: [ NO_ERRORS_SCHEMA ] schemas: [NO_ERRORS_SCHEMA]
}) })
.compileComponents(); .compileComponents();
})); }));
beforeEach(() => { beforeEach(() => {
@ -47,20 +47,15 @@ describe('PhoneList', () => {
fixture.detectChanges(); fixture.detectChanges();
let compiled = fixture.debugElement.nativeElement; let compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelectorAll('.phone-list-item').length).toBe(2); expect(compiled.querySelectorAll('.phone-list-item').length).toBe(2);
expect( expect(compiled.querySelector('.phone-list-item:nth-child(1)').textContent)
compiled.querySelector('.phone-list-item:nth-child(1)').textContent .toContain('Motorola DROID');
).toContain('Motorola DROID'); expect(compiled.querySelector('.phone-list-item:nth-child(2)').textContent)
expect( .toContain('Nexus S');
compiled.querySelector('.phone-list-item:nth-child(2)').textContent
).toContain('Nexus S');
}); });
xit('should set the default value of orderProp model', () => { xit('should set the default value of orderProp model', () => {
fixture.detectChanges(); fixture.detectChanges();
let compiled = fixture.debugElement.nativeElement; let compiled = fixture.debugElement.nativeElement;
expect( expect(compiled.querySelector('select option:last-child').selected).toBe(true);
compiled.querySelector('select option:last-child').selected
).toBe(true);
}); });
}); });

View File

@ -3,7 +3,7 @@ var fsExtra = require('fs-extra');
var resources = [ var resources = [
// polyfills // polyfills
'node_modules/core-js/client/shim.min.js', 'node_modules/core-js/client/shim.min.js',
'node_modules/zone.js/dist/zone.min.js', 'node_modules/zone.js/bundles/zone.umd.min.js',
// css // css
'app/app.css', 'app/app.css',
'app/app.animations.css', 'app/app.animations.css',
@ -20,6 +20,7 @@ var resources = [
'app/phone-detail/phone-detail.module.js' 'app/phone-detail/phone-detail.module.js'
]; ];
resources.map(function(sourcePath) { resources.map(function(sourcePath) {
var destPath = `aot/${sourcePath}`; // Need to rename zone.umd.min.js to zone.min.js
var destPath = `aot/${sourcePath}`.replace('.umd.min.js', '.min.js');
fsExtra.copySync(sourcePath, destPath); fsExtra.copySync(sourcePath, destPath);
}); });

View File

@ -27,7 +27,7 @@
<!-- #docregion angular --> <!-- #docregion angular -->
<script src="/node_modules/core-js/client/shim.min.js"></script> <script src="/node_modules/core-js/client/shim.min.js"></script>
<script src="/node_modules/zone.js/dist/zone.js"></script> <script src="/node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="/node_modules/systemjs/dist/system.src.js"></script> <script src="/node_modules/systemjs/dist/system.src.js"></script>
<!-- #enddocregion angular --> <!-- #enddocregion angular -->
<script src="/systemjs.config.1.js"></script> <script src="/systemjs.config.1.js"></script>

View File

@ -21,8 +21,8 @@ module.exports = function(config) {
'node_modules/core-js/client/shim.js', 'node_modules/core-js/client/shim.js',
// zone.js // zone.js
'node_modules/zone.js/dist/zone.js', 'node_modules/zone.js/bundles/zone.umd.js',
'node_modules/zone.js/dist/zone-testing.js', 'node_modules/zone.js/bundles/zone-testing.umd.js',
// RxJs. // RxJs.
{ pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false }, { pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false },

View File

@ -31,8 +31,8 @@ module.exports = function(config) {
'node_modules/core-js/client/shim.js', 'node_modules/core-js/client/shim.js',
// zone.js // zone.js
'node_modules/zone.js/dist/zone.js', 'node_modules/zone.js/bundles/zone.umd.js',
'node_modules/zone.js/dist/zone-testing.js', 'node_modules/zone.js/bundles/zone-testing.umd.js',
// RxJs // RxJs
{ pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false }, { pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false },

View File

@ -1,22 +1,16 @@
// #docregion // #docregion
// #docregion activatedroute // #docregion activatedroute
import { TestBed, waitForAsync } from '@angular/core/testing';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
// #enddocregion activatedroute // #enddocregion activatedroute
import { Observable, of } from 'rxjs'; import { Observable, of } from 'rxjs';
import { async, TestBed } from '@angular/core/testing';
import { PhoneDetailComponent } from './phone-detail.component'; import { PhoneDetailComponent } from './phone-detail.component';
import { Phone, PhoneData } from '../core/phone/phone.service'; import { Phone, PhoneData } from '../core/phone/phone.service';
import { CheckmarkPipe } from '../core/checkmark/checkmark.pipe'; import { CheckmarkPipe } from '../core/checkmark/checkmark.pipe';
function xyzPhoneData(): PhoneData { function xyzPhoneData(): PhoneData {
return { return {name: 'phone xyz', snippet: '', images: ['image/url1.png', 'image/url2.png']};
name: 'phone xyz',
snippet: '',
images: ['image/url1.png', 'image/url2.png']
};
} }
class MockPhone { class MockPhone {
@ -34,10 +28,9 @@ class ActivatedRouteMock {
// #enddocregion activatedroute // #enddocregion activatedroute
describe('PhoneDetailComponent', () => { describe('PhoneDetailComponent', () => {
// #docregion activatedroute // #docregion activatedroute
beforeEach(async(() => { beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [ CheckmarkPipe, PhoneDetailComponent ], declarations: [ CheckmarkPipe, PhoneDetailComponent ],
providers: [ providers: [
@ -55,5 +48,4 @@ describe('PhoneDetailComponent', () => {
const compiled = fixture.debugElement.nativeElement; const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain(xyzPhoneData().name); expect(compiled.querySelector('h1').textContent).toContain(xyzPhoneData().name);
}); });
}); });

View File

@ -1,13 +1,14 @@
/* tslint:disable */ /* tslint:disable */
// #docregion routestuff // #docregion routestuff
import { NO_ERRORS_SCHEMA } from '@angular/core'; import {SpyLocation} from '@angular/common/testing';
import { ActivatedRoute } from '@angular/router'; import {NO_ERRORS_SCHEMA} from '@angular/core';
import { Observable, of } from 'rxjs'; import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import {ActivatedRoute} from '@angular/router';
import { SpyLocation } from '@angular/common/testing'; import {Observable, of} from 'rxjs';
import { PhoneListComponent } from './phone-list.component'; import {Phone, PhoneData} from '../core/phone/phone.service';
import { Phone, PhoneData } from '../core/phone/phone.service';
import {PhoneListComponent} from './phone-list.component';
// #enddocregion routestuff // #enddocregion routestuff
@ -18,8 +19,7 @@ class ActivatedRouteMock {
class MockPhone { class MockPhone {
query(): Observable<PhoneData[]> { query(): Observable<PhoneData[]> {
return of([ return of([
{name: 'Nexus S', snippet: '', images: []}, {name: 'Nexus S', snippet: '', images: []}, {name: 'Motorola DROID', snippet: '', images: []}
{name: 'Motorola DROID', snippet: '', images: []}
]); ]);
} }
} }
@ -27,20 +27,20 @@ class MockPhone {
let fixture: ComponentFixture<PhoneListComponent>; let fixture: ComponentFixture<PhoneListComponent>;
describe('PhoneList', () => { describe('PhoneList', () => {
// #docregion routestuff // #docregion routestuff
beforeEach(async(() => { beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({ TestBed
declarations: [ PhoneListComponent ], .configureTestingModule({
providers: [ declarations: [PhoneListComponent],
{ provide: ActivatedRoute, useValue: new ActivatedRouteMock({ params: { 'phoneId': 1 } }) }, providers: [
{ provide: Location, useClass: SpyLocation }, {provide: ActivatedRoute, useValue: new ActivatedRouteMock({params: {'phoneId': 1}})},
{ provide: Phone, useClass: MockPhone }, {provide: Location, useClass: SpyLocation},
], {provide: Phone, useClass: MockPhone},
schemas: [ NO_ERRORS_SCHEMA ] ],
}) schemas: [NO_ERRORS_SCHEMA]
.compileComponents(); })
.compileComponents();
})); }));
beforeEach(() => { beforeEach(() => {
@ -52,20 +52,15 @@ describe('PhoneList', () => {
fixture.detectChanges(); fixture.detectChanges();
let compiled = fixture.debugElement.nativeElement; let compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelectorAll('.phone-list-item').length).toBe(2); expect(compiled.querySelectorAll('.phone-list-item').length).toBe(2);
expect( expect(compiled.querySelector('.phone-list-item:nth-child(1)').textContent)
compiled.querySelector('.phone-list-item:nth-child(1)').textContent .toContain('Motorola DROID');
).toContain('Motorola DROID'); expect(compiled.querySelector('.phone-list-item:nth-child(2)').textContent)
expect( .toContain('Nexus S');
compiled.querySelector('.phone-list-item:nth-child(2)').textContent
).toContain('Nexus S');
}); });
xit('should set the default value of orderProp model', () => { xit('should set the default value of orderProp model', () => {
fixture.detectChanges(); fixture.detectChanges();
let compiled = fixture.debugElement.nativeElement; let compiled = fixture.debugElement.nativeElement;
expect( expect(compiled.querySelector('select option:last-child').selected).toBe(true);
compiled.querySelector('select option:last-child').selected
).toBe(true);
}); });
}); });

View File

@ -12,7 +12,7 @@
<link rel="stylesheet" href="app.css" /> <link rel="stylesheet" href="app.css" />
<script src="/node_modules/core-js/client/shim.min.js"></script> <script src="/node_modules/core-js/client/shim.min.js"></script>
<script src="/node_modules/zone.js/dist/zone.js"></script> <script src="/node_modules/zone.js/bundles/zone.umd.js"></script>
<script src="/node_modules/systemjs/dist/system.src.js"></script> <script src="/node_modules/systemjs/dist/system.src.js"></script>
<!-- #enddocregion full --> <!-- #enddocregion full -->
<script src="/systemjs.config.1.js"></script> <script src="/systemjs.config.1.js"></script>

View File

@ -31,8 +31,8 @@ module.exports = function(config) {
'node_modules/core-js/client/shim.js', 'node_modules/core-js/client/shim.js',
// zone.js // zone.js
'node_modules/zone.js/dist/zone.js', 'node_modules/zone.js/bundles/zone.umd.js',
'node_modules/zone.js/dist/zone-testing.js', 'node_modules/zone.js/bundles/zone-testing.umd.js',
// RxJs // RxJs
{ pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false }, { pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false },

View File

@ -1,111 +1,112 @@
# Accessibility in Angular # Accesibilidad en Angular
The web is used by a wide variety of people, including those who have visual or motor impairments. Hay una amplia variedad de personas que utilizan la web, algunas de ellas con discapacidad visual o motora.
A variety of assistive technologies are available that make it much easier for these groups to Existen diferentes tecnologías de apoyo que hacen que sea mucho más fácil para estos grupos
interact with web-based software applications. interactuar con aplicaciones de software basadas en la web.
In addition, designing an application to be more accessible generally improves the user experience for all users. Además, diseñar una aplicación para que sea más accesible, normalmente mejora la experiencia de usuario en general.
For an in-depth introduction to issues and techniques for designing accessible applications, see the [Accessibility](https://developers.google.com/web/fundamentals/accessibility/#what_is_accessibility) section of the Google's [Web Fundamentals](https://developers.google.com/web/fundamentals/). Para una introducción en profundidad a los problemas y técnicas sobre el diseño de aplicaciones accesibles, puede consultar la sección de [Accesibilidad](https://developers.google.com/web/fundamentals/accessibility/#what_is_accessibility) de Google [Fundamentos Web](https://developers.google.com/web/fundamentals/).
This page discusses best practices for designing Angular applications that Esta página habla de las mejores prácticas para diseñar aplicaciones en Angular que funcionan
work well for all users, including those who rely on assistive technologies. bien para todos los usuarios, incluyendo aquéllos que necesitan tecnologías de apoyo.
<div class="alert is-helpful"> <div class="alert is-helpful">
For the sample app that this page describes, see the <live-example></live-example>. Para ver la aplicación de ejemplo que describe esta página, ir a <live-example></live-example>.
</div> </div>
## Accessibility attributes ## Atributos de accesibilidad
Building accessible web experience often involves setting [ARIA attributes](https://developers.google.com/web/fundamentals/accessibility/semantics-aria) Crear una web accesible a menudo implica establecer los [atributos ARIA](https://developers.google.com/web/fundamentals/accessibility/semantics-aria)
to provide semantic meaning where it might otherwise be missing. para proporcionar la semántica que, de otro modo, podría no estar presente.
Use [attribute binding](guide/attribute-binding) template syntax to control the values of accessibility-related attributes. Usa la plantilla de sintaxis del [enlace de atributos](attribute binding) (guide/attribute-binding) para controlar los valores de los atributos relacionados con la accesibilidad.
When binding to ARIA attributes in Angular, you must use the `attr.` prefix, as the ARIA Para enlazar los atributos ARIA en Angular, debes usar el prefijo `attr.`, ya que la especificación ARIA
specification depends specifically on HTML attributes rather than properties of DOM elements. depende de los atributos HTML y no de las propiedades de los elementos del DOM.
```html ```html
<!-- Use attr. when binding to an ARIA attribute --> <!-- Use attr. when binding to an ARIA attribute -->
<button [attr.aria-label]="myActionLabel">...</button> <button [attr.aria-label]="myActionLabel">...</button>
``` ```
Note that this syntax is only necessary for attribute _bindings_. Observa que esta sintaxis solo es necesaria para los _enlaces_ de atributos.
Static ARIA attributes require no extra syntax. Los atributos ARIA estáticos no requieren de ninguna sintaxis adicional.
```html ```html
<!-- Static ARIA attributes require no extra syntax --> <!-- Static ARIA attributes require no extra syntax -->
<button aria-label="Save document">...</button> <button aria-label="Save document">...</button>
``` ```
NOTE: NOTA:
<div class="alert is-helpful"> <div class="alert is-helpful">
By convention, HTML attributes use lowercase names (`tabindex`), while properties use camelCase names (`tabIndex`). Por convenio, los atributos HTML se escriben en minúscula (`tabindex`), mientras que para las propiedades se usa *camelCase* (`tabIndex`).
See the [Binding syntax](guide/binding-syntax#html-attribute-vs-dom-property) guide for more background on the difference between attributes and properties. Consulta la guía [Sintaxis del enlace](guide/binding-syntax#html-attribute-vs-dom-property) para saber más sobre las diferencias entre atributos y propiedades.
</div> </div>
## Angular UI components ## Componentes del interfaz de usuario de Angular
The [Angular Material](https://material.angular.io/) library, which is maintained by the Angular team, is a suite of reusable UI components that aims to be fully accessible. La librería [Angular Material](https://material.angular.io/), que es mantenida por el equipo Angular, es un conjunto de componentes reutilizables para la interfaz de usuario que pretende ser totalmente accesible.
The [Component Development Kit (CDK)](https://material.angular.io/cdk/categories) includes the `a11y` package that provides tools to support various areas of accessibility. El [Kit de Desarrollo de Componentes (CDK)](https://material.angular.io/cdk/categories) (Component Development Kit) incluye el paquete `a11y` que proporciona herramientas para dar soporte a distintos aspectos de la accesibilidad.
For example: Por ejemplo:
* `LiveAnnouncer` is used to announce messages for screen-reader users using an `aria-live` region. See the W3C documentation for more information on [aria-live regions](https://www.w3.org/WAI/PF/aria-1.1/states_and_properties#aria-live). * `LiveAnnouncer` se utiliza para comunicar mensajes a los usuarios de lectores de pantalla que usan la region `aria-live`. Se puede consultar la documentación de la W3C para obtener más información sobre [regiones aria-live](https://www.w3.org/WAI/PF/aria-1.1/states_and_properties#aria-live).
* The `cdkTrapFocus` directive traps Tab-key focus within an element. Use it to create accessible experience for components like modal dialogs, where focus must be constrained. * La directiva `cdkTrapFocus` limita el foco de la tecla de tabulación para que se quede dentro de un elemento. Úsala para crear una experiencia accesible en componentes como las ventanas modales, donde el foco debe estar limitado.
For full details of these and other tools, see the [Angular CDK accessibility overview](https://material.angular.io/cdk/a11y/overview). Para obtener más detalles sobre esta y otras herramientas, consulta el [resumen de accesibilidad del Angular CDK](https://material.angular.io/cdk/a11y/overview).
### Augmenting native elements ### Aumento de elementos nativos
Native HTML elements capture a number of standard interaction patterns that are important to accessibility. Los elementos HTML nativos capturan una serie de patrones de interacción estándar que son importantes para la accesibilidad.
When authoring Angular components, you should re-use these native elements directly when possible, rather than re-implementing well-supported behaviors. Al crear componentes de Angular, deberías reutilizar estos elementos nativos directamente cuando sea posible, en lugar de volver a implementar comportamientos bien soportados.
For example, instead of creating a custom element for a new variety of button, you can create a component that uses an attribute selector with a native `<button>` element. Por ejemplo, en lugar de crear un elemento personalizado para un nuevo tipo de botón, puedes crear un componente que use un selector de atributos con un elemento nativo `<button>`.
This most commonly applies to `<button>` and `<a>`, but can be used with many other types of element. Esto se aplica sobre todo a `<button>` y `<a>`, pero se puede usar con muchos otros tipos de elementos.
You can see examples of this pattern in Angular Material: [`MatButton`](https://github.com/angular/components/blob/master/src/material/button/button.ts#L66-L68), [`MatTabNav`](https://github.com/angular/components/blob/master/src/material/tabs/tab-nav-bar/tab-nav-bar.ts#L67), [`MatTable`](https://github.com/angular/components/blob/master/src/material/table/table.ts#L17). You can see examples of this pattern in Angular Material: [`MatButton`](https://github.com/angular/components/blob/master/src/material/button/button.ts#L66-L68), [`MatTabNav`](https://github.com/angular/components/blob/master/src/material/tabs/tab-nav-bar/tab-nav-bar.ts#L67), [`MatTable`](https://github.com/angular/components/blob/master/src/material/table/table.ts#L17).
### Using containers for native elements ### Uso de contenedores para elementos nativos
Sometimes using the appropriate native element requires a container element. A veces, para usar el elemento nativo apropiado hace falta un contenedor.
For example, the native `<input>` element cannot have children, so any custom text entry components need Por ejemplo, el elemento nativo `<input>` no puede tener hijos, por lo que cualquier componente de entrada de texto personalizado necesita envolver un `<input>` con elementos adicionales.
to wrap an `<input>` with additional elements.
While you might just include the `<input>` in your custom component's template,
this makes it impossible for users of the component to set arbitrary properties and attributes to the input element.
Instead, you can create a container component that uses content projection to include the native control in the
component's API.
You can see [`MatFormField`](https://material.angular.io/components/form-field/overview) as an example of this pattern. Si bien puedes incluir el `<input>` en la plantilla de tu componente personalizado,
esto hace que sea imposible para los usuarios de dicho componente establecer propiedades y atributos arbitrarios para el elemento de entrada.
En su lugar, puedes crear un componente contenedor que utilice la proyección de contenido para incluir el control nativo en el
API del componente.
## Case study: Building a custom progress bar Puedes consultar [`MatFormField`](https://material.angular.io/components/form-field/overview) para ver un ejemplo de este patrón.
The following example shows how to make a simple progress bar accessible by using host binding to control accessibility-related attributes. ## Caso práctico: creación de una barra de progreso personalizada
* The component defines an accessibility-enabled element with both the standard HTML attribute `role`, and ARIA attributes. The ARIA attribute `aria-valuenow` is bound to the user's input. El siguiente ejemplo muestra cómo hacer que una barra de progreso simple sea accesible utilizando el *host binding* para controlar los atributos relacionados con la accesibilidad.
* El componente define un elemento habilitado para accesibilidad con el atributo HTML estándar `role` y los atributos ARIA. El atributo ARIA `aria-valuenow` está vinculado a la entrada del usuario.
<code-example path="accessibility/src/app/progress-bar.component.ts" header="src/app/progress-bar.component.ts" region="progressbar-component"></code-example> <code-example path="accessibility/src/app/progress-bar.component.ts" header="src/app/progress-bar.component.ts" region="progressbar-component"></code-example>
* In the template, the `aria-label` attribute ensures that the control is accessible to screen readers. * En la plantilla, el atributo `aria-label` asegura que el control sea accesible para los lectores de pantalla.
<code-example path="accessibility/src/app/app.component.html" header="src/app/app.component.html" region="template"></code-example> <code-example path="accessibility/src/app/app.component.html" header="src/app/app.component.html" region="template"></code-example>
## Routing and focus management ## Enrutamiento y gestión del foco
Tracking and controlling [focus](https://developers.google.com/web/fundamentals/accessibility/focus/) in a UI is an important consideration in designing for accessibility. El seguimiento y el control del [foco](https://developers.google.com/web/fundamentals/accessibility/focus/) en una interfaz de usuario son aspectos muy importantes en el diseño si queremos tener en cuenta la accesibilidad.
When using Angular routing, you should decide where page focus goes upon navigation. Al usar el enrutamiento de Angular, debes decidir dónde va el foco de la página al navegar.
To avoid relying solely on visual cues, you need to make sure your routing code updates focus after page navigation. Para evitar depender únicamente de señales visuales, te debes asegurar de que el código de enrutamiento actualiza el foco después de la navegación de la página.
Use the `NavigationEnd` event from the `Router` service to know when to update Usa el evento `NavigationEnd` del servicio` Router` para saber cuándo actualizar el foco.
focus.
El siguiente ejemplo muestra cómo encontrar y poner el foco en el contenido principal de la cabecera (el elemento `#main-content-header`) dentro del DOM después de la navegación.
The following example shows how to find and focus the main content header in the DOM after navigation. The following example shows how to find and focus the main content header in the DOM after navigation.
@ -119,13 +120,12 @@ router.events.pipe(filter(e => e instanceof NavigationEnd)).subscribe(() => {
}); });
``` ```
In a real application, the element that receives focus will depend on your specific En una aplicación real, el elemento que recibe el foco dependerá de la estructura específica y del diseño que tenga tu aplicación.
application structure and layout. El elemento enfocado debe colocar a los usuarios en una posición en la que pasen inmediatamente al contenido principal que acaba de ser visualizado.
The focused element should put users in a position to immediately move into the main content that has just been routed into view. Debe evitar situaciones en las que el foco vuelva al elemento `body` después de un cambio de ruta.
You should avoid situations where focus returns to the `body` element after a route change.
## Additional resources ## Recursos adicionales
* [Accessibility - Google Web Fundamentals](https://developers.google.com/web/fundamentals/accessibility) * [Accessibility - Google Web Fundamentals](https://developers.google.com/web/fundamentals/accessibility)
@ -145,13 +145,13 @@ You should avoid situations where focus returns to the `body` element after a ro
* [Codelyzer](http://codelyzer.com/rules/) provides linting rules that can help you make sure your code meets accessibility standards. * [Codelyzer](http://codelyzer.com/rules/) provides linting rules that can help you make sure your code meets accessibility standards.
Books Libros
* "A Web for Everyone: Designing Accessible User Experiences", Sarah Horton and Whitney Quesenbery * "A Web for Everyone: Designing Accessible User Experiences", Sarah Horton and Whitney Quesenbery
* "Inclusive Design Patterns", Heydon Pickering * "Inclusive Design Patterns", Heydon Pickering
## More on accessibility ## Más sobre accesibilidad
You may also be interested in the following: Podrías estar interesado en lo siguiente:
* [Audit your Angular app's accessibility with codelyzer](https://web.dev/accessible-angular-with-codelyzer/). * [Audit your Angular app's accessibility with codelyzer](https://web.dev/accessible-angular-with-codelyzer/).

View File

@ -341,7 +341,7 @@ The following are some of the key AngularJS built-in directives and their equiva
In Angular, the template no longer specifies its associated controller. In Angular, the template no longer specifies its associated controller.
Rather, the component specifies its associated template as part of the component class decorator. Rather, the component specifies its associated template as part of the component class decorator.
For more information, see [Architecture Overview](guide/architecture#components). For more information, see [Architecture Overview](guide/architecture#componentes).
</td> </td>
@ -1035,7 +1035,7 @@ The Angular code is shown using TypeScript.
This is a nonissue in Angular because ES 2015 modules This is a nonissue in Angular because ES 2015 modules
handle the namespacing for you. handle the namespacing for you.
For more information on modules, see the [Modules](guide/architecture#modules) section of the For more information on modules, see the [Modules](guide/architecture#módulos) section of the
[Architecture Overview](guide/architecture). [Architecture Overview](guide/architecture).
</td> </td>
@ -1112,7 +1112,7 @@ The Angular code is shown using TypeScript.
This is how you associate a template with logic, which is defined in the component class. This is how you associate a template with logic, which is defined in the component class.
For more information, see the [Components](guide/architecture#components) For more information, see the [Components](guide/architecture#componentes)
section of the [Architecture Overview](guide/architecture) page. section of the [Architecture Overview](guide/architecture) page.
</td> </td>
@ -1144,7 +1144,7 @@ The Angular code is shown using TypeScript.
In Angular, you create a component class to contain the data model and control methods. Use the TypeScript <code>export</code> keyword to export the class so that the functionality can be imported into NgModules. In Angular, you create a component class to contain the data model and control methods. Use the TypeScript <code>export</code> keyword to export the class so that the functionality can be imported into NgModules.
For more information, see the [Components](guide/architecture#components) For more information, see the [Components](guide/architecture#componentes)
section of the [Architecture Overview](guide/architecture) page. section of the [Architecture Overview](guide/architecture) page.
</td> </td>

View File

@ -0,0 +1,665 @@
# Ahead-of-time (AOT) compilation
An Angular application consists mainly of components and their HTML templates. Because the components and templates provided by Angular cannot be understood by the browser directly, Angular applications require a compilation process before they can run in a browser.
The Angular [ahead-of-time (AOT) compiler](guide/glossary#aot) converts your Angular HTML and TypeScript code into efficient JavaScript code during the build phase _before_ the browser downloads and runs that code. Compiling your application during the build process provides a faster rendering in the browser.
This guide explains how to specify metadata and apply available compiler options to compile your applications efficiently using the AOT compiler.
<div class="alert is-helpful">
<a href="https://www.youtube.com/watch?v=anphffaCZrQ">Watch Alex Rickabaugh explain the Angular compiler</a> at AngularConnect 2019.
</div>
{@a why-aot}
Here are some reasons you might want to use AOT.
* *Faster rendering*
With AOT, the browser downloads a pre-compiled version of the application.
The browser loads executable code so it can render the application immediately, without waiting to compile the app first.
* *Fewer asynchronous requests*
The compiler _inlines_ external HTML templates and CSS style sheets within the application JavaScript,
eliminating separate ajax requests for those source files.
* *Smaller Angular framework download size*
There's no need to download the Angular compiler if the app is already compiled.
The compiler is roughly half of Angular itself, so omitting it dramatically reduces the application payload.
* *Detect template errors earlier*
The AOT compiler detects and reports template binding errors during the build step
before users can see them.
* *Better security*
AOT compiles HTML templates and components into JavaScript files long before they are served to the client.
With no templates to read and no risky client-side HTML or JavaScript evaluation,
there are fewer opportunities for injection attacks.
{@a overview}
## Choosing a compiler
Angular offers two ways to compile your application:
* **_Just-in-Time_ (JIT)**, which compiles your app in the browser at runtime. This was the default until Angular 8.
* **_Ahead-of-Time_ (AOT)**, which compiles your app and libraries at build time. This is the default since Angular 9.
When you run the [`ng build`](cli/build) (build only) or [`ng serve`](cli/serve) (build and serve locally) CLI commands, the type of compilation (JIT or AOT) depends on the value of the `aot` property in your build configuration specified in `angular.json`. By default, `aot` is set to `true` for new CLI apps.
See the [CLI command reference](cli) and [Building and serving Angular apps](guide/build) for more information.
## How AOT works
The Angular AOT compiler extracts **metadata** to interpret the parts of the application that Angular is supposed to manage.
You can specify the metadata explicitly in **decorators** such as `@Component()` and `@Input()`, or implicitly in the constructor declarations of the decorated classes.
The metadata tells Angular how to construct instances of your application classes and interact with them at runtime.
In the following example, the `@Component()` metadata object and the class constructor tell Angular how to create and display an instance of `TypicalComponent`.
```typescript
@Component({
selector: 'app-typical',
template: '<div>A typical component for {{data.name}}</div>'
)}
export class TypicalComponent {
@Input() data: TypicalData;
constructor(private someService: SomeService) { ... }
}
```
The Angular compiler extracts the metadata _once_ and generates a _factory_ for `TypicalComponent`.
When it needs to create a `TypicalComponent` instance, Angular calls the factory, which produces a new visual element, bound to a new instance of the component class with its injected dependency.
### Compilation phases
There are three phases of AOT compilation.
* Phase 1 is *code analysis*.
In this phase, the TypeScript compiler and *AOT collector* create a representation of the source. The collector does not attempt to interpret the metadata it collects. It represents the metadata as best it can and records errors when it detects a metadata syntax violation.
* Phase 2 is *code generation*.
In this phase, the compiler's `StaticReflector` interprets the metadata collected in phase 1, performs additional validation of the metadata, and throws an error if it detects a metadata restriction violation.
* Phase 3 is *template type checking*.
In this optional phase, the Angular *template compiler* uses the TypeScript compiler to validate the binding expressions in templates. You can enable this phase explicitly by setting the `fullTemplateTypeCheck` configuration option; see [Angular compiler options](guide/angular-compiler-options).
### Metadata restrictions
You write metadata in a _subset_ of TypeScript that must conform to the following general constraints:
* Limit [expression syntax](#expression-syntax) to the supported subset of JavaScript.
* Only reference exported symbols after [code folding](#code-folding).
* Only call [functions supported](#supported-functions) by the compiler.
* Decorated and data-bound class members must be public.
For additional guidelines and instructions on preparing an application for AOT compilation, see [Angular: Writing AOT-friendly applications](https://medium.com/sparkles-blog/angular-writing-aot-friendly-applications-7b64c8afbe3f).
<div class="alert is-helpful">
Errors in AOT compilation commonly occur because of metadata that does not conform to the compiler's requirements (as described more fully below).
For help in understanding and resolving these problems, see [AOT Metadata Errors](guide/aot-metadata-errors).
</div>
### Configuring AOT compilation
You can provide options in the [TypeScript configuration file](guide/typescript-configuration) that controls the compilation process. See [Angular compiler options](guide/angular-compiler-options) for a complete list of available options.
## Phase 1: Code analysis
The TypeScript compiler does some of the analytic work of the first phase. It emits the `.d.ts` _type definition files_ with type information that the AOT compiler needs to generate application code.
At the same time, the AOT **collector** analyzes the metadata recorded in the Angular decorators and outputs metadata information in **`.metadata.json`** files, one per `.d.ts` file.
You can think of `.metadata.json` as a diagram of the overall structure of a decorator's metadata, represented as an [abstract syntax tree (AST)](https://en.wikipedia.org/wiki/Abstract_syntax_tree).
<div class="alert is-helpful">
Angular's [schema.ts](https://github.com/angular/angular/blob/master/packages/compiler-cli/src/metadata/schema.ts)
describes the JSON format as a collection of TypeScript interfaces.
</div>
{@a expression-syntax}
### Expression syntax limitations
The AOT collector only understands a subset of JavaScript.
Define metadata objects with the following limited syntax:
<style>
td, th {vertical-align: top}
</style>
<table>
<tr>
<th>Syntax</th>
<th>Example</th>
</tr>
<tr>
<td>Literal object </td>
<td><code>{cherry: true, apple: true, mincemeat: false}</code></td>
</tr>
<tr>
<td>Literal array </td>
<td><code>['cherries', 'flour', 'sugar']</code></td>
</tr>
<tr>
<td>Spread in literal array</td>
<td><code>['apples', 'flour', ...the_rest]</code></td>
</tr>
<tr>
<td>Calls</td>
<td><code>bake(ingredients)</code></td>
</tr>
<tr>
<td>New</td>
<td><code>new Oven()</code></td>
</tr>
<tr>
<td>Property access</td>
<td><code>pie.slice</code></td>
</tr>
<tr>
<td>Array index</td>
<td><code>ingredients[0]</code></td>
</tr>
<tr>
<td>Identity reference</td>
<td><code>Component</code></td>
</tr>
<tr>
<td>A template string</td>
<td><code>`pie is ${multiplier} times better than cake`</code></td>
<tr>
<td>Literal string</td>
<td><code>pi</code></td>
</tr>
<tr>
<td>Literal number</td>
<td><code>3.14153265</code></td>
</tr>
<tr>
<td>Literal boolean</td>
<td><code>true</code></td>
</tr>
<tr>
<td>Literal null</td>
<td><code>null</code></td>
</tr>
<tr>
<td>Supported prefix operator </td>
<td><code>!cake</code></td>
</tr>
<tr>
<td>Supported binary operator </td>
<td><code>a+b</code></td>
</tr>
<tr>
<td>Conditional operator</td>
<td><code>a ? b : c</code></td>
</tr>
<tr>
<td>Parentheses</td>
<td><code>(a+b)</code></td>
</tr>
</table>
If an expression uses unsupported syntax, the collector writes an error node to the `.metadata.json` file.
The compiler later reports the error if it needs that piece of metadata to generate the application code.
<div class="alert is-helpful">
If you want `ngc` to report syntax errors immediately rather than produce a `.metadata.json` file with errors, set the `strictMetadataEmit` option in the TypeScript configuration file.
```
"angularCompilerOptions": {
...
"strictMetadataEmit" : true
}
```
Angular libraries have this option to ensure that all Angular `.metadata.json` files are clean and it is a best practice to do the same when building your own libraries.
</div>
{@a function-expression}
{@a arrow-functions}
### No arrow functions
The AOT compiler does not support [function expressions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function)
and [arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions), also called _lambda_ functions.
Consider the following component decorator:
```typescript
@Component({
...
providers: [{provide: server, useFactory: () => new Server()}]
})
```
The AOT collector does not support the arrow function, `() => new Server()`, in a metadata expression.
It generates an error node in place of the function.
When the compiler later interprets this node, it reports an error that invites you to turn the arrow function into an _exported function_.
You can fix the error by converting to this:
```typescript
export function serverFactory() {
return new Server();
}
@Component({
...
providers: [{provide: server, useFactory: serverFactory}]
})
```
In version 5 and later, the compiler automatically performs this rewriting while emitting the `.js` file.
{@a exported-symbols}
{@a code-folding}
### Code folding
The compiler can only resolve references to **_exported_** symbols.
The collector, however, can evaluate an expression during collection and record the result in the `.metadata.json`, rather than the original expression.
This allows you to make limited use of non-exported symbols within expressions.
For example, the collector can evaluate the expression `1 + 2 + 3 + 4` and replace it with the result, `10`.
This process is called _folding_. An expression that can be reduced in this manner is _foldable_.
{@a var-declaration}
The collector can evaluate references to module-local `const` declarations and initialized `var` and `let` declarations, effectively removing them from the `.metadata.json` file.
Consider the following component definition:
```typescript
const template = '<div>{{hero.name}}</div>';
@Component({
selector: 'app-hero',
template: template
})
export class HeroComponent {
@Input() hero: Hero;
}
```
The compiler could not refer to the `template` constant because it isn't exported.
The collector, however, can fold the `template` constant into the metadata definition by in-lining its contents.
The effect is the same as if you had written:
```typescript
@Component({
selector: 'app-hero',
template: '<div>{{hero.name}}</div>'
})
export class HeroComponent {
@Input() hero: Hero;
}
```
There is no longer a reference to `template` and, therefore, nothing to trouble the compiler when it later interprets the _collector's_ output in `.metadata.json`.
You can take this example a step further by including the `template` constant in another expression:
```typescript
const template = '<div>{{hero.name}}</div>';
@Component({
selector: 'app-hero',
template: template + '<div>{{hero.title}}</div>'
})
export class HeroComponent {
@Input() hero: Hero;
}
```
The collector reduces this expression to its equivalent _folded_ string:
```
'<div>{{hero.name}}</div><div>{{hero.title}}</div>'
```
#### Foldable syntax
The following table describes which expressions the collector can and cannot fold:
<style>
td, th {vertical-align: top}
</style>
<table>
<tr>
<th>Syntax</th>
<th>Foldable</th>
</tr>
<tr>
<td>Literal object </td>
<td>yes</td>
</tr>
<tr>
<td>Literal array </td>
<td>yes</td>
</tr>
<tr>
<td>Spread in literal array</td>
<td>no</td>
</tr>
<tr>
<td>Calls</td>
<td>no</td>
</tr>
<tr>
<td>New</td>
<td>no</td>
</tr>
<tr>
<td>Property access</td>
<td>yes, if target is foldable</td>
</tr>
<tr>
<td>Array index</td>
<td> yes, if target and index are foldable</td>
</tr>
<tr>
<td>Identity reference</td>
<td>yes, if it is a reference to a local</td>
</tr>
<tr>
<td>A template with no substitutions</td>
<td>yes</td>
</tr>
<tr>
<td>A template with substitutions</td>
<td>yes, if the substitutions are foldable</td>
</tr>
<tr>
<td>Literal string</td>
<td>yes</td>
</tr>
<tr>
<td>Literal number</td>
<td>yes</td>
</tr>
<tr>
<td>Literal boolean</td>
<td>yes</td>
</tr>
<tr>
<td>Literal null</td>
<td>yes</td>
</tr>
<tr>
<td>Supported prefix operator </td>
<td>yes, if operand is foldable</td>
</tr>
<tr>
<td>Supported binary operator </td>
<td>yes, if both left and right are foldable</td>
</tr>
<tr>
<td>Conditional operator</td>
<td>yes, if condition is foldable </td>
</tr>
<tr>
<td>Parentheses</td>
<td>yes, if the expression is foldable</td>
</tr>
</table>
If an expression is not foldable, the collector writes it to `.metadata.json` as an [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree) for the compiler to resolve.
## Phase 2: code generation
The collector makes no attempt to understand the metadata that it collects and outputs to `.metadata.json`.
It represents the metadata as best it can and records errors when it detects a metadata syntax violation.
It's the compiler's job to interpret the `.metadata.json` in the code generation phase.
The compiler understands all syntax forms that the collector supports, but it may reject _syntactically_ correct metadata if the _semantics_ violate compiler rules.
### Public symbols
The compiler can only reference _exported symbols_.
* Decorated component class members must be public. You cannot make an `@Input()` property private or protected.
* Data bound properties must also be public.
```typescript
// BAD CODE - title is private
@Component({
selector: 'app-root',
template: '<h1>{{title}}</h1>'
})
export class AppComponent {
private title = 'My App'; // Bad
}
```
{@a supported-functions}
### Supported classes and functions
The collector can represent a function call or object creation with `new` as long as the syntax is valid.
The compiler, however, can later refuse to generate a call to a _particular_ function or creation of a _particular_ object.
The compiler can only create instances of certain classes, supports only core decorators, and only supports calls to macros (functions or static methods) that return expressions.
* New instances
The compiler only allows metadata that create instances of the class `InjectionToken` from `@angular/core`.
* Supported decorators
The compiler only supports metadata for the [Angular decorators in the `@angular/core` module](api/core#decorators).
* Function calls
Factory functions must be exported, named functions.
The AOT compiler does not support lambda expressions ("arrow functions") for factory functions.
{@a function-calls}
### Functions and static method calls
The collector accepts any function or static method that contains a single `return` statement.
The compiler, however, only supports macros in the form of functions or static methods that return an *expression*.
For example, consider the following function:
```typescript
export function wrapInArray<T>(value: T): T[] {
return [value];
}
```
You can call the `wrapInArray` in a metadata definition because it returns the value of an expression that conforms to the compiler's restrictive JavaScript subset.
You might use `wrapInArray()` like this:
```typescript
@NgModule({
declarations: wrapInArray(TypicalComponent)
})
export class TypicalModule {}
```
The compiler treats this usage as if you had written:
```typescript
@NgModule({
declarations: [TypicalComponent]
})
export class TypicalModule {}
```
The Angular [`RouterModule`](api/router/RouterModule) exports two macro static methods, `forRoot` and `forChild`, to help declare root and child routes.
Review the [source code](https://github.com/angular/angular/blob/master/packages/router/src/router_module.ts#L139 "RouterModule.forRoot source code")
for these methods to see how macros can simplify configuration of complex [NgModules](guide/ngmodules).
{@a metadata-rewriting}
### Metadata rewriting
The compiler treats object literals containing the fields `useClass`, `useValue`, `useFactory`, and `data` specially, converting the expression initializing one of these fields into an exported variable that replaces the expression.
This process of rewriting these expressions removes all the restrictions on what can be in them because
the compiler doesn't need to know the expression's value&mdash;it just needs to be able to generate a reference to the value.
You might write something like:
```typescript
class TypicalServer {
}
@NgModule({
providers: [{provide: SERVER, useFactory: () => TypicalServer}]
})
export class TypicalModule {}
```
Without rewriting, this would be invalid because lambdas are not supported and `TypicalServer` is not exported.
To allow this, the compiler automatically rewrites this to something like:
```typescript
class TypicalServer {
}
export const ɵ0 = () => new TypicalServer();
@NgModule({
providers: [{provide: SERVER, useFactory: ɵ0}]
})
export class TypicalModule {}
```
This allows the compiler to generate a reference to `ɵ0` in the factory without having to know what the value of `ɵ0` contains.
The compiler does the rewriting during the emit of the `.js` file.
It does not, however, rewrite the `.d.ts` file, so TypeScript doesn't recognize it as being an export. and it does not interfere with the ES module's exported API.
{@a binding-expression-validation}
## Phase 3: Template type checking
One of the Angular compiler's most helpful features is the ability to type-check expressions within templates, and catch any errors before they cause crashes at runtime.
In the template type-checking phase, the Angular template compiler uses the TypeScript compiler to validate the binding expressions in templates.
Enable this phase explicitly by adding the compiler option `"fullTemplateTypeCheck"` in the `"angularCompilerOptions"` of the project's TypeScript configuration file
(see [Angular Compiler Options](guide/angular-compiler-options)).
<div class="alert is-helpful">
In [Angular Ivy](guide/ivy), the template type checker has been completely rewritten to be more capable as well as stricter, meaning it can catch a variety of new errors that the previous type checker would not detect.
As a result, templates that previously compiled under View Engine can fail type checking under Ivy. This can happen because Ivy's stricter checking catches genuine errors, or because application code is not typed correctly, or because the application uses libraries in which typings are inaccurate or not specific enough.
This stricter type checking is not enabled by default in version 9, but can be enabled by setting the `strictTemplates` configuration option.
We do expect to make strict type checking the default in the future.
For more information about type-checking options, and about improvements to template type checking in version 9 and above, see [Template type checking](guide/template-typecheck).
</div>
Template validation produces error messages when a type error is detected in a template binding
expression, similar to how type errors are reported by the TypeScript compiler against code in a `.ts`
file.
For example, consider the following component:
```typescript
@Component({
selector: 'my-component',
template: '{{person.addresss.street}}'
})
class MyComponent {
person?: Person;
}
```
This produces the following error:
```
my.component.ts.MyComponent.html(1,1): : Property 'addresss' does not exist on type 'Person'. Did you mean 'address'?
```
The file name reported in the error message, `my.component.ts.MyComponent.html`, is a synthetic file
generated by the template compiler that holds contents of the `MyComponent` class template.
The compiler never writes this file to disk.
The line and column numbers are relative to the template string in the `@Component` annotation of the class, `MyComponent` in this case.
If a component uses `templateUrl` instead of `template`, the errors are reported in the HTML file referenced by the `templateUrl` instead of a synthetic file.
The error location is the beginning of the text node that contains the interpolation expression with the error.
If the error is in an attribute binding such as `[value]="person.address.street"`, the error
location is the location of the attribute that contains the error.
The validation uses the TypeScript type checker and the options supplied to the TypeScript compiler to control how detailed the type validation is.
For example, if the `strictTypeChecks` is specified, the error
```my.component.ts.MyComponent.html(1,1): : Object is possibly 'undefined'```
is reported as well as the above error message.
### Type narrowing
The expression used in an `ngIf` directive is used to narrow type unions in the Angular
template compiler, the same way the `if` expression does in TypeScript.
For example, to avoid `Object is possibly 'undefined'` error in the template above, modify it to only emit the interpolation if the value of `person` is initialized as shown below:
```typescript
@Component({
selector: 'my-component',
template: '<span *ngIf="person"> {{person.addresss.street}} </span>'
})
class MyComponent {
person?: Person;
}
```
Using `*ngIf` allows the TypeScript compiler to infer that the `person` used in the binding expression will never be `undefined`.
For more information about input type narrowing, see [Input setter coercion](guide/template-typecheck#input-setter-coercion) and [Improving template type checking for custom directives](guide/structural-directives#directive-type-checks).
### Non-null type assertion operator
Use the [non-null type assertion operator](guide/template-expression-operators#non-null-assertion-operator) to suppress the `Object is possibly 'undefined'` error when it is inconvenient to use `*ngIf` or when some constraint in the component ensures that the expression is always non-null when the binding expression is interpolated.
In the following example, the `person` and `address` properties are always set together, implying that `address` is always non-null if `person` is non-null.
There is no convenient way to describe this constraint to TypeScript and the template compiler, but the error is suppressed in the example by using `address!.street`.
```typescript
@Component({
selector: 'my-component',
template: '<span *ngIf="person"> {{person.name}} lives on {{address!.street}} </span>'
})
class MyComponent {
person?: Person;
address?: Address;
setData(person: Person, address: Address) {
this.person = person;
this.address = address;
}
}
```
The non-null assertion operator should be used sparingly as refactoring of the component might break this constraint.
In this example it is recommended to include the checking of `address` in the `*ngIf` as shown below:
```typescript
@Component({
selector: 'my-component',
template: '<span *ngIf="person && address"> {{person.name}} lives on {{address.street}} </span>'
})
class MyComponent {
person?: Person;
address?: Address;
setData(person: Person, address: Address) {
this.person = person;
this.address = address;
}
}
```

View File

@ -1,62 +1,59 @@
# Ahead-of-time (AOT) compilation # Compilación anticipada (AOT)
An Angular application consists mainly of components and their HTML templates. Because the components and templates provided by Angular cannot be understood by the browser directly, Angular applications require a compilation process before they can run in a browser. Una aplicación Angular consta principalmente de componentes y sus plantillas HTML. Los componentes y plantillas proporcionados por Angular no pueden ser entendidos por el navegador directamente, las aplicaciones en Angular requieren un proceso de compilación antes de que puedan correr en un navegador.
The Angular [ahead-of-time (AOT) compiler](guide/glossary#aot) converts your Angular HTML and TypeScript code into efficient JavaScript code during the build phase _before_ the browser downloads and runs that code. Compiling your application during the build process provides a faster rendering in the browser. La [compilación anticipada de Angular (AOT)](guide/glossary#aot) convierte plantillas y código de TypeScript en eficiente código JavaScript durante la fase de construcción _antes_ de que el navegador descargue y corra el código. Compilando tu aplicación durante el proceso de construcción se proporciona una renderización más rápida en el navegador.
This guide explains how to specify metadata and apply available compiler options to compile your applications efficiently using the AOT compiler. Esta guía explica como especificar metadatos y aplicar las opciones del compilador disponibles para compilar aplicaciones eficientemente usando la compilación anticipada (AOT).
<div class="alert is-helpful"> <div class="alert is-helpful">
<a href="https://www.youtube.com/watch?v=anphffaCZrQ">Watch Alex Rickabaugh explain the Angular compiler</a> at AngularConnect 2019. <a href="https://www.youtube.com/watch?v=anphffaCZrQ">Mira a Alex Rickabaugh explicando el compilador de Angular en AngularConnect 2019.
</div> </div>
{@a why-aot} {@a why-aot}
Here are some reasons you might want to use AOT. Aquí algunas razones por las qué podrías querer usar AOT.
* *Faster rendering* * *Renderizado más rápido*
With AOT, the browser downloads a pre-compiled version of the application. Con AOT, el navegador descarga una versión pre compilada de una aplicación.
The browser loads executable code so it can render the application immediately, without waiting to compile the app first. El navegador carga el código ejecutable para que pueda renderizar la aplicación inmediatamente, sin esperar a compilar la aplicación primero.
* *Fewer asynchronous requests* * *Menos solicitudes asincrónicas*
The compiler _inlines_ external HTML templates and CSS style sheets within the application JavaScript, El compilador _inserta_ plantillas HTML y hojas de estilo CSS externas dentro de la aplicación JavaScript, eliminando solicitudes ajax separadas para esos archivos fuente.
eliminating separate ajax requests for those source files.
* *Smaller Angular framework download size* * *Angular pesa menos*
There's no need to download the Angular compiler if the app is already compiled. No existe necesidad de incluir el compilador de Angular si la aplicación ya esta compilada.
The compiler is roughly half of Angular itself, so omitting it dramatically reduces the application payload. El compilador es aproximadamente la mitad de Angular en si mismo, así que omitíendolo se reduce drásticamente el peso de la aplicación.
* *Detect template errors earlier* * *Detecte errores en platillas antes*
The AOT compiler detects and reports template binding errors during the build step El compilador AOT detecta y reporta errores de enlace de datos en plantillas durante el paso de construcción antes que los usuarios puedan verlos.
before users can see them.
* *Better security* * *Mejor seguridad*
AOT compiles HTML templates and components into JavaScript files long before they are served to the client. AOT compila las plantillas HTML y componentes en archivos JavaScript mucho antes de que se sirvan a el cliente.
With no templates to read and no risky client-side HTML or JavaScript evaluation, Sin plantillas para leer y sin evaluaciones de JavaScript o HTML del lado del cliente riesgosas, existen pocas oportunidades para ataques de inyección.
there are fewer opportunities for injection attacks.
{@a overview} {@a overview}
## Choosing a compiler ## Eligiendo un compilador.
Angular offers two ways to compile your application: Angular ofrece dos formas para compilar tu aplicación:
* **_Just-in-Time_ (JIT)**, which compiles your app in the browser at runtime. This was the default until Angular 8. * **_Just-in-Time_ (JIT)**, cuando compila tu aplicación en el navegador en tiempo de ejecución. Este fué el modo de compilación por defecto hasta Angular 8.
* **_Ahead-of-Time_ (AOT)**, which compiles your app and libraries at build time. This is the default since Angular 9. * **_Ahead-of-Time_ (AOT)**, cuando compila tu aplicación y librerías en el tiempo de construcción. Este es el modo de compilación por defecto desde Angular 9.
When you run the [`ng build`](cli/build) (build only) or [`ng serve`](cli/serve) (build and serve locally) CLI commands, the type of compilation (JIT or AOT) depends on the value of the `aot` property in your build configuration specified in `angular.json`. By default, `aot` is set to `true` for new CLI apps. Cuando ejecutas los comandos del CLI [`ng build`](cli/build) (solo construcción) o [`ng serve`](cli/serve) (construye y sirve localmente), el tipo de compilación (JIT o AOT) depende del valor de la propiedad `aot` en tu configuración de construcción especificada en el archivo `angular.json`. Por defecto, `aot` esta establecido en `true` para nuevas aplicaciones.
See the [CLI command reference](cli) and [Building and serving Angular apps](guide/build) for more information. Mira la [referencia de comandos del CLI](cli) y [Construyendo y sirviendo Angular apps](guide/build) para más información.
## How AOT works ## Como funciona AOT
The Angular AOT compiler extracts **metadata** to interpret the parts of the application that Angular is supposed to manage. El compilador de Angular AOT extrae **metadatos** para interpretar las partes de la aplicación que se supone que Angular maneja.
You can specify the metadata explicitly in **decorators** such as `@Component()` and `@Input()`, or implicitly in the constructor declarations of the decorated classes. Puedes especificar los metadatos explícitamente en **decoradores** como `@Component()` y `@Input()`, o implícitamente en las declaraciones del constructor de las clases decoradas.
The metadata tells Angular how to construct instances of your application classes and interact with them at runtime. Los metadatos le dicen a Angular como construir instancias de clases e interactuar con ellas en tiempo de ejecución.
In the following example, the `@Component()` metadata object and the class constructor tell Angular how to create and display an instance of `TypicalComponent`. En el siguiente ejemplo, los metadatos de `@Component()` y el constructor le dicen a Angular como crear y mostrar una instancia de `TypicalComponent`.
```typescript ```typescript
@Component({ @Component({
@ -69,63 +66,63 @@ export class TypicalComponent {
} }
``` ```
The Angular compiler extracts the metadata _once_ and generates a _factory_ for `TypicalComponent`. El compilador de Angular extrae los metadatos _una_ vez y genera una _fabrica_ para `TypicalComponent`.
When it needs to create a `TypicalComponent` instance, Angular calls the factory, which produces a new visual element, bound to a new instance of the component class with its injected dependency. Cuando este necesita crear una instancia de `TypicalComponent`, Angular llama a la fabrica, el cuál produce un nuevo elemento visual, vinculado a una nueva instancia la clase del componente con su dependencia inyectada.
### Compilation phases ### Fases de compilación
There are three phases of AOT compilation. Existen tres fases de compilación en AOT.
* Phase 1 is *code analysis*.
In this phase, the TypeScript compiler and *AOT collector* create a representation of the source. The collector does not attempt to interpret the metadata it collects. It represents the metadata as best it can and records errors when it detects a metadata syntax violation.
* Phase 2 is *code generation*. * Fase 1: *análisis de código*
In this phase, the compiler's `StaticReflector` interprets the metadata collected in phase 1, performs additional validation of the metadata, and throws an error if it detects a metadata restriction violation. En esta fase, el compilador de TypeScript y el *recolector AOT* crea una representación de la fuente. El recolector no intenta interpretar los metadatos recopilados. Estos representan los metadatos lo mejor que pueden y registra errores cuando este detecta un violación de sintaxis en los metadatos.
* Phase 3 is *template type checking*. * Fase 2: *generación de código*
In this optional phase, the Angular *template compiler* uses the TypeScript compiler to validate the binding expressions in templates. You can enable this phase explicitly by setting the `fullTemplateTypeCheck` configuration option; see [Angular compiler options](guide/angular-compiler-options). En esta fase, el `StaticReflector` del compilador interpreta los metadatos recolectados en la fase 1, realiza validaciones adicionales de los metadatos y lanza un error si este detecta una violación de la restricción de metadatos.
* Fase 3: *verificación de tipos en plantillas*
Esta fase es opcional, el *compilador de plantillas* de Angular usa el compilador de Typescript para validar las expresiones de enlaces de datos en las plantillas. Puedes habilitar esta fase explícitamente configurando la opción `fullTemplateTypeCheck`; revisa [Opciones del Compilador Angular](guide/angular-compiler-options).
### Metadata restrictions ### Restricciones de los metadatos
You write metadata in a _subset_ of TypeScript that must conform to the following general constraints: Escribe metadatos en un _subconjunto_ de TypeScript que debe cumplir las siguientes restricciones generales:
* Limit [expression syntax](#expression-syntax) to the supported subset of JavaScript. * Limita la [sintaxis de expresiones](#expression-syntax) al subconjunto soportado de JavaScript.
* Only reference exported symbols after [code folding](#code-folding). * Solo haz referencia a los símbolos exportados después del [plegado de código](#code-folding).
* Only call [functions supported](#supported-functions) by the compiler. * Solo llame [funciones compátibles](#supported-functions) por el compilador.
* Decorated and data-bound class members must be public. * Miembros de clase decorados y con enlaces de datos deben ser públicos.
For additional guidelines and instructions on preparing an application for AOT compilation, see [Angular: Writing AOT-friendly applications](https://medium.com/sparkles-blog/angular-writing-aot-friendly-applications-7b64c8afbe3f). Para guías e instrucciones adicionales al preparar una aplicación para compilación anticipada (AOT), revise [Angular: Writing AOT-friendly applications](https://medium.com/sparkles-blog/angular-writing-aot-friendly-applications-7b64c8afbe3f).
<div class="alert is-helpful"> <div class="alert is-helpful">
Errors in AOT compilation commonly occur because of metadata that does not conform to the compiler's requirements (as described more fully below). Los errores en compilación anticipada (AOT) comúnmente ocurren debido a que los metadatos no se ajustan a los requisitos del compilador (como se describen con más detalle a continuación).
For help in understanding and resolving these problems, see [AOT Metadata Errors](guide/aot-metadata-errors). Para ayudar a entender y resolver estos problemas, revisa [Errores de metadatos en AOT](guide/aot-metadata-errors).
</div> </div>
### Configuring AOT compilation ### Configurando la compilación anticipada (AOT).
You can provide options in the [TypeScript configuration file](guide/typescript-configuration) that controls the compilation process. See [Angular compiler options](guide/angular-compiler-options) for a complete list of available options. Puedes proporcionar opciones en el [archivo de configuración de TypeScript](guide/typescript-configuration) que controlan el proceso de compilación. Revisa [las opciones de compilación de Angular](guide/angular-compiler-options) para una lista completa de opciones disponibles.
## Phase 1: Code analysis ## Fase 1: Análisis de código.
The TypeScript compiler does some of the analytic work of the first phase. It emits the `.d.ts` _type definition files_ with type information that the AOT compiler needs to generate application code. El compilador de TypeScript realiza parte del trabajo analítico en la primer fase. Este emite los _archivos de definición de tipos_ `.d.ts` con el tipo de información que el compilador AOT necesita para generar el código de la aplicación.
At the same time, the AOT **collector** analyzes the metadata recorded in the Angular decorators and outputs metadata information in **`.metadata.json`** files, one per `.d.ts` file. Al mismo tiempo, el **recolector** AOT analiza los metadatos registrados en los decoradores de Angular y genera información de metadatos en archivos **`.metadata.json`**, uno por archivo `.d.ts`.
You can think of `.metadata.json` as a diagram of the overall structure of a decorator's metadata, represented as an [abstract syntax tree (AST)](https://en.wikipedia.org/wiki/Abstract_syntax_tree). Puedes pensar en `.metadata.json` como un diagrama de la estructura general de los metadatos de un decorador, representados como un [árbol de sintaxis abstracta (AST)](https://en.wikipedia.org/wiki/Abstract_syntax_tree).
<div class="alert is-helpful"> <div class="alert is-helpful">
Angular's [schema.ts](https://github.com/angular/angular/blob/master/packages/compiler-cli/src/metadata/schema.ts) El [schema.ts](https://github.com/angular/angular/blob/master/packages/compiler-cli/src/metadata/schema.ts) de Angular describe el formato JSON como una colección de interfaces de TypeScript.
describes the JSON format as a collection of TypeScript interfaces.
</div> </div>
{@a expression-syntax} {@a expression-syntax}
### Expression syntax limitations ### Limitaciones del sintaxis de expresión.
The AOT collector only understands a subset of JavaScript. El recolector de AOT solo entiende un subconjunto de JavaScript.
Define metadata objects with the following limited syntax: Defina objetos de metadatos con la siguiente sintaxis limitada:
<style> <style>
td, th {vertical-align: top} td, th {vertical-align: top}
@ -133,85 +130,84 @@ Define metadata objects with the following limited syntax:
<table> <table>
<tr> <tr>
<th>Syntax</th> <th>Sintaxis</th>
<th>Example</th> <th>Ejemplo</th>
</tr> </tr>
<tr> <tr>
<td>Literal object </td> <td>Objeto literal </td>
<td><code>{cherry: true, apple: true, mincemeat: false}</code></td> <td><code>{cherry: true, apple: true, mincemeat: false}</code></td>
</tr> </tr>
<tr> <tr>
<td>Literal array </td> <td>Colección literal </td>
<td><code>['cherries', 'flour', 'sugar']</code></td> <td><code>['cherries', 'flour', 'sugar']</code></td>
</tr> </tr>
<tr> <tr>
<td>Spread in literal array</td> <td>Operador spread en colección literal</td>
<td><code>['apples', 'flour', ...the_rest]</code></td> <td><code>['apples', 'flour', ...the_rest]</code></td>
</tr> </tr>
<tr> <tr>
<td>Calls</td> <td>Llamadas</td>
<td><code>bake(ingredients)</code></td> <td><code>bake(ingredients)</code></td>
</tr> </tr>
<tr> <tr>
<td>New</td> <td>Nuevo</td>
<td><code>new Oven()</code></td> <td><code>new Oven()</code></td>
</tr> </tr>
<tr> <tr>
<td>Property access</td> <td>Acceso a propiedades</td>
<td><code>pie.slice</code></td> <td><code>pie.slice</code></td>
</tr> </tr>
<tr> <tr>
<td>Array index</td> <td>Indices de colección</td>
<td><code>ingredients[0]</code></td> <td><code>ingredients[0]</code></td>
</tr> </tr>
<tr> <tr>
<td>Identity reference</td> <td>Referencia de identidad</td>
<td><code>Component</code></td> <td><code>Component</code></td>
</tr> </tr>
<tr> <tr>
<td>A template string</td> <td>Una plantilla de cadena</td>
<td><code>`pie is ${multiplier} times better than cake`</code></td> <td><code>`pie is ${multiplier} times better than cake`</code></td>
<tr> <tr>
<td>Literal string</td> <td>Cadena literal</td>
<td><code>pi</code></td> <td><code>pi</code></td>
</tr> </tr>
<tr> <tr>
<td>Literal number</td> <td>Numero literal</td>
<td><code>3.14153265</code></td> <td><code>3.14153265</code></td>
</tr> </tr>
<tr> <tr>
<td>Literal boolean</td> <td>Booleano literal</td>
<td><code>true</code></td> <td><code>true</code></td>
</tr> </tr>
<tr> <tr>
<td>Literal null</td> <td>Nulo literal</td>
<td><code>null</code></td> <td><code>null</code></td>
</tr> </tr>
<tr> <tr>
<td>Supported prefix operator </td> <td>Soporte a operador prefijo</td>
<td><code>!cake</code></td> <td><code>!cake</code></td>
</tr> </tr>
<tr> <tr>
<td>Supported binary operator </td> <td>Soporte a operaciones binarias</td>
<td><code>a+b</code></td> <td><code>a+b</code></td>
</tr> </tr>
<tr> <tr>
<td>Conditional operator</td> <td>Operador condicional</td>
<td><code>a ? b : c</code></td> <td><code>a ? b : c</code></td>
</tr> </tr>
<tr> <tr>
<td>Parentheses</td> <td>Paréntesis</td>
<td><code>(a+b)</code></td> <td><code>(a+b)</code></td>
</tr> </tr>
</table> </table>
Si una expresión usa sintaxis no compatible, el recolector escribe un error de nodo en el archivo `.metadata.json`.
If an expression uses unsupported syntax, the collector writes an error node to the `.metadata.json` file. El compilador luego reporta el error si necesita esa pieza de metadatos para generar el código de la aplicación.
The compiler later reports the error if it needs that piece of metadata to generate the application code.
<div class="alert is-helpful"> <div class="alert is-helpful">
If you want `ngc` to report syntax errors immediately rather than produce a `.metadata.json` file with errors, set the `strictMetadataEmit` option in the TypeScript configuration file. Si quieres que `ngc` reporte errores de sintaxis inmediatamente en lugar de producir un archivo `.metadata.json` con errores, configurá la opción `strictMetadataEmit` en el archivo de configuración de TypeScript.
``` ```
"angularCompilerOptions": { "angularCompilerOptions": {
@ -220,18 +216,17 @@ The compiler later reports the error if it needs that piece of metadata to gener
} }
``` ```
Angular libraries have this option to ensure that all Angular `.metadata.json` files are clean and it is a best practice to do the same when building your own libraries. Las librerías de Angular tienen esta opción para asegurar que todo los archivos `.metadata.json` están limpios y es una buena practica hacer lo mismo cuando construimos nuestras propias librerías.
</div> </div>
{@a function-expression} {@a function-expression}
{@a arrow-functions} {@a arrow-functions}
### No arrow functions ### Sin funciones flecha
The AOT compiler does not support [function expressions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function) El compilador AOT no soporta [expresiones de función](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function) y [funciones flecha](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function), tampoco las funciones llamadas _lambda_.
and [arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions), also called _lambda_ functions.
Consider the following component decorator: Considere el siguiente decorador del componente:
```typescript ```typescript
@Component({ @Component({
@ -240,11 +235,11 @@ Consider the following component decorator:
}) })
``` ```
The AOT collector does not support the arrow function, `() => new Server()`, in a metadata expression. El recolector de AOT no soporta la función tipo flecha, `() => new Server()`, en una expression de los metadatos.
It generates an error node in place of the function. Esto genera un error de nodo en lugar de la función.
When the compiler later interprets this node, it reports an error that invites you to turn the arrow function into an _exported function_. Cuando el compilador posteriormente interpreta este nodo, este reporta un error que invita a convertir la función flecha en una _función exportada_.
You can fix the error by converting to this: Puedes arreglar este error convirtiendo a esto:
```typescript ```typescript
export function serverFactory() { export function serverFactory() {
@ -257,23 +252,23 @@ export function serverFactory() {
}) })
``` ```
In version 5 and later, the compiler automatically performs this rewriting while emitting the `.js` file. En la version 5 y posterior, el compilador realiza automáticamente esta re escritura mientras emite el archivo `.js`.
{@a exported-symbols} {@a exported-symbols}
{@a code-folding} {@a code-folding}
### Code folding ### Plegado de código (code folding)
The compiler can only resolve references to **_exported_** symbols. El compilador puede solo resolver referencias a símbolos **_exportados_**.
The collector, however, can evaluate an expression during collection and record the result in the `.metadata.json`, rather than the original expression. El recolector sin embargo, puede evaluar una expresión durante la recolección y registrar el resultado en el `.metadata.json`, en vez de la expresión original.
This allows you to make limited use of non-exported symbols within expressions. Esto permite hacer un uso limitado de símbolos no exportados dentro de expresiones.
For example, the collector can evaluate the expression `1 + 2 + 3 + 4` and replace it with the result, `10`. Por ejemplo, el recolector puede evaluar la expresión `1 + 2 + 3 + 4` y remplazarlo con el resultado, `10`.
This process is called _folding_. An expression that can be reduced in this manner is _foldable_. El proceso es llamado _plegado_. Una expresión que puede se reducida de esta manera es _plegable_.
{@a var-declaration} {@a var-declaration}
The collector can evaluate references to module-local `const` declarations and initialized `var` and `let` declarations, effectively removing them from the `.metadata.json` file. El recolector puede evaluar referencias hacia el modulo local, declaraciones `const` e inicializadas en `var` y `let` efectivamente son removidas del archivo `.metadata.json`.
Consider the following component definition: Considere la siguiente definición del componente:
```typescript ```typescript
const template = '<div>{{hero.name}}</div>'; const template = '<div>{{hero.name}}</div>';
@ -287,9 +282,9 @@ export class HeroComponent {
} }
``` ```
The compiler could not refer to the `template` constant because it isn't exported. El compilador no podría referirse hacia la constante `template` por que esta no ha sido exportada.
The collector, however, can fold the `template` constant into the metadata definition by in-lining its contents. El recolector sim embargo, puede encontrar la constante `template` dentro de la definición de metadatos insertando su contenido.
The effect is the same as if you had written: El efecto es el mismo como si hubieras escrito:
```typescript ```typescript
@Component({ @Component({
@ -301,9 +296,9 @@ export class HeroComponent {
} }
``` ```
There is no longer a reference to `template` and, therefore, nothing to trouble the compiler when it later interprets the _collector's_ output in `.metadata.json`. No hay una referencia a `template` y por lo tanto nada que moleste al compilador cuando posteriormente interprete las salidas del recolector en el archivo `.metadata.json`.
You can take this example a step further by including the `template` constant in another expression: Puedes tomar este ejemplo un paso más allá para incluir la constante `template` en otra expresión:
```typescript ```typescript
const template = '<div>{{hero.name}}</div>'; const template = '<div>{{hero.name}}</div>';
@ -317,15 +312,15 @@ export class HeroComponent {
} }
``` ```
The collector reduces this expression to its equivalent _folded_ string: El recolector reduce esta expresión a su equivalente cadena _plegada_:
``` ```
'<div>{{hero.name}}</div><div>{{hero.title}}</div>' '<div>{{hero.name}}</div><div>{{hero.title}}</div>'
``` ```
#### Foldable syntax #### Sintaxis plegable
The following table describes which expressions the collector can and cannot fold: La siguiente tabla describe cuales expresiones el recolector puede y no puede encontrar:
<style> <style>
td, th {vertical-align: top} td, th {vertical-align: top}
@ -333,101 +328,101 @@ The following table describes which expressions the collector can and cannot fol
<table> <table>
<tr> <tr>
<th>Syntax</th> <th>Sintaxis</th>
<th>Foldable</th> <th>Plegable</th>
</tr> </tr>
<tr> <tr>
<td>Literal object </td> <td>Objeto literal </td>
<td>yes</td> <td>si</td>
</tr> </tr>
<tr> <tr>
<td>Literal array </td> <td>Colección literal </td>
<td>yes</td> <td>si</td>
</tr> </tr>
<tr> <tr>
<td>Spread in literal array</td> <td>Operador spread en colección literal</td>
<td>no</td> <td>no</td>
</tr> </tr>
<tr> <tr>
<td>Calls</td> <td>Llamadas</td>
<td>no</td> <td>no</td>
</tr> </tr>
<tr> <tr>
<td>New</td> <td>Nuevo</td>
<td>no</td> <td>no</td>
</tr> </tr>
<tr> <tr>
<td>Property access</td> <td>Acceso a propiedades<</td>
<td>yes, if target is foldable</td> <td>si, si el objetivo es plegable</td>
</tr> </tr>
<tr> <tr>
<td>Array index</td> <td>Indices de colección</td>
<td> yes, if target and index are foldable</td> <td>si, si el objetivo y el indice es plegable</td>
</tr> </tr>
<tr> <tr>
<td>Identity reference</td> <td>Referencia de identidad</td>
<td>yes, if it is a reference to a local</td> <td>si, si es una referencia a una local</td>
</tr> </tr>
<tr> <tr>
<td>A template with no substitutions</td> <td>Una plantilla sin sustituciones</td>
<td>yes</td> <td>si</td>
</tr> </tr>
<tr> <tr>
<td>A template with substitutions</td> <td>Una plantilla con sustituciones</td>
<td>yes, if the substitutions are foldable</td> <td>si, si las sustituciones son plegables</td>
</tr> </tr>
<tr> <tr>
<td>Literal string</td> <td>Cadena literal</td>
<td>yes</td> <td>si</td>
</tr> </tr>
<tr> <tr>
<td>Literal number</td> <td>Numero literal</td>
<td>yes</td> <td>si</td>
</tr> </tr>
<tr> <tr>
<td>Literal boolean</td> <td>Booleano literal</td>
<td>yes</td> <td>si</td>
</tr> </tr>
<tr> <tr>
<td>Literal null</td> <td>Nulo literal</td>
<td>yes</td> <td>si</td>
</tr> </tr>
<tr> <tr>
<td>Supported prefix operator </td> <td>Soporte a operador prefijo </td>
<td>yes, if operand is foldable</td> <td>si, si el operador es plegable</td>
</tr> </tr>
<tr> <tr>
<td>Supported binary operator </td> <td>Soporte a operador binario </td>
<td>yes, if both left and right are foldable</td> <td>si, si ambos tanto el izquierda y derecha con plegables</td>
</tr> </tr>
<tr> <tr>
<td>Conditional operator</td> <td>Operador condicional</td>
<td>yes, if condition is foldable </td> <td>si, si la condición es plegable </td>
</tr> </tr>
<tr> <tr>
<td>Parentheses</td> <td>Paréntesis</td>
<td>yes, if the expression is foldable</td> <td>si, si la expresión es plegable</td>
</tr> </tr>
</table> </table>
If an expression is not foldable, the collector writes it to `.metadata.json` as an [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree) for the compiler to resolve. Si es una expresión no plegable, el recolector lo escribe a `.metadata.json` como un [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree) para que el compilador lo resuelva.
## Phase 2: code generation ## Fase 2: generación de código
The collector makes no attempt to understand the metadata that it collects and outputs to `.metadata.json`. El recolector no hace ningún intento para entender los metadatos que se recolectarón y las envía a `.metadata.json`.
It represents the metadata as best it can and records errors when it detects a metadata syntax violation. Esto representa los metadatos lo mejor que puede y registra errores cuando detecta una violación de sintaxis en los metadatos.
It's the compiler's job to interpret the `.metadata.json` in the code generation phase. Es el trabajo del compilador interpretar el `.metadata.json` en la fase de generación de código.
The compiler understands all syntax forms that the collector supports, but it may reject _syntactically_ correct metadata if the _semantics_ violate compiler rules. El compilador entiende toda las formas de sintaxis que el recolector soporta pero puede rechazar metadatos _sintácticamente_ correctos si la _semántica_ viola reglas del compilador.
### Public symbols ### Símbolos públicos
The compiler can only reference _exported symbols_. El compilador puede solo referirse a _símbolos exportados_.
* Decorated component class members must be public. You cannot make an `@Input()` property private or protected. * Los atributos de la clase que tienen un decorador deben ser públicos. No puedes hacer que una propiedad `@Input()` sea privada o protegida.
* Data bound properties must also be public. * Las propiedades enlazadas a datos también deben ser publicas.
```typescript ```typescript
// BAD CODE - title is private // BAD CODE - title is private
@ -442,32 +437,32 @@ export class AppComponent {
{@a supported-functions} {@a supported-functions}
### Supported classes and functions ### Clases y funciones compatibles
The collector can represent a function call or object creation with `new` as long as the syntax is valid. El recolector puede representar una función o la creación de un objeto con `new` mientras la sintaxis sea valida.
The compiler, however, can later refuse to generate a call to a _particular_ function or creation of a _particular_ object. El compilador, sin embargo, puede posteriormente rechazar a generar una llamada hacia una función _particular_ o la creación de un objeto _particular_.
The compiler can only create instances of certain classes, supports only core decorators, and only supports calls to macros (functions or static methods) that return expressions. El compilador puede solo crea instancias de ciertas clases, compatibles solo con decoradores centrales y solo compatibles con llamadas a macros (funciones o métodos estáticos) que retornan expresiones.
* New instances
The compiler only allows metadata that create instances of the class `InjectionToken` from `@angular/core`. * Nuevas instancias
El compilador solo permite metadatos que crean instancias de las clases `InjectionToken` de `@angular/core`.
* Supported decorators * Decoradores soportados
El compilador solo soporta metadatos del [Modulo de decoradores de Angular en `@angular/core`](api/core#decorators).
The compiler only supports metadata for the [Angular decorators in the `@angular/core` module](api/core#decorators). * Llamadas a funciones
* Function calls Las funciones de fabrica deben ser exportadas.
El compilador AOT no soporta expresiones lambda ("funciones flecha") para las funciones de fabrica.
Factory functions must be exported, named functions.
The AOT compiler does not support lambda expressions ("arrow functions") for factory functions.
{@a function-calls} {@a function-calls}
### Functions and static method calls
The collector accepts any function or static method that contains a single `return` statement. ### Llamadas a funciones y métodos estáticos.
The compiler, however, only supports macros in the form of functions or static methods that return an *expression*.
For example, consider the following function: El recolector acepta cualquier función o método estático que contenga una sola declaración de `return`.
El compilador sin embargo, solo soporta macros (funciones o métodos estáticos) en la forma de funciones y métodos estáticos que retornan una *expression*.
Por ejemplo, considere la siguiente función:
```typescript ```typescript
export function wrapInArray<T>(value: T): T[] { export function wrapInArray<T>(value: T): T[] {
@ -475,9 +470,9 @@ export function wrapInArray<T>(value: T): T[] {
} }
``` ```
You can call the `wrapInArray` in a metadata definition because it returns the value of an expression that conforms to the compiler's restrictive JavaScript subset. Puedes llamar a `wrapInArray` en una definición de metadatos porque este retorna el valor de una expresiones qué se ajusta al subconjunto de Javascript restringido del compilador.
You might use `wrapInArray()` like this: Puede usar `wrapInArray()` así:
```typescript ```typescript
@NgModule({ @NgModule({
@ -486,7 +481,7 @@ You might use `wrapInArray()` like this:
export class TypicalModule {} export class TypicalModule {}
``` ```
The compiler treats this usage as if you had written: El compilador trata este uso como si hubieras escrito:
```typescript ```typescript
@NgModule({ @NgModule({
@ -494,19 +489,19 @@ The compiler treats this usage as if you had written:
}) })
export class TypicalModule {} export class TypicalModule {}
``` ```
The Angular [`RouterModule`](api/router/RouterModule) exports two macro static methods, `forRoot` and `forChild`, to help declare root and child routes.
Review the [source code](https://github.com/angular/angular/blob/master/packages/router/src/router_module.ts#L139 "RouterModule.forRoot source code") El [`RouterModule`](api/router/RouterModule) de Angular exporta dos métodos estáticos, `forRoot` y `forChild` para ayudar a declarar rutas raíz e hijas.
for these methods to see how macros can simplify configuration of complex [NgModules](guide/ngmodules). Revisa el [código fuente](https://github.com/angular/angular/blob/master/packages/router/src/router_module.ts#L139 "RouterModule.forRoot source code") para estos métodos para ver como los macros puede simplificar la configuración de complejos [NgModules](guide/ngmodules).
{@a metadata-rewriting} {@a metadata-rewriting}
### Metadata rewriting ### Re escribiendo metadatos
The compiler treats object literals containing the fields `useClass`, `useValue`, `useFactory`, and `data` specially, converting the expression initializing one of these fields into an exported variable that replaces the expression. El compilador trata a los objetos literales que contengan los campos `useClass`, `useValue`, `useFactory` y `data` específicamente, convirtiendo la expresión inicializando uno de estos campos en una variable exportada que reemplaza la expresión
This process of rewriting these expressions removes all the restrictions on what can be in them because
the compiler doesn't need to know the expression's value&mdash;it just needs to be able to generate a reference to the value.
You might write something like: Este proceso de rescribir estas expresiones remueve todo las restricciones que pueden estar en el, porque el compilador no necesita conocer el valor de las expresiones solo necesita poder generar una referencia al valor.
Puedes escribir algo como:
```typescript ```typescript
class TypicalServer { class TypicalServer {
@ -519,8 +514,8 @@ class TypicalServer {
export class TypicalModule {} export class TypicalModule {}
``` ```
Without rewriting, this would be invalid because lambdas are not supported and `TypicalServer` is not exported. Sin la reescritura, esto sería invalido por que las lambdas no son soportadas y `TypicalServer` no esta exportada.
To allow this, the compiler automatically rewrites this to something like: Para permitirlo, el compilador automáticamente re escribe esto a algo como:
```typescript ```typescript
class TypicalServer { class TypicalServer {
@ -535,40 +530,38 @@ export const ɵ0 = () => new TypicalServer();
export class TypicalModule {} export class TypicalModule {}
``` ```
This allows the compiler to generate a reference to `ɵ0` in the factory without having to know what the value of `ɵ0` contains. Esto permite que el compilador genere una referencia hacia `ɵ0` en la fabrica sin tener que conocer cual es el valor de `ɵ0`.
The compiler does the rewriting during the emit of the `.js` file. El compilador hace la reescritura durante la emisión de el archivo `.js`.
It does not, however, rewrite the `.d.ts` file, so TypeScript doesn't recognize it as being an export. and it does not interfere with the ES module's exported API. Sin embargo, no reescribe el archivo `.d.ts`, entonces TypeScript no lo reconoce como una exportación y esto no interfiere con la API exportada de los módulos ES.
{@a binding-expression-validation} {@a binding-expression-validation}
## Phase 3: Template type checking ## Fase 3: Verificación de tipos en las plantillas
One of the Angular compiler's most helpful features is the ability to type-check expressions within templates, and catch any errors before they cause crashes at runtime. Una de las características más útiles del compilador de Angular es la habilidad de comprobar el tipado de las expresiones dentro de las plantillas y capturar cualquier error antes de que ellos causen fallas en tiempo de ejecución.
In the template type-checking phase, the Angular template compiler uses the TypeScript compiler to validate the binding expressions in templates.
Enable this phase explicitly by adding the compiler option `"fullTemplateTypeCheck"` in the `"angularCompilerOptions"` of the project's TypeScript configuration file En la fase de verificación de tipos en las plantillas, el compilador de plantillas de Angular usa a el compilador de TypeScript para validar las expresiones con enlazadas a datos en las plantillas.
(see [Angular Compiler Options](guide/angular-compiler-options)).
Habilite esta fase explícitamente agregando la opción del compilador `"fullTemplateTypeCheck"` en las `"angularCompilerOptions"` del archivo de configuración del proyecto TypeScript (mira [Opciones del compilador de Angular](guide/angular-compiler-options)).
<div class="alert is-helpful"> <div class="alert is-helpful">
In [Angular Ivy](guide/ivy), the template type checker has been completely rewritten to be more capable as well as stricter, meaning it can catch a variety of new errors that the previous type checker would not detect. En [Angular Ivy](guide/ivy), la verificación de tipos para las plantillas a sido completamente reescrita para ser más capaz así como más estricto, esto significa poder capturar una variedad de nuevos errores que antes el verificador de tipos no podia detectar.
As a result, templates that previously compiled under View Engine can fail type checking under Ivy. This can happen because Ivy's stricter checking catches genuine errors, or because application code is not typed correctly, or because the application uses libraries in which typings are inaccurate or not specific enough. Como resultado, las plantillas que previamente se compilarón bajo `View Engine` pueden fallar con el verificador de tipos bajo `Ivy`. Esto puede pasar por que el verificador de Ivy captura errores genuinos o porque el código de la aplicación no esta tipado correctamente o porque la aplicación usa librerías en las cuales el tipado es incorrecto o no es lo suficientemente especifico.
This stricter type checking is not enabled by default in version 9, but can be enabled by setting the `strictTemplates` configuration option. Este verificador de tipos estricto no esta habilitado por defecto el la version 9 pero puedes habilitarlo configurando la opción `strictTemplates`.
We do expect to make strict type checking the default in the future. Nosotros esperamos hacer que el verificador de tipos estricto este habilitado por defecto en el futuro.
For more information about type-checking options, and about improvements to template type checking in version 9 and above, see [Template type checking](guide/template-typecheck). Para más información acerca de las opciones del verificador de tipos y más acerca de mejoras hacia la verificación de tipos en plantillas en la version 9 en adelante, mira [Verificando tipos en plantillas](guide/template-typecheck).
</div> </div>
Template validation produces error messages when a type error is detected in a template binding La validación de templates produce mensajes de error cuando un error de tipo es detectado en una plantilla con una expresión con enlace de datos, similar a como los errores de tipado son reportados por el compilador de TypeScript contra el código en un archivo `.ts`.
expression, similar to how type errors are reported by the TypeScript compiler against code in a `.ts`
file.
For example, consider the following component: Por ejemplo, considere el siguiente componente:
```typescript ```typescript
@Component({ @Component({
@ -580,32 +573,29 @@ For example, consider the following component:
} }
``` ```
This produces the following error: Esto produce el siguiente error:
``` ```
my.component.ts.MyComponent.html(1,1): : Property 'addresss' does not exist on type 'Person'. Did you mean 'address'? my.component.ts.MyComponent.html(1,1): : Property 'addresss' does not exist on type 'Person'. Did you mean 'address'?
``` ```
The file name reported in the error message, `my.component.ts.MyComponent.html`, is a synthetic file El archivo reporta el mensaje de error, `my.component.ts.MyComponent.html`, es un archivo sintético generado por el compilador de plantillas que espera que tenga contenido de la clase `MyComponent`.
generated by the template compiler that holds contents of the `MyComponent` class template. El compilador nunca escribe un archivo en el disco.
The compiler never writes this file to disk. Los números de línea y columna son relativos a la plantilla de cadena en el anotación `@Component` de la clase, `MyComponent` en este caso.
The line and column numbers are relative to the template string in the `@Component` annotation of the class, `MyComponent` in this case. Si un componente usa `templateUrl` en vez de `template`, los errores son reportados en el archivo HTML referenciado por el `templateUrl` en vez de un archivo sintético.
If a component uses `templateUrl` instead of `template`, the errors are reported in the HTML file referenced by the `templateUrl` instead of a synthetic file.
The error location is the beginning of the text node that contains the interpolation expression with the error. La ubicación del error esta en el inicio del nodo de texto que contiene la expresión interpolada con el error.
If the error is in an attribute binding such as `[value]="person.address.street"`, the error Si el error esta en un atributo con enlace de datos como `[value]="person.address.street"`, la ubicación del error es la ubicación del atributo que contiene el error.
location is the location of the attribute that contains the error.
La validación usa el verificador de tipos de TypeScript y las opciones suministradas hacia el compilador de TypeScript para controlar qué tan detallada es la validación de tipos.
Por ejemplo, si el `strictTypeChecks` es especificado, el error ```my.component.ts.MyComponent.html(1,1): : Object is possibly 'undefined'``` es reportado así como el mensaje de error anterior.
The validation uses the TypeScript type checker and the options supplied to the TypeScript compiler to control how detailed the type validation is.
For example, if the `strictTypeChecks` is specified, the error
```my.component.ts.MyComponent.html(1,1): : Object is possibly 'undefined'```
is reported as well as the above error message.
### Type narrowing ### Type narrowing
The expression used in an `ngIf` directive is used to narrow type unions in the Angular La expresión usada en un directiva `ngIf` es usada para estrechar uniones de tipo en el compilador de plantillas de Angular, de la misma manera que la expresión `if` lo hace en TypeScript.
template compiler, the same way the `if` expression does in TypeScript. Por ejemplo, para evitar el error `Object is possibly 'undefined'` en la plantilla de arriba, modifícalo para que solo emita la interpolación si el valor de `person` esta inicializado como se muestra en seguida:
For example, to avoid `Object is possibly 'undefined'` error in the template above, modify it to only emit the interpolation if the value of `person` is initialized as shown below:
```typescript ```typescript
@Component({ @Component({
@ -617,16 +607,17 @@ For example, to avoid `Object is possibly 'undefined'` error in the template abo
} }
``` ```
Using `*ngIf` allows the TypeScript compiler to infer that the `person` used in the binding expression will never be `undefined`. Usando `*ngIf` permite que el compilador de TypeScript infiera que el atributo `person` usado en la expresión enlanzada nunca séra `undefined`.
For more information about input type narrowing, see [Input setter coercion](guide/template-typecheck#input-setter-coercion) and [Improving template type checking for custom directives](guide/structural-directives#directive-type-checks). Para más información acerca del estrechamiento de tipos de entrada, mira [Coerción del establecedor de entrada](guide/template-typecheck#input-setter-coercion) y [Mejorando el verificar de tipos para directivas personalizadas](guide/structural-directives#directive-type-checks).
### Non-null type assertion operator ### Operador de aserción de tipo nulo
Use the [non-null type assertion operator](guide/template-expression-operators#non-null-assertion-operator) to suppress the `Object is possibly 'undefined'` error when it is inconvenient to use `*ngIf` or when some constraint in the component ensures that the expression is always non-null when the binding expression is interpolated. Use el [operador de aserción de tipo nulo](guide/template-expression-operators#non-null-assertion-operator) para reprimir el error `Object is possibly 'undefined'` cuando es inconveniente usar `*ngIf` o cuando alguna restricción en el componente asegura que la expresión siempre es no nula cuando la expresión con enlace de datos es interpolada.
En el siguiente ejemplo, las propiedades `person` y `address` son siempre configuradas juntas, implicando que `address` siempre es no nula si `person` es no nula.
No existe una forma conveniente de describir esta restricción a TypeScript y a el compilador de plantillas pero el error es suprimido en el ejemplo por usar `address!.street`.
In the following example, the `person` and `address` properties are always set together, implying that `address` is always non-null if `person` is non-null.
There is no convenient way to describe this constraint to TypeScript and the template compiler, but the error is suppressed in the example by using `address!.street`.
```typescript ```typescript
@Component({ @Component({
@ -644,9 +635,9 @@ There is no convenient way to describe this constraint to TypeScript and the tem
} }
``` ```
The non-null assertion operator should be used sparingly as refactoring of the component might break this constraint. El operador de aserción de tipo nulo debería usarse con moderación ya que la refactorización del componente podría romper esta restricción.
In this example it is recommended to include the checking of `address` in the `*ngIf` as shown below: En este ejemplo es recomendable incluir la verificación de `address` en el `*ngIf` como se muestra a continuación:
```typescript ```typescript
@Component({ @Component({

View File

@ -1,32 +1,32 @@
# App shell # App shell
App shell is a way to render a portion of your application via a route at build time. App shell es una manera de renderizar una porción de tu aplicación a través de una ruta en tiempo de compilación (build time).
It can improve the user experience by quickly launching a static rendered page (a skeleton common to all pages) while the browser downloads the full client version and switches to it automatically after the code loads. Puede mejorar la experiencia de usuario lanzando rápidamente una página estática renderizada (un esqueleto común a todas las páginas) mientras el navegador descarga la versión completa del cliente y la muestra automáticamente al finalizar su carga.
This gives users a meaningful first paint of your application that appears quickly because the browser can simply render the HTML and CSS without the need to initialize any JavaScript. Esto da a los usuarios una primera visualización significativa de su aplicación que aparece rápidamente porque el navegador simplemente puede renderizar HTML y CSS sin la necesidad de inicializar JavaScript.
Learn more in [The App Shell Model](https://developers.google.com/web/fundamentals/architecture/app-shell). Obténga más información en [El modelo de aplicación Shell](https://developers.google.com/web/fundamentals/architecture/app-shell).
## Step 1: Prepare the application ## Paso 1: Prepara la aplicación
You can do this with the following CLI command: Puedes hacer esto con el siguiente comando CLI:
<code-example language="bash"> <code-example language="bash">
ng new my-app --routing ng new my-app --routing
</code-example> </code-example>
For an existing application, you have to manually add the `RouterModule` and defining a `<router-outlet>` within your application. Para una aplicación existente, debes agregar manualmente el `RouterModule` y definir un` <router-outlet> `dentro de tu aplicación.
## Step 2: Create the app shell ## Paso 2: Crea el shell de la aplicación
Use the CLI to automatically create the app shell. Usa la CLI para crear automáticamente el shell de la aplicación.
<code-example language="bash"> <code-example language="bash">
ng generate app-shell ng generate app-shell
</code-example> </code-example>
* `client-project` takes the name of your client application. * `client-project` toma el nombre de tu aplicación cliente.
After running this command you will notice that the `angular.json` configuration file has been updated to add two new targets, with a few other changes. Después de ejecutar este comando, notará que el archivo de configuración `angular.json` se ha actualizado para agregar dos nuevos targets, con algunos otros cambios.
<code-example language="json"> <code-example language="json">
"server": { "server": {
@ -53,20 +53,18 @@ After running this command you will notice that the `angular.json` configuration
} }
</code-example> </code-example>
## Step 3: Verify the app is built with the shell content ## Paso 3: Verifica que la aplicación está construida con el contenido del shell
Use the CLI to build the `app-shell` target. Usa la CLI para construir el `app-shell` target.
<code-example language="bash"> <code-example language="bash">
ng run my-app:app-shell ng run my-app:app-shell
</code-example> </code-example>
Or to use the production configuration. O usa la configuración de producción.
<code-example language="bash"> <code-example language="bash">
ng run my-app:app-shell:production ng run my-app:app-shell:production
</code-example> </code-example>
To verify the build output, open `dist/my-app/index.html`. Look for default text `app-shell works!` to show that the app shell route was rendered as part of the output. Para verificar el resultado de la compilación, abre `dist/my-app/index.html`. Busca el texto por defecto `app-shell works!` para mostrar que la ruta del shell de la aplicación se ha renderizado como parte de la carpeta de distribución.

View File

@ -0,0 +1,104 @@
# Introduction to modules
Angular apps are modular and Angular has its own modularity system called *NgModules*.
NgModules are containers for a cohesive block of code dedicated to an application domain, a workflow, or a closely related set of capabilities. They can contain components, service providers, and other code files whose scope is defined by the containing NgModule. They can import functionality that is exported from other NgModules, and export selected functionality for use by other NgModules.
Every Angular app has at least one NgModule class, [the *root module*](guide/bootstrapping), which is conventionally named `AppModule` and resides in a file named `app.module.ts`. You launch your app by *bootstrapping* the root NgModule.
While a small application might have only one NgModule, most apps have many more *feature modules*. The *root* NgModule for an app is so named because it can include child NgModules in a hierarchy of any depth.
## NgModule metadata
An NgModule is defined by a class decorated with `@NgModule()`. The `@NgModule()` decorator is a function that takes a single metadata object, whose properties describe the module. The most important properties are as follows.
* `declarations`: The [components](guide/architecture-components), *directives*, and *pipes* that belong to this NgModule.
* `exports`: The subset of declarations that should be visible and usable in the *component templates* of other NgModules.
* `imports`: Other modules whose exported classes are needed by component templates declared in *this* NgModule.
* `providers`: Creators of [services](guide/architecture-services) that this NgModule contributes to the global collection of services; they become accessible in all parts of the app. (You can also specify providers at the component level, which is often preferred.)
* `bootstrap`: The main application view, called the *root component*, which hosts all other app views. Only the *root NgModule* should set the `bootstrap` property.
Here's a simple root NgModule definition.
<code-example path="architecture/src/app/mini-app.ts" region="module" header="src/app/app.module.ts"></code-example>
<div class="alert is-helpful">
`AppComponent` is included in the `exports` list here for illustration; it isn't actually necessary in this example. A root NgModule has no reason to *export* anything because other modules don't need to *import* the root NgModule.
</div>
## NgModules and components
NgModules provide a *compilation context* for their components. A root NgModule always has a root component that is created during bootstrap, but any NgModule can include any number of additional components, which can be loaded through the router or created through the template. The components that belong to an NgModule share a compilation context.
<div class="lightbox">
<img src="generated/images/guide/architecture/compilation-context.png" alt="Component compilation context" class="left">
</div>
<br class="clear">
A component and its template together define a *view*. A component can contain a *view hierarchy*, which allows you to define arbitrarily complex areas of the screen that can be created, modified, and destroyed as a unit. A view hierarchy can mix views defined in components that belong to different NgModules. This is often the case, especially for UI libraries.
<div class="lightbox">
<img src="generated/images/guide/architecture/view-hierarchy.png" alt="View hierarchy" class="left">
</div>
<br class="clear">
When you create a component, it's associated directly with a single view, called the *host view*. The host view can be the root of a view hierarchy, which can contain *embedded views*, which are in turn the host views of other components. Those components can be in the same NgModule, or can be imported from other NgModules. Views in the tree can be nested to any depth.
<div class="alert is-helpful">
**Note:** The hierarchical structure of views is a key factor in the way Angular detects and responds to changes in the DOM and app data.
</div>
## NgModules and JavaScript modules
The NgModule system is different from and unrelated to the JavaScript (ES2015) module system for managing collections of JavaScript objects. These are *complementary* module systems that you can use together to write your apps.
In JavaScript each *file* is a module and all objects defined in the file belong to that module.
The module declares some objects to be public by marking them with the `export` key word.
Other JavaScript modules use *import statements* to access public objects from other modules.
<code-example path="architecture/src/app/app.module.ts" region="imports"></code-example>
<code-example path="architecture/src/app/app.module.ts" region="export"></code-example>
<div class="alert is-helpful">
<a href="http://exploringjs.com/es6/ch_modules.html">Learn more about the JavaScript module system on the web.</a>
</div>
## Angular libraries
<img src="generated/images/guide/architecture/library-module.png" alt="Component" class="left">
Angular loads as a collection of JavaScript modules. You can think of them as library modules. Each Angular library name begins with the `@angular` prefix. Install them with the node package manager `npm` and import parts of them with JavaScript `import` statements.
<br class="clear">
For example, import Angular's `Component` decorator from the `@angular/core` library like this.
<code-example path="architecture/src/app/app.component.ts" region="import"></code-example>
You also import NgModules from Angular *libraries* using JavaScript import statements.
For example, the following code imports the `BrowserModule` NgModule from the `platform-browser` library.
<code-example path="architecture/src/app/mini-app.ts" region="import-browser-module"></code-example>
In the example of the simple root module above, the application module needs material from within
`BrowserModule`. To access that material, add it to the `@NgModule` metadata `imports` like this.
<code-example path="architecture/src/app/mini-app.ts" region="ngmodule-imports"></code-example>
In this way you're using the Angular and JavaScript module systems *together*. Although it's easy to confuse the two systems, which share the common vocabulary of "imports" and "exports", you will become familiar with the different contexts in which they are used.
<div class="alert is-helpful">
Learn more from the [NgModules](guide/ngmodules) guide.
</div>

View File

@ -1,39 +1,39 @@
# Introduction to modules # Introducción a módulos
Angular apps are modular and Angular has its own modularity system called *NgModules*. Las aplicaciones Angular son modulares y Angular tiene su propio sistema de modularidad llamado *NgModules*.
NgModules are containers for a cohesive block of code dedicated to an application domain, a workflow, or a closely related set of capabilities. They can contain components, service providers, and other code files whose scope is defined by the containing NgModule. They can import functionality that is exported from other NgModules, and export selected functionality for use by other NgModules. Los NgModules son contenedores para un bloque cohesivo de código dedicado a un dominio de aplicación, un flujo de trabajo o un conjunto de capacidades estrechamente relacionadas. Pueden contener componentes, proveedores de servicios y otros archivos de código cuyo alcance está definido por el NgModule que los contiene. Pueden importar la funcionalidad que se exporta desde otros NgModules y exportar la funcionalidad seleccionada para que la utilicen otros NgModules.
Every Angular app has at least one NgModule class, [the *root module*](guide/bootstrapping), which is conventionally named `AppModule` and resides in a file named `app.module.ts`. You launch your app by *bootstrapping* the root NgModule. Cada aplicación Angular tiene al menos una clase NgModule, [el *módulo raíz*](guide/bootstrapping), que se llama convencionalmente `AppModule` y reside en un archivo llamado `app.module.ts`. Inicia tu aplicación *cargando* el NgModule raíz.
While a small application might have only one NgModule, most apps have many more *feature modules*. The *root* NgModule for an app is so named because it can include child NgModules in a hierarchy of any depth. Si bien una aplicación pequeña puede tener sólo un NgModule, la mayoría de las aplicaciones tienen muchos más *módulos de funcionalidad*. El NgModule *raíz* para una aplicación se llama así porque puede incluir NgModules secundarios en una jerarquía de cualquier profundidad.
## NgModule metadata ## Metadatos de NgModule
An NgModule is defined by a class decorated with `@NgModule()`. The `@NgModule()` decorator is a function that takes a single metadata object, whose properties describe the module. The most important properties are as follows. Un NgModule está definido por una clase decorada con `@NgModule()`. El decorador `@NgModule()` es una función que toma un único objeto de metadatos, cuyas propiedades describen el módulo. Las propiedades más importantes son las siguientes.
* `declarations`: The [components](guide/architecture-components), *directives*, and *pipes* that belong to this NgModule. * `declarations`: Los [componentes](guide/architecture-components), *directivas*, y *pipes* que pertenecen a este NgModule.
* `exports`: The subset of declarations that should be visible and usable in the *component templates* of other NgModules. * `exports`: El subconjunto de declaraciones que deberían ser visibles y utilizables en las *plantillas de componentes* de otros NgModules.
* `imports`: Other modules whose exported classes are needed by component templates declared in *this* NgModule. * `imports`: Otros módulos cuyas clases exportadas son necesarias para las plantillas de componentes declaradas en *este* NgModule.
* `providers`: Creators of [services](guide/architecture-services) that this NgModule contributes to the global collection of services; they become accessible in all parts of the app. (You can also specify providers at the component level, which is often preferred.) * `providers`: Creadores de [servicios](guide/architecture-services) que este NgModule aporta a la colección global de servicios; se vuelven accesibles en todas las partes de la aplicación. (También puedes especificar proveedores a nivel de componente, que a menudo es preferido).
* `bootstrap`: The main application view, called the *root component*, which hosts all other app views. Only the *root NgModule* should set the `bootstrap` property. * `bootstrap`: La vista principal de la aplicación, llamado el *componente raíz*, que aloja todas las demás vistas de la aplicación. Sólo el *NgModule raíz* debe establecer la propiedad `bootstrap`.
Here's a simple root NgModule definition. Aquí hay una definición simple del NgModule raíz.
<code-example path="architecture/src/app/mini-app.ts" region="module" header="src/app/app.module.ts"></code-example> <code-example path="architecture/src/app/mini-app.ts" region="module" header="src/app/app.module.ts"></code-example>
<div class="alert is-helpful"> <div class="alert is-helpful">
`AppComponent` is included in the `exports` list here for illustration; it isn't actually necessary in this example. A root NgModule has no reason to *export* anything because other modules don't need to *import* the root NgModule. Aquí se incluye `AppComponent` en la lista de `exports` como ilustración; en realidad no es necesario en este ejemplo. Un NgModule raíz no tiene ninguna razón para *exportar* nada porque otros módulos no necesitan *importar* el NgModule raíz.
</div> </div>
## NgModules and components ## NgModules y componentes
NgModules provide a *compilation context* for their components. A root NgModule always has a root component that is created during bootstrap, but any NgModule can include any number of additional components, which can be loaded through the router or created through the template. The components that belong to an NgModule share a compilation context. NgModules proporciona un *contexto de compilación* para sus componentes. Un NgModule raíz siempre tiene un componente raíz que se crea durante el arranque, pero cualquier NgModule puede incluir cualquier cantidad de componentes adicionales, que se pueden cargar a través del enrutador o crear a través de la plantilla. Los componentes que pertenecen a un NgModule comparten un contexto de compilación.
<div class="lightbox"> <div class="lightbox">
<img src="generated/images/guide/architecture/compilation-context.png" alt="Component compilation context" class="left"> <img src="generated/images/guide/architecture/compilation-context.png" alt="Component compilation context" class="left">
@ -41,7 +41,7 @@ NgModules provide a *compilation context* for their components. A root NgModule
<br class="clear"> <br class="clear">
A component and its template together define a *view*. A component can contain a *view hierarchy*, which allows you to define arbitrarily complex areas of the screen that can be created, modified, and destroyed as a unit. A view hierarchy can mix views defined in components that belong to different NgModules. This is often the case, especially for UI libraries. Juntos, un componente y su plantilla definen una *vista*. Un componente puede contener una *jerarquía de vista*, que te permiten definir áreas arbitrariamente complejas de la pantalla que se pueden crear, modificar y destruir como una unidad. Una jerarquía de vistas puede mezclar vistas definidas en componentes que pertenecen a diferentes NgModules. Este suele ser el caso, especialmente para las bibliotecas de interfaz de usuario.
<div class="lightbox"> <div class="lightbox">
<img src="generated/images/guide/architecture/view-hierarchy.png" alt="View hierarchy" class="left"> <img src="generated/images/guide/architecture/view-hierarchy.png" alt="View hierarchy" class="left">
@ -49,56 +49,56 @@ A component and its template together define a *view*. A component can contain a
<br class="clear"> <br class="clear">
When you create a component, it's associated directly with a single view, called the *host view*. The host view can be the root of a view hierarchy, which can contain *embedded views*, which are in turn the host views of other components. Those components can be in the same NgModule, or can be imported from other NgModules. Views in the tree can be nested to any depth. Cuando creas un componente, se asocia directamente con una sola vista, llamada *vista host*. La vista host puede ser la raíz de una jerarquía de vistas, que puede contener *vistas incrustadas*, que a su vez son las vistas de host de otros componentes. Esos componentes pueden estar en el mismo NgModule o pueden importarse desde otros NgModules. Las vistas en el árbol se pueden anidar a cualquier profundidad.
<div class="alert is-helpful"> <div class="alert is-helpful">
**Note:** The hierarchical structure of views is a key factor in the way Angular detects and responds to changes in the DOM and app data. **Nota:** La estructura jerárquica de las vistas es un factor clave en la forma en que Angular detecta y responde a los cambios en el DOM y los datos de la aplicación.
</div> </div>
## NgModules and JavaScript modules ## NgModules y módulos JavaScript
The NgModule system is different from and unrelated to the JavaScript (ES2015) module system for managing collections of JavaScript objects. These are *complementary* module systems that you can use together to write your apps. El sistema NgModule es diferente y no está relacionado con el sistema de módulos JavaScript (ES2015) para administrar colecciones de objetos JavaScript. Estos son sistemas de módulos *complementarios* que puedes usar juntos para escribir tus aplicaciones.
In JavaScript each *file* is a module and all objects defined in the file belong to that module. En JavaScript, cada *archivo* es un módulo y todos los objetos definidos en el archivo pertenecen a ese módulo.
The module declares some objects to be public by marking them with the `export` key word. El módulo declara que algunos objetos son públicos marcándolos con la palabra clave `export`.
Other JavaScript modules use *import statements* to access public objects from other modules. Otros módulos de JavaScript usan *declaraciones de importación* para acceder a objetos públicos de otros módulos.
<code-example path="architecture/src/app/app.module.ts" region="imports"></code-example> <code-example path="architecture/src/app/app.module.ts" region="imports"></code-example>
<code-example path="architecture/src/app/app.module.ts" region="export"></code-example> <code-example path="architecture/src/app/app.module.ts" region="export"></code-example>
<div class="alert is-helpful"> <div class="alert is-helpful">
<a href="http://exploringjs.com/es6/ch_modules.html">Learn more about the JavaScript module system on the web.</a> <a href="http://exploringjs.com/es6/ch_modules.html">Obtén más información sobre el sistema de módulos de JavaScript en la web.</a>
</div> </div>
## Angular libraries ## Bibliotecas Angular
<img src="generated/images/guide/architecture/library-module.png" alt="Component" class="left"> <img src="generated/images/guide/architecture/library-module.png" alt="Component" class="left">
Angular loads as a collection of JavaScript modules. You can think of them as library modules. Each Angular library name begins with the `@angular` prefix. Install them with the node package manager `npm` and import parts of them with JavaScript `import` statements. Angular se carga como una colección de módulos JavaScript. Puedes pensar en ellos como módulos de biblioteca. Cada nombre de biblioteca de Angular comienza con el prefijo `@angular`. Instálalos con el gestor de paquetes `npm` e importa partes de ellos con declaraciones `import` de JavaScript.
<br class="clear"> <br class="clear">
For example, import Angular's `Component` decorator from the `@angular/core` library like this. Por ejemplo, importa el decorador `Component` de Angular de la biblioteca `@angular/core` como esta.
<code-example path="architecture/src/app/app.component.ts" region="import"></code-example> <code-example path="architecture/src/app/app.component.ts" region="import"></code-example>
You also import NgModules from Angular *libraries* using JavaScript import statements. También importa NgModules desde las *bibliotecas* Angular usando declaraciones de importación de JavaScript.
For example, the following code imports the `BrowserModule` NgModule from the `platform-browser` library. Por ejemplo, el siguiente código importa el NgModule `BrowserModule` de la biblioteca `platform-browser`.
<code-example path="architecture/src/app/mini-app.ts" region="import-browser-module"></code-example> <code-example path="architecture/src/app/mini-app.ts" region="import-browser-module"></code-example>
In the example of the simple root module above, the application module needs material from within En el ejemplo del módulo raíz simple anterior, el módulo de la aplicación necesita material de
`BrowserModule`. To access that material, add it to the `@NgModule` metadata `imports` like this. `BrowserModule`. Para acceder a ese material, agrégalo a los metadatos `imports` de `@NgModule` de esta manera.
<code-example path="architecture/src/app/mini-app.ts" region="ngmodule-imports"></code-example> <code-example path="architecture/src/app/mini-app.ts" region="ngmodule-imports"></code-example>
In this way you're using the Angular and JavaScript module systems *together*. Although it's easy to confuse the two systems, which share the common vocabulary of "imports" and "exports", you will become familiar with the different contexts in which they are used. De esta manera, estás utilizando los sistemas de módulos Angular y JavaScript *juntos*. Aunque es fácil confundir los dos sistemas, que comparten el vocabulario común de "importaciones" y "exportaciones", te familiarizarás con los diferentes contextos en los que se utilizan.
<div class="alert is-helpful"> <div class="alert is-helpful">
Learn more from the [NgModules](guide/ngmodules) guide. Obtén más información en la guía [NgModules](guide/ngmodules).
</div> </div>

View File

@ -0,0 +1,90 @@
# Next steps: tools and techniques
After you understand the basic Angular building blocks, you can learn more
about the features and tools that can help you develop and deliver Angular applications.
* Work through the [Tour of Heroes](tutorial) tutorial to get a feel for how to fit the basic building blocks together to create a well-designed application.
* Check out the [Glossary](guide/glossary) to understand Angular-specific terms and usage.
* Use the documentation to learn about key features in more depth, according to your stage of development and areas of interest.
## Application architecture
* The [Components and templates](guide/displaying-data) guide explains how to connect the application data in your [components](guide/glossary#component) to your page-display [templates](guide/glossary#template), to create a complete interactive application.
* The [NgModules](guide/ngmodules) guide provides in-depth information on the modular structure of an Angular application.
* The [Routing and navigation](guide/router) guide provides in-depth information on how to construct applications that allow a user to navigate to different [views](guide/glossary#view) within your single-page app.
* The [Dependency injection](guide/dependency-injection) guide provides in-depth information on how to construct an application such that each component class can acquire the services and objects it needs to perform its function.
## Responsive programming
The **Components and Templates** guide provides guidance and details of the [template syntax](guide/template-syntax) that you use to display your component data when and where you want it within a view, and to collect input from users that you can respond to.
Additional pages and sections describe some basic programming techniques for Angular apps.
* [Lifecycle hooks](guide/lifecycle-hooks): Tap into key moments in the lifetime of a component, from its creation to its destruction, by implementing the lifecycle hook interfaces.
* [Observables and event processing](guide/observables): How to use observables with components and services to publish and subscribe to messages of any type, such as user-interaction events and asynchronous operation results.
* [Angular elements](guide/elements): How to package components as *custom elements* using Web Components, a web standard for defining new HTML elements in a framework-agnostic way.
* [Forms](guide/forms-overview): Support complex data entry scenarios with HTML-based input validation.
* [Animations](guide/animations): Use Angular's animation library to animate component behavior
without deep knowledge of animation techniques or CSS.
## Client-server interaction
Angular provides a framework for single-page apps, where most of the logic and data resides on the client.
Most apps still need to access a server using the `HttpClient` to access and save data.
For some platforms and applications, you might also want to use the PWA (Progressive Web App) model to improve the user experience.
* [HTTP](guide/http): Communicate with a server to get data, save data, and invoke server-side actions with an HTTP client.
* [Server-side rendering](guide/universal): Angular Universal generates static application pages on the server through server-side rendering (SSR). This allows you to run your Angular app on the server in order to improve performance and show the first page quickly on mobile and low-powered devices, and also facilitate web crawlers.
* [Service workers and PWA](guide/service-worker-intro): Use a service worker to reduce dependency on the network and significantly improve the user experience.
* [Web workers](guide/web-worker): Learn how to run CPU-intensive computations in a background thread.
## Support for the development cycle
The **Development Workflow** section describes the tools and processes you use to compile, test, and deploy Angular applications.
* [CLI Command Reference](cli): The Angular CLI is a command-line tool that you use to create projects, generate application and library code, and perform a variety of ongoing development tasks such as testing, bundling, and deployment.
* [Compilation](guide/aot-compiler): Angular provides just-in-time (JIT) compilation for the development environment, and ahead-of-time (AOT) compilation for the production environment.
* [Testing platform](guide/testing): Run unit tests on your application parts as they interact with the Angular framework.
* [Deployment](guide/deployment): Learn techniques for deploying your Angular application to a remote server.
* [Security guidelines](guide/security): Learn about Angular's built-in protections against common web-app vulnerabilities and attacks such as cross-site scripting attacks.
* [Internationalization](guide/i18n): Make your app available in multiple languages with Angular's internationalization (i18n) tools.
* [Accessibility](guide/accessibility): Make your app accessible to all users.
## File structure, configuration, and dependencies
* [Workspace and file structure](guide/file-structure): Understand the structure of Angular workspace and project folders.
* [Building and serving](guide/build): Learn to define different build and proxy server configurations for your project, such as development, staging, and production.
* [npm packages](guide/npm-packages): The Angular Framework, Angular CLI, and components used by Angular applications are packaged as [npm](https://docs.npmjs.com/) packages and distributed via the npm registry. The Angular CLI creates a default `package.json` file, which specifies a starter set of packages that work well together and jointly support many common application scenarios.
* [TypeScript configuration](guide/typescript-configuration): TypeScript is the primary language for Angular application development.
* [Browser support](guide/browser-support): Make your apps compatible across a wide range of browsers.
## Extending Angular
* [Angular libraries](guide/libraries): Learn about using and creating re-usable libraries.
* [Schematics](guide/schematics): Learn about customizing and extending the CLI's generation capabilities.
* [CLI builders](guide/cli-builder): Learn about customizing and extending the CLI's ability to apply tools to perform complex tasks, such as building and testing applications.

View File

@ -1,90 +1,88 @@
# Next steps: tools and techniques # Próximos Pasos: Herramientas y Técnicas
After you understand the basic Angular building blocks, you can learn more Una vez que comprendas los conceptos básicos de Angular, puedes aprender más sobre las funcionalidades y herramientas que pueden ayudarte a desarrollar y entregar aplicaciones Angular.
about the features and tools that can help you develop and deliver Angular applications.
* Work through the [Tour of Heroes](tutorial) tutorial to get a feel for how to fit the basic building blocks together to create a well-designed application. * Realiza el tutorial [Tour de Héroes](tutorial) para familiarizarte con los conceptos básicos necesarios para crear una aplicación bien diseñada.
* Check out the [Glossary](guide/glossary) to understand Angular-specific terms and usage. * Consulta el [Glosario](guide/glossary) para comprender los términos específicos de Angular y su correspondiente utilización.
* Use the documentation to learn about key features in more depth, according to your stage of development and areas of interest. * Utiliza la documentación te permite conocer en detalle las funcionalidades claves, según tu etapa de desarrollo y tus áreas de interés.
## Application architecture ## Arquitectura de la aplicación
* The [Components and templates](guide/displaying-data) guide explains how to connect the application data in your [components](guide/glossary#component) to your page-display [templates](guide/glossary#template), to create a complete interactive application. * La guía de [Componentes y Plantillas](guide/displaying-data) explica como conectar los datos de la aplicación de sus [componentes](guide/glossary#componente) con las [plantillas](guide/glossary#plantilla) de las pantallas, para crear una aplicación completamente interactiva.
* The [NgModules](guide/ngmodules) guide provides in-depth information on the modular structure of an Angular application. * La guía de [NgModules](guide/ngmodules) proporciona información detallada sobre la estructura de módulos utilizada en una aplicación Angular.
* The [Routing and navigation](guide/router) guide provides in-depth information on how to construct applications that allow a user to navigate to different [views](guide/glossary#view) within your single-page app. * La guía de [Enrutamiento y navigación](guide/router) describe como crear aplicaciones que permitan al usuario navegar entre las diferentes [vistas](guide/glossary#vista) dentro de su aplicación de una sola página (SPA).
* The [Dependency injection](guide/dependency-injection) guide provides in-depth information on how to construct an application such that each component class can acquire the services and objects it needs to perform its function. * La guía de [Injección de dependencias](guide/dependency-injection) brinda información detallada sobre cómo construir una aplicación de modo que cada clase de componente pueda adquirir los servicios y objetos que necesita para realizar su función.
## Responsive programming ## Programación responsive
The **Components and Templates** guide provides guidance and details of the [template syntax](guide/template-syntax) that you use to display your component data when and where you want it within a view, and to collect input from users that you can respond to. La guía de **Componentes y Plantillas** brinda orientación y detalles de la [sintaxis de plantilla](guide/template-syntax) que se utilizan para mostrar la información de sus componentes, cuando y donde lo desees dentro de una vista y para obtener entradas (inputs) de los usuarios a las que puedas responder.
Additional pages and sections describe some basic programming techniques for Angular apps. Las páginas y secciones adicionales describen algunas técnicas básicas de programación para aplicaciones Angular.
* [Lifecycle hooks](guide/lifecycle-hooks): Tap into key moments in the lifetime of a component, from its creation to its destruction, by implementing the lifecycle hook interfaces. * [Lifecycle Hooks](guide/lifecycle-hooks): Aprovecha los momentos claves de la vida de un componente, desde su creación hasta su destrucción, implementando las interfaces de los `lifecycle hooks`.
* [Observables and event processing](guide/observables): How to use observables with components and services to publish and subscribe to messages of any type, such as user-interaction events and asynchronous operation results. * [Observables y procesamiento de eventos](guide/observables): Cómo utilizar observables con componentes y servicios para publicar y suscribirse a mensajes de cualquier tipo, tales como los eventos de interacción del usuario y los resultados de operaciones asincrónicas.
* [Angular elements](guide/elements): How to package components as *custom elements* using Web Components, a web standard for defining new HTML elements in a framework-agnostic way. * [Elementos Angular](guide/elements): Cómo empaquetar componentes como *elementos personalizados* utilizando Web Components, un estándar web para definir nuevos elementos HTML de una manera agnóstica a cualquier framework.
* [Forms](guide/forms-overview): Support complex data entry scenarios with HTML-based input validation. * [Formularios](guide/forms-overview): Soporta escenarios complejos de entrada de datos con validación de entradas (inputs) basadas en HTML.
* [Animations](guide/animations): Use Angular's animation library to animate component behavior * [Animaciones](guide/animations): Utiliza la librería de animación de Angular para animar el comportamiento de los componentes sin necesidad de conocer en profundidad las técnicas de animación o CSS.
without deep knowledge of animation techniques or CSS.
## Client-server interaction ## Interacción Cliente-Servidor
Angular provides a framework for single-page apps, where most of the logic and data resides on the client. Angular ofrece un framework para aplicaciones de una sola página (SPA), donde la mayoría de la lógica y los datos se encuentran en el cliente.
Most apps still need to access a server using the `HttpClient` to access and save data. La mayoría de las aplicaciones todavía necesitan acceder a un servidor usando el `HttpClient` para acceder y guardar datos.
For some platforms and applications, you might also want to use the PWA (Progressive Web App) model to improve the user experience. Para algunas plataformas y aplicaciones, se puede también querer utilizar el modelo PWA (Aplicaciones Web Progresivas) para mejorar la experiencia de usuario.
* [HTTP](guide/http): Communicate with a server to get data, save data, and invoke server-side actions with an HTTP client. * [HTTP](guide/http): Comunícate con un servidor para obtener datos, guardarlos e invocar acciones del lado del servidor con un cliente HTTP.
* [Server-side rendering](guide/universal): Angular Universal generates static application pages on the server through server-side rendering (SSR). This allows you to run your Angular app on the server in order to improve performance and show the first page quickly on mobile and low-powered devices, and also facilitate web crawlers. * [Renderizado del lado del servidor](guide/universal): Angular Universal genera páginas de aplicación estáticas en el servidor a través de la renderización del lado del servidor (SSR). Esto te permite ejecutar tu aplicación Angular en el servidor para mejorar el rendimiento y mostrar la primera página rápidamente en dispositivos móviles y de baja potencia, y también facilitar los rastreadores web.
* [Service workers and PWA](guide/service-worker-intro): Use a service worker to reduce dependency on the network and significantly improve the user experience. * [Service workers y PWA](guide/service-worker-intro): Utiliza un service worker para reducir la dependencia de la red y mejorar significativamente la experiencia del usuario.
* [Web workers](guide/web-worker): Learn how to run CPU-intensive computations in a background thread. * [Web workers](guide/web-worker): Aprende a ejecutar cálculos con uso intensivo de la CPU en un hilo en segundo plano.
## Support for the development cycle ## Soporte del Ciclo de Desarrollo
The **Development Workflow** section describes the tools and processes you use to compile, test, and deploy Angular applications. La sección **Workflow de Desarrollo** detalla las herramientas y los procesos utilizados para compilar, probar y desplegar aplicaciones Angular.
* [CLI Command Reference](cli): The Angular CLI is a command-line tool that you use to create projects, generate application and library code, and perform a variety of ongoing development tasks such as testing, bundling, and deployment. * [CLI Referencia de Comando](cli): La CLI de Angular es una interfaz de línea de comandos utilizada para crear proyectos, generar código de aplicaciones y librerías y realizar un conjunto de tareas de desarrollo tales como pruebas, empaquetamiento y despliegue de aplicaciones.
* [Compilation](guide/aot-compiler): Angular provides just-in-time (JIT) compilation for the development environment, and ahead-of-time (AOT) compilation for the production environment. * [Compilación](guide/aot-compiler): Angular proporciona compilación `just-in-time` (JIT) para el entorno de desarrollo y compilación `ahead-of-time` (AOT) para el entorno de producción.
* [Testing platform](guide/testing): Run unit tests on your application parts as they interact with the Angular framework. * [Plataforma de pruebas](guide/testing): Ejecuta pruebas unitarias sobre las distintas partes de tu aplicación a medida que interactúan con el framework de Angular.
* [Deployment](guide/deployment): Learn techniques for deploying your Angular application to a remote server. * [Despliegue](guide/deployment): Aprende técnicas para desplegar tu aplicación Angular en un servidor remoto.
* [Security guidelines](guide/security): Learn about Angular's built-in protections against common web-app vulnerabilities and attacks such as cross-site scripting attacks. * [Lineamientos de Seguridad](guide/security): Aprende sobre las protecciones integradas por Angular contra las vulnerabilidades y los ataques comunes a las aplicaciones web, como por ejemplo, ataques de cross-site scripting.
* [Internationalization](guide/i18n): Make your app available in multiple languages with Angular's internationalization (i18n) tools. * [Internacionalización](guide/i18n): Haz que tu aplicación soporte múltiples lenguajes con las herramientas de internacionalización de Angular (i18n).
* [Accessibility](guide/accessibility): Make your app accessible to all users. * [Accesibilidad](guide/accessibility): Haz que tu aplicación sea accesible a todos los usuarios.
## File structure, configuration, and dependencies ## Estructura de Archivos, Configuración y Dependencias
* [Workspace and file structure](guide/file-structure): Understand the structure of Angular workspace and project folders. * [Espacio de trabajo y estructura de archivos](guide/file-structure): Comprende la estructura del espacio de trabajo y las carpetas de proyectos en Angular.
* [Building and serving](guide/build): Learn to define different build and proxy server configurations for your project, such as development, staging, and production. * [Construcción y servicio](guide/build): Aprende a definir diferentes configuraciones de servidores proxy y construcción para tu proyecto, como por ejemplo desarrollo, staging y producción.
* [npm packages](guide/npm-packages): The Angular Framework, Angular CLI, and components used by Angular applications are packaged as [npm](https://docs.npmjs.com/) packages and distributed via the npm registry. The Angular CLI creates a default `package.json` file, which specifies a starter set of packages that work well together and jointly support many common application scenarios. * [Paquetes npm](guide/npm-packages): El Framework de Angular, la CLI de Angular y los componentes usados por las aplicaciones Angular se empaquetan como paquetes [npm](https://docs.npmjs.com/) y se distribuyen a través del registro de `npm`. La CLI de Angular crea por defecto un archivo `package.json`, que especifica un conjunto inicial de paquetes que funcionan bien en conjunto y dan soporte a muchos escenarios de aplicaciones comunes.
* [TypeScript configuration](guide/typescript-configuration): TypeScript is the primary language for Angular application development. * [Configuración de Typescript](guide/typescript-configuration): TypeScript es el lenguaje principal utilizado para el desarrollo de aplicaciones Angular.
* [Browser support](guide/browser-support): Make your apps compatible across a wide range of browsers. * [Soporte de Navegadores](guide/browser-support): Haz que tus aplicaciones sean compatibles en una amplia gama de navegadores.
## Extending Angular ## Extendiendo Angular
* [Angular libraries](guide/libraries): Learn about using and creating re-usable libraries. * [Librerías Angular](guide/libraries): Aprende a usar y crear librerías reutilizables.
* [Schematics](guide/schematics): Learn about customizing and extending the CLI's generation capabilities. * [Esquemas](guide/schematics): Aprende como personalizar y extender las capacidades de generación de la CLI.
* [CLI builders](guide/cli-builder): Learn about customizing and extending the CLI's ability to apply tools to perform complex tasks, such as building and testing applications. * [Constructores de la CLI](guide/cli-builder): Aprende a personalizar y extender la capacidad de la CLI de aplicar herramientas para realizar tareas complejas, como la construcción y pruebas de aplicaciones.

View File

@ -0,0 +1,116 @@
# Introduction to services and dependency injection
*Service* is a broad category encompassing any value, function, or feature that an app needs.
A service is typically a class with a narrow, well-defined purpose.
It should do something specific and do it well.
Angular distinguishes components from services to increase modularity and reusability.
By separating a component's view-related functionality from other kinds of processing,
you can make your component classes lean and efficient.
Ideally, a component's job is to enable the user experience and nothing more.
A component should present properties and methods for data binding,
in order to mediate between the view (rendered by the template)
and the application logic (which often includes some notion of a *model*).
A component can delegate certain tasks to services, such as fetching data from the server,
validating user input, or logging directly to the console.
By defining such processing tasks in an *injectable service class*, you make those tasks
available to any component.
You can also make your app more adaptable by injecting different providers of the same kind of service,
as appropriate in different circumstances.
Angular doesn't *enforce* these principles. Angular does help you *follow* these principles
by making it easy to factor your application logic into services and make those services
available to components through *dependency injection*.
## Service examples
Here's an example of a service class that logs to the browser console.
<code-example path="architecture/src/app/logger.service.ts" header="src/app/logger.service.ts (class)" region="class"></code-example>
Services can depend on other services. For example, here's a `HeroService` that depends on the `Logger` service, and also uses `BackendService` to get heroes. That service in turn might depend on the `HttpClient` service to fetch heroes asynchronously from a server.
<code-example path="architecture/src/app/hero.service.ts" header="src/app/hero.service.ts (class)" region="class"></code-example>
## Dependency injection (DI)
<img src="generated/images/guide/architecture/dependency-injection.png" alt="Service" class="left">
DI is wired into the Angular framework and used everywhere to provide new components with the services or other things they need.
Components consume services; that is, you can *inject* a service into a component, giving the component access to that service class.
To define a class as a service in Angular, use the `@Injectable()` decorator to provide the metadata that allows Angular to inject it into a component as a *dependency*.
Similarly, use the `@Injectable()` decorator to indicate that a component or other class (such as another service, a pipe, or an NgModule) *has* a dependency.
* The *injector* is the main mechanism. Angular creates an application-wide injector for you during the bootstrap process, and additional injectors as needed. You don't have to create injectors.
* An injector creates dependencies, and maintains a *container* of dependency instances that it reuses if possible.
* A *provider* is an object that tells an injector how to obtain or create a dependency.
For any dependency that you need in your app, you must register a provider with the app's injector,
so that the injector can use the provider to create new instances.
For a service, the provider is typically the service class itself.
<div class="alert is-helpful">
A dependency doesn't have to be a service&mdash;it could be a function, for example, or a value.
</div>
When Angular creates a new instance of a component class, it determines which services or other dependencies that component needs by looking at the constructor parameter types. For example, the constructor of `HeroListComponent` needs `HeroService`.
<code-example path="architecture/src/app/hero-list.component.ts" header="src/app/hero-list.component.ts (constructor)" region="ctor"></code-example>
When Angular discovers that a component depends on a service, it first checks if the injector has any existing instances of that service. If a requested service instance doesn't yet exist, the injector makes one using the registered provider, and adds it to the injector before returning the service to Angular.
When all requested services have been resolved and returned, Angular can call the component's constructor with those services as arguments.
The process of `HeroService` injection looks something like this.
<div class="lightbox">
<img src="generated/images/guide/architecture/injector-injects.png" alt="Service" class="left">
</div>
### Providing services
You must register at least one *provider* of any service you are going to use.
The provider can be part of the service's own metadata, making that service available everywhere,
or you can register providers with specific modules or components.
You register providers in the metadata of the service (in the `@Injectable()` decorator),
or in the `@NgModule()` or `@Component()` metadata
* By default, the Angular CLI command [`ng generate service`](cli/generate) registers a provider with the root injector for your service by including provider metadata in the `@Injectable()` decorator. The tutorial uses this method to register the provider of HeroService class definition.
```
@Injectable({
providedIn: 'root',
})
```
When you provide the service at the root level, Angular creates a single, shared instance of `HeroService`
and injects it into any class that asks for it.
Registering the provider in the `@Injectable()` metadata also allows Angular to optimize an app
by removing the service from the compiled app if it isn't used.
* When you register a provider with a [specific NgModule](guide/architecture-modules), the same instance of a service is available to all components in that NgModule. To register at this level, use the `providers` property of the `@NgModule()` decorator,
```
@NgModule({
providers: [
BackendService,
Logger
],
...
})
```
* When you register a provider at the component level, you get a new instance of the
service with each new instance of that component.
At the component level, register a service provider in the `providers` property of the `@Component()` metadata.
<code-example path="architecture/src/app/hero-list.component.ts" header="src/app/hero-list.component.ts (component providers)" region="providers"></code-example>
For more detailed information, see the [Dependency Injection](guide/dependency-injection) section.

View File

@ -1,88 +1,81 @@
# Introduction to services and dependency injection # Introducción a servicios e inyección de dependencias
*Service* is a broad category encompassing any value, function, or feature that an app needs. *Servicio* es una categoría amplia que abarca cualquier valor, función o característica que necesite una aplicación.
A service is typically a class with a narrow, well-defined purpose. Un servicio es típicamente una clase con un propósito limitado y bien definido.
It should do something specific and do it well. Debe hacer algo específico y hacerlo bien.
Angular distinguishes components from services to increase modularity and reusability. Angular distingue los componentes de los servicios para aumentar la modularidad y la reutilización.
By separating a component's view-related functionality from other kinds of processing, Al separar la funcionalidad relacionada con la vista de un componente de otros tipos de procesamiento, puedes hacer que tus componentes sean ágiles y eficientes.
you can make your component classes lean and efficient.
Ideally, a component's job is to enable the user experience and nothing more. Idealmente, el trabajo de un componente es permitir la experiencia del usuario y nada más.
A component should present properties and methods for data binding, Un componente debe presentar propiedades y métodos para el enlace de datos,
in order to mediate between the view (rendered by the template) para mediar entre la vista (representada por la plantilla)
and the application logic (which often includes some notion of a *model*). y la lógica de la aplicación (que a menudo incluye alguna noción de * modelo *).
A component can delegate certain tasks to services, such as fetching data from the server, Un componente puede delegar ciertas tareas a los servicios, como obtener datos del servidor, validar la entrada del usuario o registrar información directamente en la consola.
validating user input, or logging directly to the console. Al definir tales tareas de procesamiento en una * clase de servicio inyectable *, hace que esas tareas sean disponibles para cualquier componente.
By defining such processing tasks in an *injectable service class*, you make those tasks También puedes hacer que tu aplicación sea más adaptable inyectando diferentes proveedores del mismo tipo de servicio, según corresponda en diferentes circunstancias.
available to any component.
You can also make your app more adaptable by injecting different providers of the same kind of service,
as appropriate in different circumstances.
Angular doesn't *enforce* these principles. Angular does help you *follow* these principles Angular no * impone * estos principios. Angular te ayuda a * seguir * estos principios
by making it easy to factor your application logic into services and make those services al facilitar la integración de la lógica de tu aplicación en los servicios y hacer que esos servicios sean disponibles para los componentes a través de * inyección de dependencia *.
available to components through *dependency injection*.
## Service examples ## Ejemplos de servicios
Here's an example of a service class that logs to the browser console. A continuación, se muestra un ejemplo de una clase de servicio que registra información en la consola del navegador.
<code-example path="architecture/src/app/logger.service.ts" header="src/app/logger.service.ts (class)" region="class"></code-example> <code-example path="architecture/src/app/logger.service.ts" header="src/app/logger.service.ts (class)" region="class"></code-example>
Services can depend on other services. For example, here's a `HeroService` that depends on the `Logger` service, and also uses `BackendService` to get heroes. That service in turn might depend on the `HttpClient` service to fetch heroes asynchronously from a server. Los servicios pueden depender de otros servicios. Por ejemplo, hay un `HeroService` que depende del `Logger` service, y también usa `BackendService` para obtener héroes. Ese servicio, a su vez, podría depender del servicio `HttpClient` para buscar héroes de forma asíncrona desde un servidor.
<code-example path="architecture/src/app/hero.service.ts" header="src/app/hero.service.ts (class)" region="class"></code-example> <code-example path="architecture/src/app/hero.service.ts" header="src/app/hero.service.ts (class)" region="class"></code-example>
## Dependency injection (DI) ## Inyección de dependencia (ID)
<img src="generated/images/guide/architecture/dependency-injection.png" alt="Service" class="left"> <img src="generated/images/guide/architecture/dependency-injection.png" alt="Service" class="left">
DI is wired into the Angular framework and used everywhere to provide new components with the services or other things they need. Inyección de dependencia está conectado al framework de Angular y se usa en todas partes para proporcionar nuevos componentes con los servicios u otras cosas que necesitan.
Components consume services; that is, you can *inject* a service into a component, giving the component access to that service class. Los componentes consumen servicios; es decir, puede * inyectar * un servicio en un componente, dándole acceso al componente a ese servicio.
To define a class as a service in Angular, use the `@Injectable()` decorator to provide the metadata that allows Angular to inject it into a component as a *dependency*. Para definir una clase como un servicio en Angular, usa el decorador `@Injectable ()` para proporcionar los metadatos que le permitan a Angular inyectarlo en un componente como una * dependencia *.
Similarly, use the `@Injectable()` decorator to indicate that a component or other class (such as another service, a pipe, or an NgModule) *has* a dependency. De manera similar, usa el decorador `@Injectable()` para indicar que un componente u otra clase (como otro servicio, un pipeline o un NgModule) * tiene * una dependencia.
* The *injector* is the main mechanism. Angular creates an application-wide injector for you during the bootstrap process, and additional injectors as needed. You don't have to create injectors. * El * inyector * es el mecanismo principal. Angular crea un inyector para toda la aplicación durante el proceso de arranque e inyectores adicionales según sea necesario. No es necesario crear inyectores.
* An injector creates dependencies, and maintains a *container* of dependency instances that it reuses if possible. * Un inyector crea dependencias y mantiene un * contenedor * de instancias de dependencia que reutiliza si es posible.
* A *provider* is an object that tells an injector how to obtain or create a dependency. * Un * proveedor * es un objeto que le dice a un inyector cómo obtener o crear una dependencia.
For any dependency that you need in your app, you must register a provider with the app's injector, Para cualquier dependencia que necesites en tu aplicación, debes registrar un proveedor con el inyector de la aplicación, con el fin de que el inyector pueda utilizar el proveedor para crear nuevas instancias.
so that the injector can use the provider to create new instances. Para un servicio, el proveedor suele ser la propia clase de servicio.
For a service, the provider is typically the service class itself.
<div class="alert is-helpful"> <div class="alert is-helpful">
A dependency doesn't have to be a service&mdash;it could be a function, for example, or a value. Una dependencia no tiene que ser solamente un servicio&mdash;podría ser una función, por ejemplo, o un valor.
</div> </div>
When Angular creates a new instance of a component class, it determines which services or other dependencies that component needs by looking at the constructor parameter types. For example, the constructor of `HeroListComponent` needs `HeroService`. Cuando Angular crea una nueva instancia de una clase de componente, determina qué servicios u otras dependencias necesita ese componente al observar los tipos de parámetros del constructor. Por ejemplo, el constructor de `HeroListComponent` necesita `HeroService`.
<code-example path="architecture/src/app/hero-list.component.ts" header="src/app/hero-list.component.ts (constructor)" region="ctor"></code-example> <code-example path="architecture/src/app/hero-list.component.ts" header="src/app/hero-list.component.ts (constructor)" region="ctor"></code-example>
When Angular discovers that a component depends on a service, it first checks if the injector has any existing instances of that service. If a requested service instance doesn't yet exist, the injector makes one using the registered provider, and adds it to the injector before returning the service to Angular. Cuando Angular descubre que un componente depende de un servicio, primero verifica si el inyector tiene instancias existentes de ese servicio. Si una instancia de servicio solicitada aún no existe, el inyector crea una utilizando el proveedor registrado y la agrega al inyector antes de devolver el servicio a Angular.
When all requested services have been resolved and returned, Angular can call the component's constructor with those services as arguments. Cuando todos los servicios solicitados se han resuelto y devuelto, Angular puede llamar al constructor del componente con esos servicios como argumentos.
The process of `HeroService` injection looks something like this. El proceso de inyección de "HeroService" se parece a esto.
<div class="lightbox"> <div class="lightbox">
<img src="generated/images/guide/architecture/injector-injects.png" alt="Service" class="left"> <img src="generated/images/guide/architecture/injector-injects.png" alt="Service" class="left">
</div> </div>
### Providing services ### Proporcionar servicios
You must register at least one *provider* of any service you are going to use. Deberías registrar al menos un * proveedor * de cualquier servicio que vayas a utilizar.
The provider can be part of the service's own metadata, making that service available everywhere, El proveedor puede formar parte de los propios metadatos del servicio, haciendo que ese servicio esté disponible en todas partes, o puede registrar proveedores con módulos o componentes específicos.
or you can register providers with specific modules or components. Debes registrar proveedores en los metadatos del servicio (en el decorador `@Injectable()`),
You register providers in the metadata of the service (in the `@Injectable()` decorator), o en los metadatos `@NgModule()` o `@Component()`
or in the `@NgModule()` or `@Component()` metadata
* By default, the Angular CLI command [`ng generate service`](cli/generate) registers a provider with the root injector for your service by including provider metadata in the `@Injectable()` decorator. The tutorial uses this method to register the provider of HeroService class definition. * Por defecto, el comando CLI de Angular [`ng generate service`](cli/generate) registra un proveedor con el inyector raíz para tu servicio al incluir metadatos del proveedor en el decorador `@Injectable()`. El tutorial utiliza este método para registrar el proveedor de la definición de clase HeroService.
``` ```
@Injectable({ @Injectable({
@ -90,12 +83,10 @@ or in the `@NgModule()` or `@Component()` metadata
}) })
``` ```
When you provide the service at the root level, Angular creates a single, shared instance of `HeroService` Cuando proporcionas el servicio en el nivel raíz, Angular crea una instancia única compartida de `HeroService` y lo inyecta en cualquier clase que lo solicite.
and injects it into any class that asks for it. El registro del proveedor en los metadatos `@Injectable()` también permite a Angular optimizar una aplicación eliminando el servicio de la aplicación compilada si no se utiliza.
Registering the provider in the `@Injectable()` metadata also allows Angular to optimize an app
by removing the service from the compiled app if it isn't used.
* When you register a provider with a [specific NgModule](guide/architecture-modules), the same instance of a service is available to all components in that NgModule. To register at this level, use the `providers` property of the `@NgModule()` decorator, * Cuando registras un proveedor con un [NgModule específico](guide/architecture-modules), la misma instancia de un servicio está disponible para todos los componentes en ese NgModule. Para registrar en este nivel, usa la propiedad `Provider` del decorador `@NgModule()`.
``` ```
@NgModule({ @NgModule({
@ -107,10 +98,10 @@ or in the `@NgModule()` or `@Component()` metadata
}) })
``` ```
* When you register a provider at the component level, you get a new instance of the * Cuando registras un proveedor a nivel del componente, obtienes una nueva instancia del
service with each new instance of that component. servicio con cada nueva instancia de ese componente.
At the component level, register a service provider in the `providers` property of the `@Component()` metadata. A nivel del componente, registra un proveedor de servicios en la propiedad `Providers` de los metadatos `@Component()`.
<code-example path="architecture/src/app/hero-list.component.ts" header="src/app/hero-list.component.ts (component providers)" region="providers"></code-example> <code-example path="architecture/src/app/hero-list.component.ts" header="src/app/hero-list.component.ts (component providers)" region="providers"></code-example>
For more detailed information, see the [Dependency Injection](guide/dependency-injection) section. Para obtener información más detallada, consulta la sección [Inyección de dependencia](guide/dependency-injection).

View File

@ -0,0 +1,157 @@
# Introduction to Angular concepts
Angular is a platform and framework for building single-page client applications using HTML and TypeScript.
Angular is written in TypeScript.
It implements core and optional functionality as a set of TypeScript libraries that you import into your apps.
The architecture of an Angular application relies on certain fundamental concepts.
The basic building blocks are *NgModules*, which provide a compilation context for *components*. NgModules collect related code into functional sets; an Angular app is defined by a set of NgModules. An app always has at least a *root module* that enables bootstrapping, and typically has many more *feature modules*.
* Components define *views*, which are sets of screen elements that Angular can choose among and modify according to your program logic and data.
* Components use *services*, which provide specific functionality not directly related to views. Service providers can be *injected* into components as *dependencies*, making your code modular, reusable, and efficient.
Modules, components and services are classes that use *decorators*. These decorators mark their type and provide metadata that tells Angular how to use them.
* The metadata for a component class associates it with a *template* that defines a view. A template combines ordinary HTML with Angular *directives* and *binding markup* that allow Angular to modify the HTML before rendering it for display.
* The metadata for a service class provides the information Angular needs to make it available to components through *dependency injection (DI)*.
An app's components typically define many views, arranged hierarchically. Angular provides the `Router` service to help you define navigation paths among views. The router provides sophisticated in-browser navigational capabilities.
<div class="alert is-helpful">
See the [Angular Glossary](guide/glossary) for basic definitions of important Angular terms and usage.
</div>
<div class="alert is-helpful">
For the sample app that this page describes, see the <live-example></live-example>.
</div>
## Modules
Angular *NgModules* differ from and complement JavaScript (ES2015) modules. An NgModule declares a compilation context for a set of components that is dedicated to an application domain, a workflow, or a closely related set of capabilities. An NgModule can associate its components with related code, such as services, to form functional units.
Every Angular app has a *root module*, conventionally named `AppModule`, which provides the bootstrap mechanism that launches the application. An app typically contains many functional modules.
Like JavaScript modules, NgModules can import functionality from other NgModules, and allow their own functionality to be exported and used by other NgModules. For example, to use the router service in your app, you import the `Router` NgModule.
Organizing your code into distinct functional modules helps in managing development of complex applications, and in designing for reusability. In addition, this technique lets you take advantage of *lazy-loading*&mdash;that is, loading modules on demand&mdash;to minimize the amount of code that needs to be loaded at startup.
<div class="alert is-helpful">
For a more detailed discussion, see [Introduction to modules](guide/architecture-modules).
</div>
## Components
Every Angular application has at least one component, the *root component* that connects a component hierarchy with the page document object model (DOM). Each component defines a class that contains application data and logic, and is associated with an HTML *template* that defines a view to be displayed in a target environment.
The `@Component()` decorator identifies the class immediately below it as a component, and provides the template and related component-specific metadata.
<div class="alert is-helpful">
Decorators are functions that modify JavaScript classes. Angular defines a number of decorators that attach specific kinds of metadata to classes, so that the system knows what those classes mean and how they should work.
<a href="https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841#.x5c2ndtx0">Learn more about decorators on the web.</a>
</div>
### Templates, directives, and data binding
A template combines HTML with Angular markup that can modify HTML elements before they are displayed.
Template *directives* provide program logic, and *binding markup* connects your application data and the DOM.
There are two types of data binding:
* *Event binding* lets your app respond to user input in the target environment by updating your application data.
* *Property binding* lets you interpolate values that are computed from your application data into the HTML.
Before a view is displayed, Angular evaluates the directives and resolves the binding syntax in the template to modify the HTML elements and the DOM, according to your program data and logic. Angular supports *two-way data binding*, meaning that changes in the DOM, such as user choices, are also reflected in your program data.
Your templates can use *pipes* to improve the user experience by transforming values for display.
For example, use pipes to display dates and currency values that are appropriate for a user's locale.
Angular provides predefined pipes for common transformations, and you can also define your own pipes.
<div class="alert is-helpful">
For a more detailed discussion of these concepts, see [Introduction to components](guide/architecture-components).
</div>
{@a dependency-injection}
## Services and dependency injection
For data or logic that isn't associated with a specific view, and that you want to share across components, you create a *service* class. A service class definition is immediately preceded by the `@Injectable()` decorator. The decorator provides the metadata that allows other providers to be **injected** as dependencies into your class.
*Dependency injection* (DI) lets you keep your component classes lean and efficient. They don't fetch data from the server, validate user input, or log directly to the console; they delegate such tasks to services.
<div class="alert is-helpful">
For a more detailed discussion, see [Introduction to services and DI](guide/architecture-services).
</div>
### Routing
The Angular `Router` NgModule provides a service that lets you define a navigation path among the different application states and view hierarchies in your app. It is modeled on the familiar browser navigation conventions:
* Enter a URL in the address bar and the browser navigates to a corresponding page.
* Click links on the page and the browser navigates to a new page.
* Click the browser's back and forward buttons and the browser navigates backward and forward through the history of pages you've seen.
The router maps URL-like paths to views instead of pages. When a user performs an action, such as clicking a link, that would load a new page in the browser, the router intercepts the browser's behavior, and shows or hides view hierarchies.
If the router determines that the current application state requires particular functionality, and the module that defines it hasn't been loaded, the router can *lazy-load* the module on demand.
The router interprets a link URL according to your app's view navigation rules and data state. You can navigate to new views when the user clicks a button or selects from a drop box, or in response to some other stimulus from any source. The router logs activity in the browser's history, so the back and forward buttons work as well.
To define navigation rules, you associate *navigation paths* with your components. A path uses a URL-like syntax that integrates your program data, in much the same way that template syntax integrates your views with your program data. You can then apply program logic to choose which views to show or to hide, in response to user input and your own access rules.
<div class="alert is-helpful">
For a more detailed discussion, see [Routing and navigation](guide/router).
</div>
<hr/>
## What's next
You've learned the basics about the main building blocks of an Angular application. The following diagram shows how these basic pieces are related.
<div class="lightbox">
<img src="generated/images/guide/architecture/overview2.png" alt="overview">
</div>
* Together, a component and template define an Angular view.
* A decorator on a component class adds the metadata, including a pointer to the associated template.
* Directives and binding markup in a component's template modify views based on program data and logic.
* The dependency injector provides services to a component, such as the router service that lets you define navigation among views.
Each of these subjects is introduced in more detail in the following pages.
* [Introduction to Modules](guide/architecture-modules)
* [Introduction to Components](guide/architecture-components)
* [Templates and views](guide/architecture-components#templates-and-views)
* [Component metadata](guide/architecture-components#component-metadata)
* [Data binding](guide/architecture-components#data-binding)
* [Directives](guide/architecture-components#directives)
* [Pipes](guide/architecture-components#pipes)
* [Introduction to services and dependency injection](guide/architecture-services)
When you're familiar with these fundamental building blocks, you can explore them in more detail in the documentation. To learn about more tools and techniques that are available to help you build and deploy Angular applications, see [Next steps: tools and techniques](guide/architecture-next-steps).
</div>

View File

@ -1,157 +1,157 @@
# Introduction to Angular concepts # Introducción a los conceptos de Angular
Angular is a platform and framework for building single-page client applications using HTML and TypeScript. Angular es una plataforma y un framework para crear aplicaciones de una sola página en el lado del cliente usando HTML y TypeScript.
Angular is written in TypeScript. Angular está escrito en TypeScript.
It implements core and optional functionality as a set of TypeScript libraries that you import into your apps. Implementa la funcionalidad básica y opcional como un conjunto de bibliotecas TypeScript que importas en tus aplicaciones.
The architecture of an Angular application relies on certain fundamental concepts. La arquitectura de una aplicación en Angular se basa en ciertos conceptos fundamentales.
The basic building blocks are *NgModules*, which provide a compilation context for *components*. NgModules collect related code into functional sets; an Angular app is defined by a set of NgModules. An app always has at least a *root module* that enables bootstrapping, and typically has many more *feature modules*. Los bloques de construcción básicos son los *NgModules*, que proporcionan un contexto de compilación para los *componentes*. Los NgModules recopilan código relacionado en conjuntos funcionales; una aplicación de Angular se define por un conjunto de NgModules. Una aplicación siempre tiene al menos un *módulo raíz* que permite el arranque y generalmente tiene muchos más *módulos de funcionalidad*.
* Components define *views*, which are sets of screen elements that Angular can choose among and modify according to your program logic and data. * Los componentes definen *vistas*, que son conjuntos de elementos de la pantalla que Angular puede elegir y modificar de acuerdo con la lógica y los datos de tu programa.
* Components use *services*, which provide specific functionality not directly related to views. Service providers can be *injected* into components as *dependencies*, making your code modular, reusable, and efficient. * Los componentes usan *servicios*, los cuales proporcionan una funcionalidad específica que no está directamente relacionada con las vistas. Los proveedores de servicios pueden *inyectarse* en componentes como *dependencias*, haciendo que tu código sea modular, reutilizable y eficiente.
Modules, components and services are classes that use *decorators*. These decorators mark their type and provide metadata that tells Angular how to use them. Los módulos, componentes y servicios son clases que usan *decoradores*. Estos decoradores indican su tipo y proporcionan metadatos que le indican a Angular cómo usarlos.
* The metadata for a component class associates it with a *template* that defines a view. A template combines ordinary HTML with Angular *directives* and *binding markup* that allow Angular to modify the HTML before rendering it for display. * Los metadatos para una clase componente son asociados con una *plantilla* que define una vista. Una plantilla combina HTML ordinario con *directivas* de Angular y *enlace markup* que permiten a Angular modificar el HTML antes de mostrarlo para su visualización.
* The metadata for a service class provides the information Angular needs to make it available to components through *dependency injection (DI)*. * Los metadatos para una clase servicio proporcionan la información que Angular necesita para que esté disponible para los componentes a través de la *Inyección de Dependencia (ID)*.
An app's components typically define many views, arranged hierarchically. Angular provides the `Router` service to help you define navigation paths among views. The router provides sophisticated in-browser navigational capabilities. Los componentes de una aplicación suelen definir muchas vistas, ordenadas jerárquicamente. Angular proporciona el servicio `Router` para ayudarte a definir rutas de navegación entre vistas. El enrutador proporciona capacidades de navegación sofisticadas en el navegador.
<div class="alert is-helpful"> <div class="alert is-helpful">
See the [Angular Glossary](guide/glossary) for basic definitions of important Angular terms and usage. Visita el [Glosario de Angular](guide/glossary) para ver las definiciones básicas de términos importantes en Angular y su uso.
</div> </div>
<div class="alert is-helpful"> <div class="alert is-helpful">
For the sample app that this page describes, see the <live-example></live-example>. Para ver la aplicación de ejemplo que describe esta página, consulta el <live-example>ejemplo</live-example>.
</div> </div>
## Modules ## Módulos
Angular *NgModules* differ from and complement JavaScript (ES2015) modules. An NgModule declares a compilation context for a set of components that is dedicated to an application domain, a workflow, or a closely related set of capabilities. An NgModule can associate its components with related code, such as services, to form functional units. Los *NgModules* de Angular difieren y complementan los módulos JavaScript (ES2015). Un NgModule declara un contexto de compilación para un conjunto de componentes que está dedicado a un dominio de aplicación, un flujo de trabajo o un conjunto de capacidades estrechamente relacionadas. Un NgModule puede asociar sus componentes con código relacionado, como servicios, para formar unidades funcionales.
Every Angular app has a *root module*, conventionally named `AppModule`, which provides the bootstrap mechanism that launches the application. An app typically contains many functional modules. Cada aplicación en Angular tiene un *módulo raíz*, convencionalmente nombrado `AppModule`, que proporciona el mecanismo de arranque que inicia la aplicación. Una aplicación generalmente contiene muchos módulos funcionales.
Like JavaScript modules, NgModules can import functionality from other NgModules, and allow their own functionality to be exported and used by other NgModules. For example, to use the router service in your app, you import the `Router` NgModule. Como en los módulos de JavaScript, los NgModules pueden importar la funcionalidad de otros, y permiten que su propia funcionalidad sea exportada y utilizada por otros NgModules. Por ejemplo, para utilizar el servicio de enrutamiento en su aplicación, importa el NgModule `Router`.
Organizing your code into distinct functional modules helps in managing development of complex applications, and in designing for reusability. In addition, this technique lets you take advantage of *lazy-loading*&mdash;that is, loading modules on demand&mdash;to minimize the amount of code that needs to be loaded at startup. Organizar tu código en distintos módulos funcionales ayuda a gestionar el desarrollo de aplicaciones complejas, y en el diseño para su reutilización. Además, esta técnica te permite aprovechar la *carga diferida*&mdash;es decir, cargar módulos bajo demanda&mdash;para minimizar la cantidad de código que debe cargarse al inicio.
<div class="alert is-helpful"> <div class="alert is-helpful">
For a more detailed discussion, see [Introduction to modules](guide/architecture-modules). Para más información, visita [Introducción a los módulos](guide/architecture-modules).
</div> </div>
## Components ## Componentes
Every Angular application has at least one component, the *root component* that connects a component hierarchy with the page document object model (DOM). Each component defines a class that contains application data and logic, and is associated with an HTML *template* that defines a view to be displayed in a target environment. Cada aplicación de Angular tiene al menos un componente, el *componente raíz* que conecta una jerarquía de componentes con el modelo de objetos del documento de la página (DOM). Cada componente define una clase que contiene datos y lógica de la aplicación, y está asociado con una *plantilla* HTML que define una vista que se mostrará en un entorno de destino.
The `@Component()` decorator identifies the class immediately below it as a component, and provides the template and related component-specific metadata. El decorador `@Component()` identifica la clase inmediatamente debajo de ella como un componente, y proporciona la plantilla y los metadatos específicos del componente relacionado.
<div class="alert is-helpful"> <div class="alert is-helpful">
Decorators are functions that modify JavaScript classes. Angular defines a number of decorators that attach specific kinds of metadata to classes, so that the system knows what those classes mean and how they should work. Los decoradores son funciones que modifican las clases de JavaScript. Angular define una serie de decoradores que adjuntan tipos específicos de metadatos a las clases, para que el sistema sepa qué significan esas clases y cómo deberían funcionar.
<a href="https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841#.x5c2ndtx0">Learn more about decorators on the web.</a> <a href="https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841#.x5c2ndtx0">Obten más información sobre decoradores en la web.</a>
</div> </div>
### Templates, directives, and data binding ### Plantillas, directivas y enlace de datos
A template combines HTML with Angular markup that can modify HTML elements before they are displayed. Una plantilla combina HTML con markup de Angular que puede modificar elementos HTML antes de que se muestren.
Template *directives* provide program logic, and *binding markup* connects your application data and the DOM. Las *directivas* de la plantilla proporcionan la lógica de programa y el *enlace markup* conecta los datos de tu aplicación y el DOM.
There are two types of data binding: Hay dos tipos de enlace de datos:
* *Event binding* lets your app respond to user input in the target environment by updating your application data. * *Manejador de eventos* permite que tu aplicación responda a la entrada del usuario en el entorno objetivo actualizando los datos de tu aplicación.
* *Property binding* lets you interpolate values that are computed from your application data into the HTML. * *Vincular propiedades* te permite interpolar valores que se calculan a partir de los datos de tu aplicación en HTML.
Before a view is displayed, Angular evaluates the directives and resolves the binding syntax in the template to modify the HTML elements and the DOM, according to your program data and logic. Angular supports *two-way data binding*, meaning that changes in the DOM, such as user choices, are also reflected in your program data. Antes de mostrar una vista, Angular evalúa las directivas y resuelve la sintaxis de enlace en la plantilla para modificar los elementos HTML y el DOM, de acuerdo con los datos y la lógica de tu programa. Angular soporta *enlace de datos en dos sentidos*, lo que significa que los cambios en el DOM, como las elecciones del usuario, también se reflejan en los datos de su programa.
Your templates can use *pipes* to improve the user experience by transforming values for display. Tus plantillas pueden usar *pipes* para mejorar la experiencia del usuario mediante la transformación de valores para mostrar.
For example, use pipes to display dates and currency values that are appropriate for a user's locale. Por ejemplo, usa pipes para mostrar fechas y valores de moneda que sean apropiados para la configuración regional de un usuario.
Angular provides predefined pipes for common transformations, and you can also define your own pipes. Angular proporciona pipes predefinidas para transformaciones comunes, y también puedes definir tus propias pipes.
<div class="alert is-helpful"> <div class="alert is-helpful">
For a more detailed discussion of these concepts, see [Introduction to components](guide/architecture-components). Para más información sobre estos conceptos, visita [Introducción a los componentes](guide/architecture-components).
</div> </div>
{@a dependency-injection} {@a dependency-injection}
## Services and dependency injection ## Servicios e inyección de dependencia
For data or logic that isn't associated with a specific view, and that you want to share across components, you create a *service* class. A service class definition is immediately preceded by the `@Injectable()` decorator. The decorator provides the metadata that allows other providers to be **injected** as dependencies into your class. Para los datos o la lógica que no están asociados con una vista específica y que deseas compartir entre componentes, crea una clase *servicio*. Una definición de clase servicio está inmediatamente precedida por el decorador `@Injectable()`. El decorador proporciona los metadatos que permiten **inyectar** otros proveedores como dependencias en su clase.
*Dependency injection* (DI) lets you keep your component classes lean and efficient. They don't fetch data from the server, validate user input, or log directly to the console; they delegate such tasks to services. *Inyección de Dependecia* (ID) te permite mantener sus clases componente ligeras y eficientes. No obtienen datos del servidor, validan la entrada del usuario o registra directamente en la consola; tales tareas son delegadas a los servicios.
<div class="alert is-helpful"> <div class="alert is-helpful">
For a more detailed discussion, see [Introduction to services and DI](guide/architecture-services). Para más información, visita [Introducción a los servicios e inyección de dependencia](guide/architecture-services).
</div> </div>
### Routing ### Enrutamiento
The Angular `Router` NgModule provides a service that lets you define a navigation path among the different application states and view hierarchies in your app. It is modeled on the familiar browser navigation conventions: El NgModule `Router` de Angular proporciona un servicio que te permite definir una ruta de navegación entre los diferentes estados de la aplicación y ver sus jerarquías. Se basa en las convenciones frecuentes de navegación del navegador:
* Enter a URL in the address bar and the browser navigates to a corresponding page. * Ingresa una URL en la barra de direcciones para que el navegador vaya a la página correspondiente.
* Click links on the page and the browser navigates to a new page. * Haz clic en los enlaces de la página para que el navegador vaya a una nueva página.
* Click the browser's back and forward buttons and the browser navigates backward and forward through the history of pages you've seen. * Haz clic en los botones atrás y adelante del navegador para que el navegador vaya hacia atrás y hacia adelante a través del historial de las páginas que has visto.
The router maps URL-like paths to views instead of pages. When a user performs an action, such as clicking a link, that would load a new page in the browser, the router intercepts the browser's behavior, and shows or hides view hierarchies. El enrutador mapea rutas similares a URL para las vistas en lugar de páginas. Cuando un usuario realiza una acción, como hacer clic en un enlace, que cargaría una nueva página en el navegador, el enrutador intercepta el comportamiento del navegador y muestra u oculta las jerarquías de vista.
If the router determines that the current application state requires particular functionality, and the module that defines it hasn't been loaded, the router can *lazy-load* the module on demand. Si el enrutador determina que el estado actual de la aplicación requiere una funcionalidad particular, y el módulo que lo define no se ha cargado, el enrutador puede hacer *cargar diferida* sobre el módulo bajo demanda.
The router interprets a link URL according to your app's view navigation rules and data state. You can navigate to new views when the user clicks a button or selects from a drop box, or in response to some other stimulus from any source. The router logs activity in the browser's history, so the back and forward buttons work as well. El enrutador interpreta una URL de enlace de acuerdo con las reglas de navegación de visualización de la aplicación y el estado de los datos. Puedes navegar a las nuevas vistas cuando el usuario hace clic en un botón o selecciona desde un cuadro desplegable, o en respuesta a algún otro estímulo de cualquier fuente. El enrutador registra la actividad en el historial del navegador, por lo que los botones de retroceso y avance también funcionan.
To define navigation rules, you associate *navigation paths* with your components. A path uses a URL-like syntax that integrates your program data, in much the same way that template syntax integrates your views with your program data. You can then apply program logic to choose which views to show or to hide, in response to user input and your own access rules. Para definir reglas de navegación, asocia *rutas de navegación* a tus componentes. Una ruta utiliza una sintaxis similar a una URL que integra los datos de tu programa, de la misma manera que la sintaxis de la plantilla integra tus vistas con los datos de tu programa. Luego puedes aplicar la lógica del programa para elegir qué vistas mostrar u ocultar, en respuesta a la entrada del usuario y a tus propias reglas de acceso.
<div class="alert is-helpful"> <div class="alert is-helpful">
For a more detailed discussion, see [Routing and navigation](guide/router). Para más información, visita [Enrutamiento y navegación](guide/router).
</div> </div>
<hr/> <hr/>
## What's next ## ¿Qué sigue?
You've learned the basics about the main building blocks of an Angular application. The following diagram shows how these basic pieces are related. Has aprendido los conceptos básicos sobre los bloques de construcción de una aplicación en Angular. El siguiente diagrama muestra cómo se relacionan estos conceptos básicos.
<div class="lightbox"> <div class="lightbox">
<img src="generated/images/guide/architecture/overview2.png" alt="overview"> <img src="generated/images/guide/architecture/overview2.png" alt="overview">
</div> </div>
* Together, a component and template define an Angular view. * Juntos, un componente y una plantilla definen una vista en Angular.
* A decorator on a component class adds the metadata, including a pointer to the associated template. * Un decorador en una clase componente agrega los metadatos, incluido un apuntador a la plantilla asociada.
* Directives and binding markup in a component's template modify views based on program data and logic. * Las directivas y el enlace markup en la plantilla de un componente modifican las vistas basadas en los datos y la lógica del programa.
* The dependency injector provides services to a component, such as the router service that lets you define navigation among views. * El inyector de dependencia proporciona servicios a un componente, como el servicio de enrutamiento que le permite definir la navegación entre vistas.
Each of these subjects is introduced in more detail in the following pages. Cada uno de estos temas se presenta con más detalle en las siguientes páginas.
* [Introduction to Modules](guide/architecture-modules) * [Introducción a los Módulos](guide/architecture-modules)
* [Introduction to Components](guide/architecture-components) * [Introducción a los Componentes](guide/architecture-components)
* [Templates and views](guide/architecture-components#templates-and-views) * [Plantillas y Vistas](guide/architecture-components#templates-and-views)
* [Component metadata](guide/architecture-components#component-metadata) * [Metadatos de Componentes](guide/architecture-components#component-metadata)
* [Data binding](guide/architecture-components#data-binding) * [Enlace de Datos](guide/architecture-components#data-binding)
* [Directives](guide/architecture-components#directives) * [Directivas](guide/architecture-components#directives)
* [Pipes](guide/architecture-components#pipes) * [Pipes](guide/architecture-components#pipes)
* [Introduction to services and dependency injection](guide/architecture-services) * [Introducción a los Servicios e Inyección de Dependencias.](guide/architecture-services)
When you're familiar with these fundamental building blocks, you can explore them in more detail in the documentation. To learn about more tools and techniques that are available to help you build and deploy Angular applications, see [Next steps: tools and techniques](guide/architecture-next-steps). Cuando estés familiarizado con estos bloques de construcción fundamentales, podrás explorarlos con más detalle en la documentación. Para saber más acerca de las herramientas y técnicas disponibles para ayudarte a crear y desplegar aplicaciones de Angular, visita [Próximos pasos: herramientas y técnicas](guide/architecture-next-steps).
</div> </div>

View File

@ -0,0 +1,303 @@
# Attribute, class, and style bindings
The template syntax provides specialized one-way bindings for scenarios less well-suited to property binding.
<div class="alert is-helpful">
See the <live-example></live-example> for a working example containing the code snippets in this guide.
</div>
## Attribute binding
Set the value of an attribute directly with an **attribute binding**. This is the only exception to the rule that a binding sets a target property and the only binding that creates and sets an attribute.
Usually, setting an element property with a [property binding](guide/property-binding)
is preferable to setting the attribute with a string. However, sometimes
there is no element property to bind, so attribute binding is the solution.
Consider the [ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) and
[SVG](https://developer.mozilla.org/en-US/docs/Web/SVG). They are purely attributes, don't correspond to element properties, and don't set element properties. In these cases, there are no property targets to bind to.
Attribute binding syntax resembles property binding, but
instead of an element property between brackets, start with the prefix `attr`,
followed by a dot (`.`), and the name of the attribute.
You then set the attribute value, using an expression that resolves to a string,
or remove the attribute when the expression resolves to `null`.
One of the primary use cases for attribute binding
is to set ARIA attributes, as in this example:
<code-example path="attribute-binding/src/app/app.component.html" region="attrib-binding-aria" header="src/app/app.component.html"></code-example>
{@a colspan}
<div class="alert is-helpful">
#### `colspan` and `colSpan`
Notice the difference between the `colspan` attribute and the `colSpan` property.
If you wrote something like this:
<code-example language="html">
&lt;tr&gt;&lt;td colspan="{{1 + 1}}"&gt;Three-Four&lt;/td&gt;&lt;/tr&gt;
</code-example>
You'd get this error:
<code-example language="bash">
Template parse errors:
Can't bind to 'colspan' since it isn't a known native property
</code-example>
As the message says, the `<td>` element does not have a `colspan` property. This is true
because `colspan` is an attribute&mdash;`colSpan`, with a capital `S`, is the
corresponding property. Interpolation and property binding can set only *properties*, not attributes.
Instead, you'd use property binding and write it like this:
<code-example path="attribute-binding/src/app/app.component.html" region="colSpan" header="src/app/app.component.html"></code-example>
</div>
<hr/>
{@a class-binding}
## Class binding
Here's how to set the `class` attribute without a binding in plain HTML:
```html
<!-- standard class attribute setting -->
<div class="foo bar">Some text</div>
```
You can also add and remove CSS class names from an element's `class` attribute with a **class binding**.
To create a single class binding, start with the prefix `class` followed by a dot (`.`) and the name of the CSS class (for example, `[class.foo]="hasFoo"`).
Angular adds the class when the bound expression is truthy, and it removes the class when the expression is falsy (with the exception of `undefined`, see [styling delegation](#styling-delegation)).
To create a binding to multiple classes, use a generic `[class]` binding without the dot (for example, `[class]="classExpr"`).
The expression can be a space-delimited string of class names, or you can format it as an object with class names as the keys and truthy/falsy expressions as the values.
With object format, Angular will add a class only if its associated value is truthy.
It's important to note that with any object-like expression (`object`, `Array`, `Map`, `Set`, etc), the identity of the object must change for the class list to be updated.
Updating the property without changing object identity will have no effect.
If there are multiple bindings to the same class name, conflicts are resolved using [styling precedence](#styling-precedence).
<style>
td, th {vertical-align: top}
</style>
<table width="100%">
<col width="15%">
</col>
<col width="20%">
</col>
<col width="35%">
</col>
<col width="30%">
</col>
<tr>
<th>
Binding Type
</th>
<th>
Syntax
</th>
<th>
Input Type
</th>
<th>
Example Input Values
</th>
</tr>
<tr>
<td>Single class binding</td>
<td><code>[class.foo]="hasFoo"</code></td>
<td><code>boolean | undefined | null</code></td>
<td><code>true</code>, <code>false</code></td>
</tr>
<tr>
<td rowspan=3>Multi-class binding</td>
<td rowspan=3><code>[class]="classExpr"</code></td>
<td><code>string</code></td>
<td><code>"my-class-1 my-class-2 my-class-3"</code></td>
</tr>
<tr>
<td><code>{[key: string]: boolean | undefined | null}</code></td>
<td><code>{foo: true, bar: false}</code></td>
</tr>
<tr>
<td><code>Array</code><<code>string</code>></td>
<td><code>['foo', 'bar']</code></td>
</tr>
</table>
The [NgClass](guide/built-in-directives/#ngclass) directive can be used as an alternative to direct `[class]` bindings.
However, using the above class binding syntax without `NgClass` is preferred because due to improvements in class binding in Angular, `NgClass` no longer provides significant value, and might eventually be removed in the future.
<hr/>
## Style binding
Here's how to set the `style` attribute without a binding in plain HTML:
```html
<!-- standard style attribute setting -->
<div style="color: blue">Some text</div>
```
You can also set styles dynamically with a **style binding**.
To create a single style binding, start with the prefix `style` followed by a dot (`.`) and the name of the CSS style property (for example, `[style.width]="width"`).
The property will be set to the value of the bound expression, which is normally a string.
Optionally, you can add a unit extension like `em` or `%`, which requires a number type.
<div class="alert is-helpful">
Note that a _style property_ name can be written in either
[dash-case](guide/glossary#dash-case), as shown above, or
[camelCase](guide/glossary#camelcase), such as `fontSize`.
</div>
If there are multiple styles you'd like to toggle, you can bind to the `[style]` property directly without the dot (for example, `[style]="styleExpr"`).
The expression attached to the `[style]` binding is most often a string list of styles like `"width: 100px; height: 100px;"`.
You can also format the expression as an object with style names as the keys and style values as the values, like `{width: '100px', height: '100px'}`.
It's important to note that with any object-like expression (`object`, `Array`, `Map`, `Set`, etc), the identity of the object must change for the class list to be updated.
Updating the property without changing object identity will have no effect.
If there are multiple bindings to the same style property, conflicts are resolved using [styling precedence rules](#styling-precedence).
<style>
td, th {vertical-align: top}
</style>
<table width="100%">
<col width="15%">
</col>
<col width="20%">
</col>
<col width="35%">
</col>
<col width="30%">
</col>
<tr>
<th>
Binding Type
</th>
<th>
Syntax
</th>
<th>
Input Type
</th>
<th>
Example Input Values
</th>
</tr>
<tr>
<td>Single style binding</td>
<td><code>[style.width]="width"</code></td>
<td><code>string | undefined | null</code></td>
<td><code>"100px"</code></td>
</tr>
<tr>
<tr>
<td>Single style binding with units</td>
<td><code>[style.width.px]="width"</code></td>
<td><code>number | undefined | null</code></td>
<td><code>100</code></td>
</tr>
<tr>
<td rowspan=3>Multi-style binding</td>
<td rowspan=3><code>[style]="styleExpr"</code></td>
<td><code>string</code></td>
<td><code>"width: 100px; height: 100px"</code></td>
</tr>
<tr>
<td><code>{[key: string]: string | undefined | null}</code></td>
<td><code>{width: '100px', height: '100px'}</code></td>
</tr>
<tr>
<td><code>Array</code><<code>string</code>></td>
<td><code>['width', '100px']</code></td>
</tr>
</table>
The [NgStyle](guide/built-in-directives/#ngstyle) directive can be used as an alternative to direct `[style]` bindings.
However, using the above style binding syntax without `NgStyle` is preferred because due to improvements in style binding in Angular, `NgStyle` no longer provides significant value, and might eventually be removed in the future.
<hr/>
{@a styling-precedence}
## Styling Precedence
A single HTML element can have its CSS class list and style values bound to multiple sources (for example, host bindings from multiple directives).
When there are multiple bindings to the same class name or style property, Angular uses a set of precedence rules to resolve conflicts and determine which classes or styles are ultimately applied to the element.
<div class="alert is-helpful">
<h4>Styling precedence (highest to lowest)</h4>
1. Template bindings
1. Property binding (for example, `<div [class.foo]="hasFoo">` or `<div [style.color]="color">`)
1. Map binding (for example, `<div [class]="classExpr">` or `<div [style]="styleExpr">`)
1. Static value (for example, `<div class="foo">` or `<div style="color: blue">`)
1. Directive host bindings
1. Property binding (for example, `host: {'[class.foo]': 'hasFoo'}` or `host: {'[style.color]': 'color'}`)
1. Map binding (for example, `host: {'[class]': 'classExpr'}` or `host: {'[style]': 'styleExpr'}`)
1. Static value (for example, `host: {'class': 'foo'}` or `host: {'style': 'color: blue'}`)
1. Component host bindings
1. Property binding (for example, `host: {'[class.foo]': 'hasFoo'}` or `host: {'[style.color]': 'color'}`)
1. Map binding (for example, `host: {'[class]': 'classExpr'}` or `host: {'[style]': 'styleExpr'}`)
1. Static value (for example, `host: {'class': 'foo'}` or `host: {'style': 'color: blue'}`)
</div>
The more specific a class or style binding is, the higher its precedence.
A binding to a specific class (for example, `[class.foo]`) will take precedence over a generic `[class]` binding, and a binding to a specific style (for example, `[style.bar]`) will take precedence over a generic `[style]` binding.
<code-example path="attribute-binding/src/app/app.component.html" region="basic-specificity" header="src/app/app.component.html"></code-example>
Specificity rules also apply when it comes to bindings that originate from different sources.
It's possible for an element to have bindings in the template where it's declared, from host bindings on matched directives, and from host bindings on matched components.
Template bindings are the most specific because they apply to the element directly and exclusively, so they have the highest precedence.
Directive host bindings are considered less specific because directives can be used in multiple locations, so they have a lower precedence than template bindings.
Directives often augment component behavior, so host bindings from components have the lowest precedence.
<code-example path="attribute-binding/src/app/app.component.html" region="source-specificity" header="src/app/app.component.html"></code-example>
In addition, bindings take precedence over static attributes.
In the following case, `class` and `[class]` have similar specificity, but the `[class]` binding will take precedence because it is dynamic.
<code-example path="attribute-binding/src/app/app.component.html" region="dynamic-priority" header="src/app/app.component.html"></code-example>
{@a styling-delegation}
### Delegating to styles with lower precedence
It is possible for higher precedence styles to "delegate" to lower precedence styles using `undefined` values.
Whereas setting a style property to `null` ensures the style is removed, setting it to `undefined` will cause Angular to fall back to the next-highest precedence binding to that style.
For example, consider the following template:
<code-example path="attribute-binding/src/app/app.component.html" region="style-delegation" header="src/app/app.component.html"></code-example>
Imagine that the `dirWithHostBinding` directive and the `comp-with-host-binding` component both have a `[style.width]` host binding.
In that case, if `dirWithHostBinding` sets its binding to `undefined`, the `width` property will fall back to the value of the `comp-with-host-binding` host binding.
However, if `dirWithHostBinding` sets its binding to `null`, the `width` property will be removed entirely.

View File

@ -1,33 +1,28 @@
# Attribute, class, and style bindings # Enlaces de atributos, clases y estilos
The template syntax provides specialized one-way bindings for scenarios less well-suited to property binding. La sintaxis de la plantilla proporciona enlaces one-way especializados para escenarios menos adecuados para el enlace de propiedades.
<div class="alert is-helpful"> <div class="alert is-helpful">
See the <live-example></live-example> for a working example containing the code snippets in this guide. Consulta el <live-example></live-example> para ver un ejemplo práctico que contiene los fragmentos de código de esta guía.
</div> </div>
## Attribute binding ## Enlace de atributo
Set the value of an attribute directly with an **attribute binding**. This is the only exception to the rule that a binding sets a target property and the only binding that creates and sets an attribute. Establece el valor de un atributo directamente con un **enlace de atributo**. Esta es la única excepción a la regla de que un enlace establece una propiedad de destino y el único enlace que crea y establece un atributo.
Usually, setting an element property with a [property binding](guide/property-binding) Por lo general, establecer una propiedad de elemento con un [enlace de propiedad](guide/property-binding) es preferible establecer el atributo con una string. Sin embargo, a veces
is preferable to setting the attribute with a string. However, sometimes no hay ninguna propiedad de elemento para vincular, por lo que la vinculación de atributos es la solución.
there is no element property to bind, so attribute binding is the solution.
Consider the [ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) and Considera el [ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) y
[SVG](https://developer.mozilla.org/en-US/docs/Web/SVG). They are purely attributes, don't correspond to element properties, and don't set element properties. In these cases, there are no property targets to bind to. [SVG](https://developer.mozilla.org/en-US/docs/Web/SVG). Son puramente atributos, no corresponden a las propiedades del elemento y no establecen las propiedades del elemento. En estos casos, no hay objetivos de propiedad a los que vincularse.
Attribute binding syntax resembles property binding, but La sintaxis de enlace de atributo se parece al enlace de propiedad, pero en lugar de una propiedad de elemento entre paréntesis, comienza con el prefijo `attr`, seguido de un punto (`.`) y el nombre del atributo.
instead of an element property between brackets, start with the prefix `attr`, Luego establece el valor del atributo, utilizando una expresión que se resuelve en una string, o elimina el atributo cuando la expresión se resuelva en `null`.
followed by a dot (`.`), and the name of the attribute.
You then set the attribute value, using an expression that resolves to a string,
or remove the attribute when the expression resolves to `null`.
One of the primary use cases for attribute binding Uno de los casos de uso principales para el enlace de atributos es establecer atributos ARIA, como en este ejemplo:
is to set ARIA attributes, as in this example:
<code-example path="attribute-binding/src/app/app.component.html" region="attrib-binding-aria" header="src/app/app.component.html"></code-example> <code-example path="attribute-binding/src/app/app.component.html" region="attrib-binding-aria" header="src/app/app.component.html"></code-example>
@ -35,28 +30,27 @@ is to set ARIA attributes, as in this example:
<div class="alert is-helpful"> <div class="alert is-helpful">
#### `colspan` and `colSpan` #### `colspan` y `colSpan`
Notice the difference between the `colspan` attribute and the `colSpan` property. Observa la diferencia entre el atributo `colspan` y la propiedad `colSpan`.
If you wrote something like this: Si escribes algo como esto:
<code-example language="html"> <code-example language="html">
&lt;tr&gt;&lt;td colspan="{{1 + 1}}"&gt;Three-Four&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt;&lt;td colspan="{{1 + 1}}"&gt;Three-Four&lt;/td&gt;&lt;/tr&gt;
</code-example> </code-example>
You'd get this error: Recibirías este error:
<code-example language="bash"> <code-example language="bash">
Template parse errors: Template parse errors:
Can't bind to 'colspan' since it isn't a known native property Can't bind to 'colspan' since it isn't a known native property
</code-example> </code-example>
As the message says, the `<td>` element does not have a `colspan` property. This is true Como dice el mensaje, el elemento `<td>` no tiene una propiedad `colspan`. Esto es verdad
because `colspan` is an attribute&mdash;`colSpan`, with a capital `S`, is the porque `colspan` es un atributo&mdash;`colSpan`, con una `S` mayúscula, es la propiedad correspondiente. La interpolación y el enlace de propiedades solo pueden establecer *propiedades*, no atributos.
corresponding property. Interpolation and property binding can set only *properties*, not attributes.
Instead, you'd use property binding and write it like this: En su lugar, puedes usar el enlace de propiedad y lo escribirías así:
<code-example path="attribute-binding/src/app/app.component.html" region="colSpan" header="src/app/app.component.html"></code-example> <code-example path="attribute-binding/src/app/app.component.html" region="colSpan" header="src/app/app.component.html"></code-example>
@ -66,28 +60,28 @@ Instead, you'd use property binding and write it like this:
{@a class-binding} {@a class-binding}
## Class binding ## Enlace de clase
Here's how to set the `class` attribute without a binding in plain HTML: Aquí se explica cómo configurar el atributo `class` sin un enlace en HTML simple:
```html ```html
<!-- standard class attribute setting --> <!-- standard class attribute setting -->
<div class="foo bar">Some text</div> <div class="foo bar">Algún texto</div>
``` ```
You can also add and remove CSS class names from an element's `class` attribute with a **class binding**. También puedes agregar y eliminar nombres de clase CSS del atributo `class` de un elemento con un **enlace de clase**.
To create a single class binding, start with the prefix `class` followed by a dot (`.`) and the name of the CSS class (for example, `[class.foo]="hasFoo"`). Para crear un enlace de clase único, comienza con el prefijo `class` seguido de un punto (`.`) y el nombre de la clase CSS (por ejemplo, `[class.foo]="hasFoo"`).
Angular adds the class when the bound expression is truthy, and it removes the class when the expression is falsy (with the exception of `undefined`, see [styling delegation](#styling-delegation)). Angular agrega la clase cuando la expresión enlazada es verdadera y elimina la clase cuando la expresión es falsa (con la excepción de `undefined`, vea [delegación de estilo](#styling-delegation)).
To create a binding to multiple classes, use a generic `[class]` binding without the dot (for example, `[class]="classExpr"`). Para crear un enlace a varias clases, usa un enlace genérico `[class]` sin el punto (por ejemplo, `[class]="classExpr"`).
The expression can be a space-delimited string of class names, or you can format it as an object with class names as the keys and truthy/falsy expressions as the values. La expresión puede ser una string de nombres de clase delimitada por espacios, o puede formatearla como un objeto con nombres de clase como claves y expresiones de verdad / falsedad como valores.
With object format, Angular will add a class only if its associated value is truthy. Con el formato de objeto, Angular agregará una clase solo si su valor asociado es verdadero.
It's important to note that with any object-like expression (`object`, `Array`, `Map`, `Set`, etc), the identity of the object must change for the class list to be updated. Es importante tener en cuenta que con cualquier expresión similar a un objeto (`object`,`Array`, `Map`, `Set`, etc.), la identidad del objeto debe cambiar para que se actualice la lista de clases.
Updating the property without changing object identity will have no effect. Actualizar la propiedad sin cambiar la identidad del objeto no tendrá ningún efecto.
If there are multiple bindings to the same class name, conflicts are resolved using [styling precedence](#styling-precedence). Si hay varios enlaces al mismo nombre de clase, los conflictos se resuelven usando [precedencia de estilo](#styling-precedence).
<style> <style>
td, th {vertical-align: top} td, th {vertical-align: top}
@ -104,26 +98,26 @@ If there are multiple bindings to the same class name, conflicts are resolved us
</col> </col>
<tr> <tr>
<th> <th>
Binding Type Tipo de enlace
</th> </th>
<th> <th>
Syntax Sintaxis
</th> </th>
<th> <th>
Input Type Tipo de entrada
</th> </th>
<th> <th>
Example Input Values Ejemplo de valores de entrada
</th> </th>
</tr> </tr>
<tr> <tr>
<td>Single class binding</td> <td>Enlace de clase única</td>
<td><code>[class.foo]="hasFoo"</code></td> <td><code>[class.foo]="hasFoo"</code></td>
<td><code>boolean | undefined | null</code></td> <td><code>boolean | undefined | null</code></td>
<td><code>true</code>, <code>false</code></td> <td><code>true</code>, <code>false</code></td>
</tr> </tr>
<tr> <tr>
<td rowspan=3>Multi-class binding</td> <td rowspan=3>Enlace de clases múltiples</td>
<td rowspan=3><code>[class]="classExpr"</code></td> <td rowspan=3><code>[class]="classExpr"</code></td>
<td><code>string</code></td> <td><code>string</code></td>
<td><code>"my-class-1 my-class-2 my-class-3"</code></td> <td><code>"my-class-1 my-class-2 my-class-3"</code></td>
@ -139,43 +133,43 @@ If there are multiple bindings to the same class name, conflicts are resolved us
</table> </table>
The [NgClass](guide/built-in-directives/#ngclass) directive can be used as an alternative to direct `[class]` bindings. La directiva [NgClass](guide/built-in-directives/#ngclass) se puede utilizar como alternativa a los enlaces directos `[class]`.
However, using the above class binding syntax without `NgClass` is preferred because due to improvements in class binding in Angular, `NgClass` no longer provides significant value, and might eventually be removed in the future. Sin embargo, se prefiere usar la sintaxis de enlace de clase anterior sin `NgClass` porque debido a las mejoras en el enlace de clase en Angular, `NgClass` ya no proporciona un valor significativo y podría eliminarse en el futuro.
<hr/> <hr/>
## Style binding {@a style-binding}
Here's how to set the `style` attribute without a binding in plain HTML: ## Enlace de estilo
Aquí se explica cómo configurar el atributo `style` sin un enlace en HTML simple:
```html ```html
<!-- standard style attribute setting --> <!-- standard style attribute setting -->
<div style="color: blue">Some text</div> <div style="color: blue">Algún texto</div>
``` ```
You can also set styles dynamically with a **style binding**. También se puede establecer estilos dinámicamente con un **enlace de estilo**.
To create a single style binding, start with the prefix `style` followed by a dot (`.`) and the name of the CSS style property (for example, `[style.width]="width"`). Para crear un enlace de estilo único, comienza con el prefijo `style` seguido de un punto (`.`) y el nombre de la propiedad de estilo CSS (por ejemplo, `[style.width]="width"`).
The property will be set to the value of the bound expression, which is normally a string. La propiedad se establecerá en el valor de la expresión enlazada, que normalmente es una string.
Optionally, you can add a unit extension like `em` or `%`, which requires a number type. Opcionalmente, se puede agregar una extensión de unidad como `em` o `%`, que requiere un tipo de número.
<div class="alert is-helpful"> <div class="alert is-helpful">
Note that a _style property_ name can be written in either Ten en cuenta que se puede escribir una _propiedad de estilo_ en [dash-case](guide/glossary#dash-case), como se muestra arriba, o [camelCase](guide/glossary#camelcase), como `fontSize`.
[dash-case](guide/glossary#dash-case), as shown above, or
[camelCase](guide/glossary#camelcase), such as `fontSize`.
</div> </div>
If there are multiple styles you'd like to toggle, you can bind to the `[style]` property directly without the dot (for example, `[style]="styleExpr"`). Si deseas alternar múltiples estilos, puedes vincular la propiedad `[style]` directamente sin el punto (por ejemplo, `[style]="styleExpr"`).
The expression attached to the `[style]` binding is most often a string list of styles like `"width: 100px; height: 100px;"`. La expresión asociada al enlace `[style]` suele ser una lista de string de estilos como `"width: 100px; height: 100px;"`.
You can also format the expression as an object with style names as the keys and style values as the values, like `{width: '100px', height: '100px'}`. También se puede formatear la expresión como un objeto con nombres de estilo como claves y valores de estilo como los valores, como `{width: '100px', height: '100px'}`.
It's important to note that with any object-like expression (`object`, `Array`, `Map`, `Set`, etc), the identity of the object must change for the class list to be updated. Es importante tener en cuenta que con cualquier expresión similar a un objeto (`object`, `Array`, `Map`, `Set`, etc), la identidad del objeto debe cambiar para que se actualice la lista de clases.
Updating the property without changing object identity will have no effect. Actualizar la propiedad sin cambiar la identidad del objeto no tendrá ningún efecto.
If there are multiple bindings to the same style property, conflicts are resolved using [styling precedence rules](#styling-precedence). Si hay varios enlaces a la misma propiedad de estilo, los conflictos se resuelven usando [reglas de precedencia de estilo](#styling-precedence).
<style> <style>
td, th {vertical-align: top} td, th {vertical-align: top}
@ -192,33 +186,33 @@ If there are multiple bindings to the same style property, conflicts are resolve
</col> </col>
<tr> <tr>
<th> <th>
Binding Type Tipo de enlace
</th> </th>
<th> <th>
Syntax Sintaxis
</th> </th>
<th> <th>
Input Type Tipo de entrada
</th> </th>
<th> <th>
Example Input Values Ejemplo de valores de entrada
</th> </th>
</tr> </tr>
<tr> <tr>
<td>Single style binding</td> <td>Enlace de estilo único</td>
<td><code>[style.width]="width"</code></td> <td><code>[style.width]="width"</code></td>
<td><code>string | undefined | null</code></td> <td><code>string | undefined | null</code></td>
<td><code>"100px"</code></td> <td><code>"100px"</code></td>
</tr> </tr>
<tr> <tr>
<tr> <tr>
<td>Single style binding with units</td> <td>Enlace de estilo único con unidades</td>
<td><code>[style.width.px]="width"</code></td> <td><code>[style.width.px]="width"</code></td>
<td><code>number | undefined | null</code></td> <td><code>number | undefined | null</code></td>
<td><code>100</code></td> <td><code>100</code></td>
</tr> </tr>
<tr> <tr>
<td rowspan=3>Multi-style binding</td> <td rowspan=3>Enlace de múltiples estilos</td>
<td rowspan=3><code>[style]="styleExpr"</code></td> <td rowspan=3><code>[style]="styleExpr"</code></td>
<td><code>string</code></td> <td><code>string</code></td>
<td><code>"width: 100px; height: 100px"</code></td> <td><code>"width: 100px; height: 100px"</code></td>
@ -233,71 +227,71 @@ If there are multiple bindings to the same style property, conflicts are resolve
</tr> </tr>
</table> </table>
The [NgStyle](guide/built-in-directives/#ngstyle) directive can be used as an alternative to direct `[style]` bindings. La directiva [NgStyle](guide/built-in-directives/#ngstyle) se puede utilizar como alternativa a los enlaces directos `[style]`.
However, using the above style binding syntax without `NgStyle` is preferred because due to improvements in style binding in Angular, `NgStyle` no longer provides significant value, and might eventually be removed in the future. Sin embargo, se prefiere usar la sintaxis de enlace de estilos anterior sin `NgStyle` porque debido a las mejoras en el enlace de estilos en Angular, `NgStyle` ya no proporciona un valor significativo y podría eliminarse en el futuro.
<hr/> <hr/>
{@a styling-precedence} {@a styling-precedence}
## Styling Precedence ## Precedencia de estilo
A single HTML element can have its CSS class list and style values bound to multiple sources (for example, host bindings from multiple directives). Un único elemento HTML puede tener su lista de clases CSS y valores de estilo vinculados a múltiples fuentes (por ejemplo, enlaces de host de múltiples directivas).
When there are multiple bindings to the same class name or style property, Angular uses a set of precedence rules to resolve conflicts and determine which classes or styles are ultimately applied to the element. Cuando hay varios enlaces al mismo nombre de clase o propiedad de estilo, Angular usa un conjunto de reglas de precedencia para resolver conflictos y determinar qué clases o estilos se aplican finalmente al elemento.
<div class="alert is-helpful"> <div class="alert is-helpful">
<h4>Styling precedence (highest to lowest)</h4> <h4>Precedencia de estilo (de mayor a menor)</h4>
1. Template bindings 1. Enlaces de plantillas
1. Property binding (for example, `<div [class.foo]="hasFoo">` or `<div [style.color]="color">`) 1. Enlace de propiedad (por ejemplo, `<div [class.foo]="hasFoo">` o `<div [style.color]="color">`)
1. Map binding (for example, `<div [class]="classExpr">` or `<div [style]="styleExpr">`) 1. Enlace de mapa (por ejemplo, `<div [class]="classExpr">` o `<div [style]="styleExpr">`)
1. Static value (for example, `<div class="foo">` or `<div style="color: blue">`) 1. Valor estático (por ejemplo, `<div class="foo">` o `<div style="color: blue">`)
1. Directive host bindings 1. Enlaces de directivas hosts
1. Property binding (for example, `host: {'[class.foo]': 'hasFoo'}` or `host: {'[style.color]': 'color'}`) 1. Enlace de propiedad (por ejemplo, `host: {'[class.foo]': 'hasFoo'}` o `host: {'[style.color]': 'color'}`)
1. Map binding (for example, `host: {'[class]': 'classExpr'}` or `host: {'[style]': 'styleExpr'}`) 1. Enlace de mapa (por ejemplo, `host: {'[class]': 'classExpr'}` o `host: {'[style]': 'styleExpr'}`)
1. Static value (for example, `host: {'class': 'foo'}` or `host: {'style': 'color: blue'}`) 1. Valor estático (por ejemplo, `host: {'class': 'foo'}` o `host: {'style': 'color: blue'}`)
1. Component host bindings 1. Enlaces de componentes hosts
1. Property binding (for example, `host: {'[class.foo]': 'hasFoo'}` or `host: {'[style.color]': 'color'}`) 1. Enlace de propiedad (por ejemplo, `host: {'[class.foo]': 'hasFoo'}` o `host: {'[style.color]': 'color'}`)
1. Map binding (for example, `host: {'[class]': 'classExpr'}` or `host: {'[style]': 'styleExpr'}`) 1. Enlace de mapa (por ejemplo, `host: {'[class]': 'classExpr'}` o `host: {'[style]': 'styleExpr'}`)
1. Static value (for example, `host: {'class': 'foo'}` or `host: {'style': 'color: blue'}`) 1. Valor estático (por ejemplo, `host: {'class': 'foo'}` o `host: {'style': 'color: blue'}`)
</div> </div>
The more specific a class or style binding is, the higher its precedence. Cuanto más específico sea un enlace de clase o estilo, mayor será su precedencia.
A binding to a specific class (for example, `[class.foo]`) will take precedence over a generic `[class]` binding, and a binding to a specific style (for example, `[style.bar]`) will take precedence over a generic `[style]` binding. Un enlace a una clase específica (por ejemplo, `[class.foo]`) tendrá prioridad sobre un enlace genérico `[class]`, y un enlace a un estilo específico (por ejemplo, `[style.bar]`) tendrá prioridad sobre un enlace genérico `[style]`.
<code-example path="attribute-binding/src/app/app.component.html" region="basic-specificity" header="src/app/app.component.html"></code-example> <code-example path="attribute-binding/src/app/app.component.html" region="basic-specificity" header="src/app/app.component.html"></code-example>
Specificity rules also apply when it comes to bindings that originate from different sources. Las reglas de especificidad también se aplican cuando se trata de enlaces que se originan de diferentes fuentes.
It's possible for an element to have bindings in the template where it's declared, from host bindings on matched directives, and from host bindings on matched components. Es posible que un elemento tenga enlaces en la plantilla donde se declara, desde enlaces de host en directivas coincidentes y desde enlaces de host en componentes coincidentes.
Template bindings are the most specific because they apply to the element directly and exclusively, so they have the highest precedence. Los enlaces de plantilla son los más específicos porque se aplican al elemento directa y exclusivamente, por lo que tienen la mayor prioridad.
Directive host bindings are considered less specific because directives can be used in multiple locations, so they have a lower precedence than template bindings. Los enlaces de host de directiva se consideran menos específicos porque las directivas se pueden usar en varias ubicaciones, por lo que tienen una precedencia menor que los enlaces de plantilla.
Directives often augment component behavior, so host bindings from components have the lowest precedence. Las directivas a menudo aumentan el comportamiento de los componentes, por lo que los enlaces de host de los componentes tienen la prioridad más baja.
<code-example path="attribute-binding/src/app/app.component.html" region="source-specificity" header="src/app/app.component.html"></code-example> <code-example path="attribute-binding/src/app/app.component.html" region="source-specificity" header="src/app/app.component.html"></code-example>
In addition, bindings take precedence over static attributes. Además, los enlaces tienen prioridad sobre los atributos estáticos.
In the following case, `class` and `[class]` have similar specificity, but the `[class]` binding will take precedence because it is dynamic. En el siguiente caso, `class` y `[class]` tienen una especificidad similar, pero el enlace `[class]` tendrá prioridad porque es dinámico.
<code-example path="attribute-binding/src/app/app.component.html" region="dynamic-priority" header="src/app/app.component.html"></code-example> <code-example path="attribute-binding/src/app/app.component.html" region="dynamic-priority" header="src/app/app.component.html"></code-example>
{@a styling-delegation} {@a styling-delegation}
### Delegating to styles with lower precedence ### Delegar a estilos con menor prioridad
It is possible for higher precedence styles to "delegate" to lower precedence styles using `undefined` values. Es posible que los estilos de precedencia más alta "deleguen" a los estilos de precedencia más bajos utilizando valores `undefined`.
Whereas setting a style property to `null` ensures the style is removed, setting it to `undefined` will cause Angular to fall back to the next-highest precedence binding to that style. Mientras que establecer una propiedad de estilo en `null` asegura que el estilo se elimine, establecerlo en `undefined` hará que Angular vuelva al siguiente enlace de precedencia más alto para ese estilo.
For example, consider the following template: Por ejemplo, considera la siguiente plantilla:
<code-example path="attribute-binding/src/app/app.component.html" region="style-delegation" header="src/app/app.component.html"></code-example> <code-example path="attribute-binding/src/app/app.component.html" region="style-delegation" header="src/app/app.component.html"></code-example>
Imagine that the `dirWithHostBinding` directive and the `comp-with-host-binding` component both have a `[style.width]` host binding. Imagina que la directiva `dirWithHostBinding` y el componente `comp-with-host-binding` tienen un enlace de host `[style.width]`.
In that case, if `dirWithHostBinding` sets its binding to `undefined`, the `width` property will fall back to the value of the `comp-with-host-binding` host binding. En ese caso, si `dirWithHostBinding` establece su enlace en `undefined`, la propiedad `width` volverá al valor del enlace de host del componente `comp-with-host-binding`.
However, if `dirWithHostBinding` sets its binding to `null`, the `width` property will be removed entirely. Sin embargo, si `dirWithHostBinding` establece su enlace en `null`, la propiedad `width` se eliminará por completo.

View File

@ -0,0 +1,318 @@
# Binding syntax: an overview
Data-binding is a mechanism for coordinating what users see, specifically
with application data values.
While you could push values to and pull values from HTML,
the application is easier to write, read, and maintain if you turn these tasks over to a binding framework.
You simply declare bindings between binding sources, target HTML elements, and let the framework do the rest.
<div class="alert is-helpful">
See the <live-example></live-example> for a working example containing the code snippets in this guide.
</div>
Angular provides many kinds of data-binding. Binding types can be grouped into three categories distinguished by the direction of data flow:
* From the _source-to-view_
* From _view-to-source_
* Two-way sequence: _view-to-source-to-view_
<style>
td, th {vertical-align: top}
</style>
<table width="100%">
<col width="30%">
</col>
<col width="50%">
</col>
<col width="20%">
</col>
<tr>
<th>
Type
</th>
<th>
Syntax
</th>
<th>
Category
</th>
</tr>
<tr>
<td>
Interpolation<br>
Property<br>
Attribute<br>
Class<br>
Style
</td>
<td>
<code-example>
{{expression}}
[target]="expression"
bind-target="expression"
</code-example>
</td>
<td>
One-way<br>from data source<br>to view target
</td>
<tr>
<td>
Event
</td>
<td>
<code-example>
(target)="statement"
on-target="statement"
</code-example>
</td>
<td>
One-way<br>from view target<br>to data source
</td>
</tr>
<tr>
<td>
Two-way
</td>
<td>
<code-example>
[(target)]="expression"
bindon-target="expression"
</code-example>
</td>
<td>
Two-way
</td>
</tr>
</tr>
</table>
Binding types other than interpolation have a **target name** to the left of the equal sign, either surrounded by punctuation, `[]` or `()`,
or preceded by a prefix: `bind-`, `on-`, `bindon-`.
The *target* of a binding is the property or event inside the binding punctuation: `[]`, `()` or `[()]`.
Every public member of a **source** directive is automatically available for binding.
You don't have to do anything special to access a directive member in a template expression or statement.
### Data-binding and HTML
In the normal course of HTML development, you create a visual structure with HTML elements, and
you modify those elements by setting element attributes with string constants.
```html
<div class="special">Plain old HTML</div>
<img src="images/item.png">
<button disabled>Save</button>
```
With data-binding, you can control things like the state of a button:
<code-example path="binding-syntax/src/app/app.component.html" region="disabled-button" header="src/app/app.component.html"></code-example>
Notice that the binding is to the `disabled` property of the button's DOM element,
**not** the attribute. This applies to data-binding in general. Data-binding works with *properties* of DOM elements, components, and directives, not HTML *attributes*.
{@a html-attribute-vs-dom-property}
### HTML attribute vs. DOM property
The distinction between an HTML attribute and a DOM property is key to understanding
how Angular binding works. **Attributes are defined by HTML. Properties are accessed from DOM (Document Object Model) nodes.**
* A few HTML attributes have 1:1 mapping to properties; for example, `id`.
* Some HTML attributes don't have corresponding properties; for example, `aria-*`.
* Some DOM properties don't have corresponding attributes; for example, `textContent`.
It is important to remember that *HTML attribute* and the *DOM property* are different things, even when they have the same name.
In Angular, the only role of HTML attributes is to initialize element and directive state.
**Template binding works with *properties* and *events*, not *attributes*.**
When you write a data-binding, you're dealing exclusively with the *DOM properties* and *events* of the target object.
<div class="alert is-helpful">
This general rule can help you build a mental model of attributes and DOM properties:
**Attributes initialize DOM properties and then they are done.
Property values can change; attribute values can't.**
There is one exception to this rule.
Attributes can be changed by `setAttribute()`, which re-initializes corresponding DOM properties.
</div>
For more information, see the [MDN Interfaces documentation](https://developer.mozilla.org/en-US/docs/Web/API#Interfaces) which has API docs for all the standard DOM elements and their properties.
Comparing the [`<td>` attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/td) attributes to the [`<td>` properties](https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableCellElement) provides a helpful example for differentiation.
In particular, you can navigate from the attributes page to the properties via "DOM interface" link, and navigate the inheritance hierarchy up to `HTMLTableCellElement`.
#### Example 1: an `<input>`
When the browser renders `<input type="text" value="Sarah">`, it creates a
corresponding DOM node with a `value` property initialized to "Sarah".
```html
<input type="text" value="Sarah">
```
When the user enters "Sally" into the `<input>`, the DOM element `value` *property* becomes "Sally".
However, if you look at the HTML attribute `value` using `input.getAttribute('value')`, you can see that the *attribute* remains unchanged&mdash;it returns "Sarah".
The HTML attribute `value` specifies the *initial* value; the DOM `value` property is the *current* value.
To see attributes versus DOM properties in a functioning app, see the <live-example name="binding-syntax"></live-example> especially for binding syntax.
#### Example 2: a disabled button
The `disabled` attribute is another example. A button's `disabled`
*property* is `false` by default so the button is enabled.
When you add the `disabled` *attribute*, its presence alone
initializes the button's `disabled` *property* to `true`
so the button is disabled.
```html
<button disabled>Test Button</button>
```
Adding and removing the `disabled` *attribute* disables and enables the button.
However, the value of the *attribute* is irrelevant,
which is why you cannot enable a button by writing `<button disabled="false">Still Disabled</button>`.
To control the state of the button, set the `disabled` *property*,
<div class="alert is-helpful">
Though you could technically set the `[attr.disabled]` attribute binding, the values are different in that the property binding requires to a boolean value, while its corresponding attribute binding relies on whether the value is `null` or not. Consider the following:
```html
<input [disabled]="condition ? true : false">
<input [attr.disabled]="condition ? 'disabled' : null">
```
Generally, use property binding over attribute binding as it is more intuitive (being a boolean value), has a shorter syntax, and is more performant.
</div>
To see the `disabled` button example in a functioning app, see the <live-example name="binding-syntax"></live-example> especially for binding syntax. This example shows you how to toggle the disabled property from the component.
## Binding types and targets
The **target of a data-binding** is something in the DOM.
Depending on the binding type, the target can be a property (element, component, or directive),
an event (element, component, or directive), or sometimes an attribute name.
The following table summarizes the targets for the different binding types.
<style>
td, th {vertical-align: top}
</style>
<table width="100%">
<col width="10%">
</col>
<col width="15%">
</col>
<col width="75%">
</col>
<tr>
<th>
Type
</th>
<th>
Target
</th>
<th>
Examples
</th>
</tr>
<tr>
<td>
Property
</td>
<td>
Element&nbsp;property<br>
Component&nbsp;property<br>
Directive&nbsp;property
</td>
<td>
<code>src</code>, <code>hero</code>, and <code>ngClass</code> in the following:
<code-example path="template-syntax/src/app/app.component.html" region="property-binding-syntax-1"></code-example>
<!-- For more information, see [Property Binding](guide/property-binding). -->
</td>
</tr>
<tr>
<td>
Event
</td>
<td>
Element&nbsp;event<br>
Component&nbsp;event<br>
Directive&nbsp;event
</td>
<td>
<code>click</code>, <code>deleteRequest</code>, and <code>myClick</code> in the following:
<code-example path="template-syntax/src/app/app.component.html" region="event-binding-syntax-1"></code-example>
<!-- KW--Why don't these links work in the table? -->
<!-- <div>For more information, see [Event Binding](guide/event-binding).</div> -->
</td>
</tr>
<tr>
<td>
Two-way
</td>
<td>
Event and property
</td>
<td>
<code-example path="template-syntax/src/app/app.component.html" region="2-way-binding-syntax-1"></code-example>
</td>
</tr>
<tr>
<td>
Attribute
</td>
<td>
Attribute
(the&nbsp;exception)
</td>
<td>
<code-example path="template-syntax/src/app/app.component.html" region="attribute-binding-syntax-1"></code-example>
</td>
</tr>
<tr>
<td>
Class
</td>
<td>
<code>class</code> property
</td>
<td>
<code-example path="template-syntax/src/app/app.component.html" region="class-binding-syntax-1"></code-example>
</td>
</tr>
<tr>
<td>
Style
</td>
<td>
<code>style</code> property
</td>
<td>
<code-example path="template-syntax/src/app/app.component.html" region="style-binding-syntax-1"></code-example>
</td>
</tr>
</table>

View File

@ -1,23 +1,21 @@
# Binding syntax: an overview # Sintaxis de Enlace: una visión general
Data-binding is a mechanism for coordinating what users see, specifically El enlace de datos es un mecanismo utilizado para coordinar los valores de los datos que los usuarios visualizan en la aplicación.
with application data values. Aunque puedas insertar y actualizar valores en el HTML, la aplicación es más fácil de escribir, leer y mantener si tu le dejas esas tareas al framework de enlace.
While you could push values to and pull values from HTML, Por lo que simplemente debes declarar enlaces entre los datos del modelo y los elementos HTML y dejar al framework que haga el resto del trabajo.
the application is easier to write, read, and maintain if you turn these tasks over to a binding framework.
You simply declare bindings between binding sources, target HTML elements, and let the framework do the rest.
<div class="alert is-helpful"> <div class="alert is-helpful">
See the <live-example></live-example> for a working example containing the code snippets in this guide. Consulta la <live-example>aplicación de muestra</live-example> que es un ejemplo funcional que contiene los fragmentos de código utilizados en esta guía.
</div> </div>
Angular provides many kinds of data-binding. Binding types can be grouped into three categories distinguished by the direction of data flow: Angular proporciona muchas formas para manejar el enlace de datos. Los tipos de enlace se pueden agrupar en tres categorías que se distinguen de acuerdo a la dirección del flujo de datos:
* From the _source-to-view_ * Desde el _modelo-hacia-vista_
* From _view-to-source_ * Desde la _vista-hacia-modelo_
* Two-way sequence: _view-to-source-to-view_ * Secuencia Bidireccional: _vista-hacia-modelo-hacia-vista_
<style> <style>
td, th {vertical-align: top} td, th {vertical-align: top}
@ -32,23 +30,23 @@ Angular provides many kinds of data-binding. Binding types can be grouped into t
</col> </col>
<tr> <tr>
<th> <th>
Type Tipo
</th> </th>
<th> <th>
Syntax Sintaxis
</th> </th>
<th> <th>
Category Categoría
</th> </th>
</tr> </tr>
<tr> <tr>
<td> <td>
Interpolation<br> Interpolación<br>
Property<br> Propiedad<br>
Attribute<br> Atributo<br>
Class<br> Clase<br>
Style Estilos
</td> </td>
<td> <td>
@ -61,11 +59,11 @@ Angular provides many kinds of data-binding. Binding types can be grouped into t
</td> </td>
<td> <td>
One-way<br>from data source<br>to view target Una sola dirección<br>desde el modelo de datos<br>hacia la vista
</td> </td>
<tr> <tr>
<td> <td>
Event Evento
</td> </td>
<td> <td>
<code-example> <code-example>
@ -75,12 +73,12 @@ Angular provides many kinds of data-binding. Binding types can be grouped into t
</td> </td>
<td> <td>
One-way<br>from view target<br>to data source Una sola dirección<br>desde la vista<br>hacia el modelo de datos
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <td>
Two-way Bidireccional
</td> </td>
<td> <td>
<code-example> <code-example>
@ -89,132 +87,123 @@ Angular provides many kinds of data-binding. Binding types can be grouped into t
</code-example> </code-example>
</td> </td>
<td> <td>
Two-way Bidireccional
</td> </td>
</tr> </tr>
</tr> </tr>
</table> </table>
Binding types other than interpolation have a **target name** to the left of the equal sign, either surrounded by punctuation, `[]` or `()`, Los tipos de enlace distintos a la interporlación tienen un **nombre de destino** hacia la izquierda del signo igual, están rodeados por los signos de puntación `[]` o `()`, o bien están precedidos por el prefijo: `bind-`, `on-`, `bindon-`.
or preceded by a prefix: `bind-`, `on-`, `bindon-`.
The *target* of a binding is the property or event inside the binding punctuation: `[]`, `()` or `[()]`. El *destino* de un enlace es la propiedad o evento situado dentro de los signos de puntuación: `[]`, `()` or `[()]`.
Every public member of a **source** directive is automatically available for binding. Cada miembro <span class="x x-first x-last">público</span> de una directiva **fuente** <span class="x x-first x-last">está</span> disponible automaticamente para ser utilizada con los enlaces.
You don't have to do anything special to access a directive member in a template expression or statement. No es necesario hacer nada especial para poder acceder al miembro de una directiva en una expresión o declaración de plantilla.
### Enlace de Datos y el HTML
### Data-binding and HTML En condiciones normales para un desarrollo HTML, primero se crea la estructura visual con los elementos HTML y luego se modifican dichos elementos estableciendo los atributos de dichos elementos utilizando una cadena de caracteres.
In the normal course of HTML development, you create a visual structure with HTML elements, and
you modify those elements by setting element attributes with string constants.
```html ```html
<div class="special">Plain old HTML</div> <div class="special">HTML Simple</div>
<img src="images/item.png"> <img src="images/item.png">
<button disabled>Save</button> <button disabled>Guardar</button>
``` ```
With data-binding, you can control things like the state of a button: Usando el enlace de datos, puedes controlar cosas como el estado de un botón:
<code-example path="binding-syntax/src/app/app.component.html" region="disabled-button" header="src/app/app.component.html"></code-example> <code-example path="binding-syntax/src/app/app.component.html" region="disabled-button" header="src/app/app.component.html"></code-example>
Notice that the binding is to the `disabled` property of the button's DOM element, Puedes notar que el enlace se realiza a la propiedad `disabled` del elemento botón del DOM,
**not** the attribute. This applies to data-binding in general. Data-binding works with *properties* of DOM elements, components, and directives, not HTML *attributes*. **no** al atributo. Esto aplica al enlace de datos en general. El enlace de datos funciona con las *propiedades* de los elementos, componentes y directivas del DOM, no con los *atributos* HTML
{@a html-attribute-vs-dom-property} {@a html-attribute-vs-dom-property}
### HTML attribute vs. DOM property ### Atributos HTML vs. Propiedades del DOM
The distinction between an HTML attribute and a DOM property is key to understanding Distinguir la diferencia entre un atributo HTML y una propiedad del DOM es clave para comprender como funciona el enlace en Angular. **Los attributos son definidos por el HTML. Las propiedades se acceden desde los nodos del DOM (Document Object Model).**
how Angular binding works. **Attributes are defined by HTML. Properties are accessed from DOM (Document Object Model) nodes.**
* A few HTML attributes have 1:1 mapping to properties; for example, `id`. * Muy pocos atributos HTML tienen una relación 1:1 con las propiedades; por ejemplo el, `id`.
* Some HTML attributes don't have corresponding properties; for example, `aria-*`. * Algunos atributos HTML no tienen su correspondencia en propiedades; como por ejemplo, `aria-*`.
* Some DOM properties don't have corresponding attributes; for example, `textContent`. * Algunas propiedades del DOM no tienen su correspondencia hacia atributos; como por ejemplo, `textContent`.
It is important to remember that *HTML attribute* and the *DOM property* are different things, even when they have the same name. Es importante recordar que los *atributos HTML* y las *propiedades del DOM* son cosas muy diferentes, incluso cuando tienen el mismo nombre.
In Angular, the only role of HTML attributes is to initialize element and directive state. En Angular, el único rol de los atributos HTML es el de inicializar el estado de los elementos y las directivas.
**Template binding works with *properties* and *events*, not *attributes*.** **El enlace de plantilla funciona con *propiedades* y *eventos*, no con *atributos*.**
When you write a data-binding, you're dealing exclusively with the *DOM properties* and *events* of the target object. Cuando escribes un enlace de datos, se trata exclusivamente sobre las *propiedades del DOM* and *eventos* del objeto de destino.
<div class="alert is-helpful"> <div class="alert is-helpful">
This general rule can help you build a mental model of attributes and DOM properties: Esta regla general puede ayudarnos a crear un modelo mental de los atributos y las propiedades del DOM:
**Attributes initialize DOM properties and then they are done. **Los atributos inicializan las propiedades del DOM y cuando eso ya esta hecho, los valores de las propiedades pueden cambiar, mientras que los atributos no lo pueden hacer.**
Property values can change; attribute values can't.**
There is one exception to this rule. Solamente hay una excepción a la regla.
Attributes can be changed by `setAttribute()`, which re-initializes corresponding DOM properties. Los atributos pueden cambiarse usando el método `setAttribute()`, el cual re-inicializa las propiedades del DOM correspondientes.
</div> </div>
For more information, see the [MDN Interfaces documentation](https://developer.mozilla.org/en-US/docs/Web/API#Interfaces) which has API docs for all the standard DOM elements and their properties. Para más información, consulta la [Documentación de Interfaces MDN](https://developer.mozilla.org/en-US/docs/Web/API#Interfaces) que contiene los documentos de la API para todos los elementos estándar del DOM y sus propiedades.
Comparing the [`<td>` attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/td) attributes to the [`<td>` properties](https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableCellElement) provides a helpful example for differentiation. Comparar los atributos [`<td>` atributos](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/td) con las propiedades [`<td>` propiedades](https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableCellElement) nos proporciona un ejemplo útil para poder diferenciar estos dos términos de una mejor manera.
In particular, you can navigate from the attributes page to the properties via "DOM interface" link, and navigate the inheritance hierarchy up to `HTMLTableCellElement`. En particular, se puede navegar de la página de atributos a la página de propiedades por medio del enlace "Interfaz del DOM", y navegar la jerarquía de la herencia hasta `HTMLTableCellElement`.
#### Example 1: an `<input>` #### Ejemplo 1: un `<input>`
When the browser renders `<input type="text" value="Sarah">`, it creates a Cuando el navegador renderiza `<input type="text" value="Sarah">`, este crea un nodo correspondiente en el DOM con la propiedad `value` inicializada con el valor de "Sarah".
corresponding DOM node with a `value` property initialized to "Sarah".
```html ```html
<input type="text" value="Sarah"> <input type="text" value="Sarah">
``` ```
When the user enters "Sally" into the `<input>`, the DOM element `value` *property* becomes "Sally". Cuando el usuario ingresa "Sally" dentro del `<input>`, la **propiedad** `value` del elemento del DOM se convierte en "Sally".
However, if you look at the HTML attribute `value` using `input.getAttribute('value')`, you can see that the *attribute* remains unchanged&mdash;it returns "Sarah". Sin embargo, si tu revisas el atributo HTML `value` usando el método `input.getAttribute('value')`, puedes notar que el *atributo* no ha cambiado&mdash;por lo que returna el valor de "Sarah".
The HTML attribute `value` specifies the *initial* value; the DOM `value` property is the *current* value. El atributo HTML `value` especifica el valor *inicial*; la propiedad del DOM `value` es el valor *actual*.
To see attributes versus DOM properties in a functioning app, see the <live-example name="binding-syntax"></live-example> especially for binding syntax. Para consultar los atributos vs las propiedades del DOM en una aplicación funcional, consulta la <live-example name="binding-syntax">aplicación</live-example> en especial para repasar la sintaxis de enlace.
#### Example 2: a disabled button #### Ejemplo 2: un botón desactivado
The `disabled` attribute is another example. A button's `disabled` El atributo `disabled` es otro ejemplo. La *propiedad* del botón `disabled`
*property* is `false` by default so the button is enabled. *property* es `false` por defecto así que el botón esta activo.
When you add the `disabled` *attribute*, its presence alone Cuando añades el *atributo* `disabled`, su sola presencia inicializa la *propiedad* del botón `disabled` con el valor de `true` por lo que el botón esta desactivado.
initializes the button's `disabled` *property* to `true`
so the button is disabled.
```html ```html
<button disabled>Test Button</button> <button disabled>Botón de Ejemplo</button>
``` ```
Adding and removing the `disabled` *attribute* disables and enables the button. Añadir y eliminar el *atributo* `disabled` desactiva y activa el botón.
However, the value of the *attribute* is irrelevant, Sin embargo, el valor del *atributo* es irrelevante,
which is why you cannot enable a button by writing `<button disabled="false">Still Disabled</button>`. lo cual es la razón del por qué no puedes activar un botón escribiendo `<button disabled="false">Todavía Desactivado</button>`.
To control the state of the button, set the `disabled` *property*, Para controlar el estado de un botón, establece la *propiedad* `disabled`.
<div class="alert is-helpful"> <div class="alert is-helpful">
Though you could technically set the `[attr.disabled]` attribute binding, the values are different in that the property binding requires to a boolean value, while its corresponding attribute binding relies on whether the value is `null` or not. Consider the following: Aunque técnicamente podrías establecer el enlace de atributo `[attr.disabled]`, los valores son diferentes ya que el enlace de propiedad necesita un valor booleano, mientras que el enlace de atributo correspondiente depende de que su valor sea `null` o no. Por lo que considera lo siguiente:
```html ```html
<input [disabled]="condition ? true : false"> <input [disabled]="condition ? true : false">
<input [attr.disabled]="condition ? 'disabled' : null"> <input [attr.disabled]="condition ? 'disabled' : null">
``` ```
Generally, use property binding over attribute binding as it is more intuitive (being a boolean value), has a shorter syntax, and is more performant. Por lo general usa enlace de propiedades sobre enlace de atributos ya que es más intuitivo (siendo un valor booleano), tienen una sintaxis corta y es más eficaz.
</div> </div>
Para ver el ejemplo del botón `disabled`, consulta la <live-example name="binding-syntax">aplicación</live-example> en especial para revisar la sintaxis de enlace. Este ejemplo muestra como alternar la propiedad disabled desde el componente.
To see the `disabled` button example in a functioning app, see the <live-example name="binding-syntax"></live-example> especially for binding syntax. This example shows you how to toggle the disabled property from the component. ## Tipos de enlace y objetivos
## Binding types and targets El **objetivo de un enlace de datos** se relaciona con algo del DOM.
Dependiendo del tipo de enlace, el objetivo puede ser una propiedad (elemento, componente, o directiva),
The **target of a data-binding** is something in the DOM. un evento (elemento, componente o directiva), o incluso algunas veces el nombre de un atributo.
Depending on the binding type, the target can be a property (element, component, or directive), La siguiente tabla recoge los objetivos para los diferentes tipos de enlace.
an event (element, component, or directive), or sometimes an attribute name.
The following table summarizes the targets for the different binding types.
<style> <style>
td, th {vertical-align: top} td, th {vertical-align: top}
@ -229,23 +218,23 @@ The following table summarizes the targets for the different binding types.
</col> </col>
<tr> <tr>
<th> <th>
Type Tipo
</th> </th>
<th> <th>
Target Objetivo
</th> </th>
<th> <th>
Examples Ejemplos
</th> </th>
</tr> </tr>
<tr> <tr>
<td> <td>
Property Propiedad
</td> </td>
<td> <td>
Element&nbsp;property<br> Propiedad del&nbsp;elemento<br>
Component&nbsp;property<br> Propiedad del&nbsp;componente<br>
Directive&nbsp;property Propiedad de la&nbsp;directiva
</td> </td>
<td> <td>
<code>src</code>, <code>hero</code>, and <code>ngClass</code> in the following: <code>src</code>, <code>hero</code>, and <code>ngClass</code> in the following:
@ -255,12 +244,12 @@ The following table summarizes the targets for the different binding types.
</tr> </tr>
<tr> <tr>
<td> <td>
Event Evento
</td> </td>
<td> <td>
Element&nbsp;event<br> Evento del &nbsp;elemento<br>
Component&nbsp;event<br> Evento del&nbsp;componente<br>
Directive&nbsp;event Evento de la &nbsp;directiva
</td> </td>
<td> <td>
<code>click</code>, <code>deleteRequest</code>, and <code>myClick</code> in the following: <code>click</code>, <code>deleteRequest</code>, and <code>myClick</code> in the following:
@ -271,10 +260,10 @@ The following table summarizes the targets for the different binding types.
</tr> </tr>
<tr> <tr>
<td> <td>
Two-way Bidireccional
</td> </td>
<td> <td>
Event and property Eventos y propiedades
</td> </td>
<td> <td>
<code-example path="template-syntax/src/app/app.component.html" region="2-way-binding-syntax-1"></code-example> <code-example path="template-syntax/src/app/app.component.html" region="2-way-binding-syntax-1"></code-example>
@ -282,11 +271,11 @@ The following table summarizes the targets for the different binding types.
</tr> </tr>
<tr> <tr>
<td> <td>
Attribute Atributo
</td> </td>
<td> <td>
Attribute Atributo
(the&nbsp;exception) (la&nbsp;excepción)
</td> </td>
<td> <td>
<code-example path="template-syntax/src/app/app.component.html" region="attribute-binding-syntax-1"></code-example> <code-example path="template-syntax/src/app/app.component.html" region="attribute-binding-syntax-1"></code-example>
@ -294,10 +283,10 @@ The following table summarizes the targets for the different binding types.
</tr> </tr>
<tr> <tr>
<td> <td>
Class Clase
</td> </td>
<td> <td>
<code>class</code> property Propiedad de una <code>clase</code>
</td> </td>
<td> <td>
<code-example path="template-syntax/src/app/app.component.html" region="class-binding-syntax-1"></code-example> <code-example path="template-syntax/src/app/app.component.html" region="class-binding-syntax-1"></code-example>
@ -305,14 +294,13 @@ The following table summarizes the targets for the different binding types.
</tr> </tr>
<tr> <tr>
<td> <td>
Style Estilos
</td> </td>
<td> <td>
<code>style</code> property Propiedad de un <code>estilo</code>
</td> </td>
<td> <td>
<code-example path="template-syntax/src/app/app.component.html" region="style-binding-syntax-1"></code-example> <code-example path="template-syntax/src/app/app.component.html" region="style-binding-syntax-1"></code-example>
</td> </td>
</tr> </tr>
</table> </table>

View File

@ -0,0 +1,174 @@
# Launching your app with a root module
#### Prerequisites
A basic understanding of the following:
* [JavaScript Modules vs. NgModules](guide/ngmodule-vs-jsmodule).
<hr />
An NgModule describes how the application parts fit together.
Every application has at least one Angular module, the _root_ module,
which must be present for bootstrapping the application on launch.
By convention and by default, this NgModule is named `AppModule`.
When you use the [Angular CLI](cli) command `ng new` to generate an app, the default `AppModule` is as follows.
```typescript
/* JavaScript imports */
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
/* the AppModule class with the @NgModule decorator */
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
```
After the import statements is a class with the
**`@NgModule`** [decorator](guide/glossary#decorator '"Decorator" explained').
The `@NgModule` decorator identifies `AppModule` as an `NgModule` class.
`@NgModule` takes a metadata object that tells Angular how to compile and launch the application.
* **_declarations_**&mdash;this application's lone component.
* **_imports_**&mdash;import `BrowserModule` to have browser specific services such as DOM rendering, sanitization, and location.
* **_providers_**&mdash;the service providers.
* **_bootstrap_**&mdash;the _root_ component that Angular creates and inserts
into the `index.html` host web page.
The default application created by the Angular CLI only has one component, `AppComponent`, so it
is in both the `declarations` and the `bootstrap` arrays.
{@a declarations}
## The `declarations` array
The module's `declarations` array tells Angular which components belong to that module.
As you create more components, add them to `declarations`.
You must declare every component in exactly one `NgModule` class.
If you use a component without declaring it, Angular returns an
error message.
The `declarations` array only takes declarables. Declarables
are components, [directives](guide/attribute-directives) and [pipes](guide/pipes).
All of a module's declarables must be in the `declarations` array.
Declarables must belong to exactly one module. The compiler emits
an error if you try to declare the same class in more than one module.
These declared classes are visible within the module but invisible
to components in a different module unless they are exported from
this module and the other module imports this one.
An example of what goes into a declarations array follows:
```typescript
declarations: [
YourComponent,
YourPipe,
YourDirective
],
```
A declarable can only belong to one module, so only declare it in
one `@NgModule`. When you need it elsewhere,
import the module that has the declarable you need in it.
**Only `@NgModule` references** go in the `imports` array.
### Using directives with `@NgModule`
Use the `declarations` array for directives.
To use a directive, component, or pipe in a module, you must do a few things:
1. Export it from the file where you wrote it.
2. Import it into the appropriate module.
3. Declare it in the `@NgModule` `declarations` array.
Those three steps look like the following. In the file where you create your directive, export it.
The following example, named `ItemDirective` is the default directive structure that the CLI generates in its own file, `item.directive.ts`:
<code-example path="bootstrapping/src/app/item.directive.ts" region="directive" header="src/app/item.directive.ts"></code-example>
The key point here is that you have to export it so you can import it elsewhere. Next, import it
into the `NgModule`, in this example `app.module.ts`, with a JavaScript import statement:
<code-example path="bootstrapping/src/app/app.module.ts" region="directive-import" header="src/app/app.module.ts"></code-example>
And in the same file, add it to the `@NgModule` `declarations` array:
<code-example path="bootstrapping/src/app/app.module.ts" region="declarations" header="src/app/app.module.ts"></code-example>
Now you could use your `ItemDirective` in a component. This example uses `AppModule`, but you'd do it the same way for a feature module. For more about directives, see [Attribute Directives](guide/attribute-directives) and [Structural Directives](guide/structural-directives). You'd also use the same technique for [pipes](guide/pipes) and components.
Remember, components, directives, and pipes belong to one module only. You only need to declare them once in your app because you share them by importing the necessary modules. This saves you time and helps keep your app lean.
{@a imports}
## The `imports` array
The module's `imports` array appears exclusively in the `@NgModule` metadata object.
It tells Angular about other NgModules that this particular module needs to function properly.
This list of modules are those that export components, directives, or pipes
that the component templates in this module reference. In this case, the component is
`AppComponent`, which references components, directives, or pipes in `BrowserModule`,
`FormsModule`, or `HttpClientModule`.
A component template can reference another component, directive,
or pipe when the referenced class is declared in this module or
the class was imported from another module.
{@a bootstrap-array}
## The `providers` array
The providers array is where you list the services the app needs. When
you list services here, they are available app-wide. You can scope
them when using feature modules and lazy loading. For more information, see
[Providers](guide/providers).
## The `bootstrap` array
The application launches by bootstrapping the root `AppModule`, which is
also referred to as an `entryComponent`.
Among other things, the bootstrapping process creates the component(s) listed in the `bootstrap` array
and inserts each one into the browser DOM.
Each bootstrapped component is the base of its own tree of components.
Inserting a bootstrapped component usually triggers a cascade of
component creations that fill out that tree.
While you can put more than one component tree on a host web page,
most applications have only one component tree and bootstrap a single root component.
This one root component is usually called `AppComponent` and is in the
root module's `bootstrap` array.
## More about Angular Modules
For more on NgModules you're likely to see frequently in apps,
see [Frequently Used Modules](guide/frequent-ngmodules).

View File

@ -1,18 +1,18 @@
# Launching your app with a root module # Lanzando tu aplicación con un módulo raíz
#### Prerequisites #### Pre-requisitos
A basic understanding of the following: Una comprensión básica de lo siguiente:
* [JavaScript Modules vs. NgModules](guide/ngmodule-vs-jsmodule). * [JavaScript Modules vs. NgModules](guide/ngmodule-vs-jsmodule).
<hr /> <hr />
An NgModule describes how the application parts fit together. Un NgModule describe cómo encajan las partes de la aplicación.
Every application has at least one Angular module, the _root_ module, Cada aplicación tiene al menos un módulo Angular, el módulo _root_,
which must be present for bootstrapping the application on launch. que debe estar presente para arrancar la aplicación en el lanzamiento inicial.
By convention and by default, this NgModule is named `AppModule`. Por convención y por defecto, este NgModule se llama `AppModule`.
When you use the [Angular CLI](cli) command `ng new` to generate an app, the default `AppModule` is as follows. Cuando se usa el comando de [Angular CLI](cli) `ng new` para generar una aplicación, el `AppModule` predeterminado es el siguiente.
```typescript ```typescript
/* JavaScript imports */ /* JavaScript imports */
@ -40,43 +40,44 @@ export class AppModule { }
``` ```
After the import statements is a class with the Después de las declaraciones de importación hay una clase con
**`@NgModule`** [decorator](guide/glossary#decorator '"Decorator" explained'). [decorador](guide/glossary#decorator 'Explicando "Decorator"') **`@NgModule`**.
The `@NgModule` decorator identifies `AppModule` as an `NgModule` class. El decorador `@NgModule` identifica `AppModule` como una clase `NgModule`.
`@NgModule` takes a metadata object that tells Angular how to compile and launch the application. `@NgModule` toma un objeto de metadatos que le dice a Angular cómo compilar e iniciar la aplicación.
* **_declarations_**&mdash;this application's lone component. * **_declarations_**&mdash; el único componente de esta aplicación..
* **_imports_**&mdash;import `BrowserModule` to have browser specific services such as DOM rendering, sanitization, and location. * **_imports_**&mdash; importar `BrowserModule` para tener servicios específicos del navegador como renderizado DOM, sanitization y ubicación.
* **_providers_**&mdash;the service providers. * **_providers_**&mdash; los proveedores de servicios.
* **_bootstrap_**&mdash;the _root_ component that Angular creates and inserts * **_bootstrap_**&mdash; el componente raíz que Angular crea e inserta
into the `index.html` host web page. en la página web de host `index.html`.
The default application created by the Angular CLI only has one component, `AppComponent`, so it La aplicación predeterminada creada por Angular CLI solo tiene un componente, `AppComponent`, por lo que
is in both the `declarations` and the `bootstrap` arrays. está en los arrays de `declarations` y `bootstrap`.
{@a the-declarations-array}
{@a declarations} {@a declarations}
## The `declarations` array ## El array `declarations`
The module's `declarations` array tells Angular which components belong to that module. El array de `declarations` le dice a Angular qué componentes pertenecen a ese módulo.
As you create more components, add them to `declarations`. A medida que crees más componentes, agrégalos a las `declarations`.
You must declare every component in exactly one `NgModule` class. Debe declarar cada componente en exactamente una clase `NgModule`.
If you use a component without declaring it, Angular returns an Si se usa un componente sin declararlo, Angular devuelve un
error message. mensaje de error.
The `declarations` array only takes declarables. Declarables El array `declarations` solo acepta declarables. Declarables pueden ser
are components, [directives](guide/attribute-directives) and [pipes](guide/pipes). componentes, [directivas](guide/attribute-directives) y [pipes](guide/pipes).
All of a module's declarables must be in the `declarations` array. Todos los declarables de un módulo deben estar en el array de `declarations`.
Declarables must belong to exactly one module. The compiler emits Los declarables deben pertenecer exactamente a un módulo. El compilador emite
an error if you try to declare the same class in more than one module. un error si se intenta declarar la misma clase en más de un módulo.
These declared classes are visible within the module but invisible Estas clases declaradas son visibles dentro del módulo pero invisibles
to components in a different module unless they are exported from a componentes en un módulo diferente, a menos que se exporten desde
this module and the other module imports this one. éste módulo y el otro módulo importe éste mismo módulo.
An example of what goes into a declarations array follows: A continuación, se muestra un ejemplo de un array `declarations`:
```typescript ```typescript
declarations: [ declarations: [
@ -86,89 +87,86 @@ An example of what goes into a declarations array follows:
], ],
``` ```
A declarable can only belong to one module, so only declare it in Un declarable solo puede pertenecer a un módulo, por lo que solo debe ser declarado en
one `@NgModule`. When you need it elsewhere, un `@NgModule`. Cuando se necesite en otro lugar,
import the module that has the declarable you need in it. importa el módulo que tiene el declarable que necesites.
**Only `@NgModule` references** go in the `imports` array. **Solo las referencias de `@NgModule`** van en el array `imports`.
### Using directives with `@NgModule` ### Usando directivas con `@NgModule`
Use the `declarations` array for directives. Usa el array `declarations` para las directivas.
To use a directive, component, or pipe in a module, you must do a few things: Para usar una directiva, un componente o un pipe en un módulo, hay que hacer algunas cosas:
1. Export it from the file where you wrote it. 1. Exportarlo desde el archivo donde se escribió.
2. Import it into the appropriate module. 2. Importarlo al módulo apropiado.
3. Declare it in the `@NgModule` `declarations` array. 3. Declararlo en el array `declarations` del `@NgModule`.
Those three steps look like the following. In the file where you create your directive, export it. Esos tres pasos se parecen a los siguientes. En el archivo donde se crea la directiva, expórtalo.
The following example, named `ItemDirective` is the default directive structure that the CLI generates in its own file, `item.directive.ts`: El siguiente ejemplo, llamado `ItemDirective` es la estructura de directiva predeterminada que la CLI genera en su propio archivo, `item.directive.ts`:
<code-example path="bootstrapping/src/app/item.directive.ts" region="directive" header="src/app/item.directive.ts"></code-example> <code-example path="bootstrapping/src/app/item.directive.ts" region="directive" header="src/app/item.directive.ts"></code-example>
The key point here is that you have to export it so you can import it elsewhere. Next, import it El punto clave aquí es que se debe exportar para poder importarlo en otro lugar. A continuación, importar
into the `NgModule`, in this example `app.module.ts`, with a JavaScript import statement: en el `NgModule`, en este ejemplo, `app.module.ts` con una declaración de importación de JavaScript:
<code-example path="bootstrapping/src/app/app.module.ts" region="directive-import" header="src/app/app.module.ts"></code-example> <code-example path="bootstrapping/src/app/app.module.ts" region="directive-import" header="src/app/app.module.ts"></code-example>
And in the same file, add it to the `@NgModule` `declarations` array: Y en el mismo archivo, agregarlo al array `declarations` del `@ NgModule`:
<code-example path="bootstrapping/src/app/app.module.ts" region="declarations" header="src/app/app.module.ts"></code-example> <code-example path="bootstrapping/src/app/app.module.ts" region="declarations" header="src/app/app.module.ts"></code-example>
Now you could use your `ItemDirective` in a component. This example uses `AppModule`, but you'd do it the same way for a feature module. For more about directives, see [Attribute Directives](guide/attribute-directives) and [Structural Directives](guide/structural-directives). You'd also use the same technique for [pipes](guide/pipes) and components. Ahora puedes usar tu `ItemDirective` en un componente. Este ejemplo usa `AppModule`, pero se haría de la misma manera para un módulo de funciones. Para obtener más información sobre las directivas, consulta [Directivas de atributos](guide/attribute-directives) y [Directivas estructurales](guide/structural-directives). También se usaría la misma técnica para [pipes](guide/pipes) y componentes.
Remember, components, directives, and pipes belong to one module only. You only need to declare them once in your app because you share them by importing the necessary modules. This saves you time and helps keep your app lean.
Recuerda, los componentes, directivas y pipes pertenecen a un solo módulo. Solo se necesita declararlos una vez en tu aplicación porque se comparten importando los módulos necesarios. Esto ahorra tiempo y ayuda a mantener la aplicación optimizada.
{@a imports} {@a imports}
## The `imports` array ## El array de `imports`
The module's `imports` array appears exclusively in the `@NgModule` metadata object. El array de `imports` del módulo aparece exclusivamente en el objeto de metadatos del `@NgModule`.
It tells Angular about other NgModules that this particular module needs to function properly. Le dice a Angular sobre otros NgModules que este módulo en particular necesita para funcionar correctamente.
This list of modules are those that export components, directives, or pipes Esta lista de módulos son los que exportan componentes, directivas o pipes
that the component templates in this module reference. In this case, the component is que las plantillas de componentes en este módulo hacen referencia. En este caso, el componente es
`AppComponent`, which references components, directives, or pipes in `BrowserModule`, `AppComponent`, que hace referencia a componentes, directivas o pipes en `BrowserModule`,
`FormsModule`, or `HttpClientModule`. `FormsModule`, o `HttpClientModule`.
A component template can reference another component, directive, Una plantilla de componente puede hacer referencia a otro componente, directiva,
or pipe when the referenced class is declared in this module or o pipe cuando la clase referenciada se declara en este módulo o
the class was imported from another module. la clase se importó de otro módulo.
{@a bootstrap-array} {@a bootstrap-array}
## The `providers` array ## El array `providers`
The providers array is where you list the services the app needs. When El array `providers` es donde se enumeran los servicios que necesita la aplicación. Cuando
you list services here, they are available app-wide. You can scope enumera los servicios, están disponibles en toda la aplicación. Puedes reducir el scope
them when using feature modules and lazy loading. For more information, see al usar módulos de funciones y carga diferida. Para más información, ver
[Providers](guide/providers). [Proveedores](guide/providers).
## The `bootstrap` array ## El array `bootstrap`
The application launches by bootstrapping the root `AppModule`, which is La aplicación se inicia haciendo bootstraping desde la raíz `AppModule`, que es
also referred to as an `entryComponent`. también conocido como `entryComponent`.
Among other things, the bootstrapping process creates the component(s) listed in the `bootstrap` array Entre otras cosas, el proceso de carga crea los componentes enumerados en el array de `bootstrap`
and inserts each one into the browser DOM. e inserta cada uno en el DOM del navegador.
Each bootstrapped component is the base of its own tree of components. Cada componente bootstrap es la base de su propio árbol de componentes.
Inserting a bootstrapped component usually triggers a cascade of La inserción de un componente bootstrapped generalmente desencadena una cascada de
component creations that fill out that tree. creaciones de componentes que completan ese árbol.
While you can put more than one component tree on a host web page, Si bien puedes colocar más de un árbol de componentes en una página web de host,
most applications have only one component tree and bootstrap a single root component. la mayoría de las aplicaciones tienen solo un árbol de componentes y arrancan un solo componente raíz.
This one root component is usually called `AppComponent` and is in the Este componente raíz se suele llamar `AppComponent` y se encuentra en el
root module's `bootstrap` array. array `bootstrap` del módulo raíz.
## Más sobre módulos Angular
## More about Angular Modules Para obtener más información sobre NgModules que probablemente veas con frecuencia en las aplicaciones,
consulta [Módulos de uso frecuente](guide/frequent-ngmodules).
For more on NgModules you're likely to see frequently in apps,
see [Frequently Used Modules](guide/frequent-ngmodules).

View File

@ -526,7 +526,7 @@ For example:
// __Zone_enable_cross_context_check = true; // __Zone_enable_cross_context_check = true;
&lt;/script> &lt;/script>
&lt;!-- zone.js required by Angular --> &lt;!-- zone.js required by Angular -->
&lt;script src="node_modules/zone.js/dist/zone.js">&lt;/script> &lt;script src="node_modules/zone.js/bundles/zone.umd.js">&lt;/script>
&lt;!-- application polyfills --> &lt;!-- application polyfills -->
</code-example> </code-example>

View File

@ -10,7 +10,7 @@
</tr> </tr>
<tr> <tr>
<td><code><b>platformBrowserDynamic().bootstrapModule</b>(AppModule);</code></td> <td><code><b>platformBrowserDynamic().bootstrapModule</b>(AppModule);</code></td>
<td><p>Bootstraps the app, using the root component from the specified <code>NgModule</code>. </p> <td><p>Carga la app, usando el componente raíz del <code>NgModule</code> especificado.</p>
</td> </td>
</tr> </tr>
</tbody></table> </tbody></table>
@ -24,370 +24,371 @@
</tr> </tr>
<tr> <tr>
<td><code>@<b>NgModule</b>({ declarations: ..., imports: ...,<br> exports: ..., providers: ..., bootstrap: ...})<br>class MyModule {}</code></td> <td><code>@<b>NgModule</b>({ declarations: ..., imports: ...,<br> exports: ..., providers: ..., bootstrap: ...})<br>class MyModule {}</code></td>
<td><p>Defines a module that contains components, directives, pipes, and providers.</p> <td><p>Define un módulo que contiene componentes, directivas, pipes y proveedores.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code><b>declarations:</b> [MyRedComponent, MyBlueComponent, MyDatePipe]</code></td> <td><code><b>declarations:</b> [MyRedComponent, MyBlueComponent, MyDatePipe]</code></td>
<td><p>List of components, directives, and pipes that belong to this module.</p> <td><p>Lista de componentes, directivas y pipes que pertenecen a este módulo.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code><b>imports:</b> [BrowserModule, SomeOtherModule]</code></td> <td><code><b>imports:</b> [BrowserModule, SomeOtherModule]</code></td>
<td><p>List of modules to import into this module. Everything from the imported modules <td><p>Lista de módulos para importar en este módulo. Todo, desde los módulos importados,
is available to <code>declarations</code> of this module.</p> está disponible para las declaraciones (<code>declarations</code>) de este módulo.
</td> </td>
</tr><tr> </tr><tr>
<td><code><b>exports:</b> [MyRedComponent, MyDatePipe]</code></td> <td><code><b>exports:</b> [MyRedComponent, MyDatePipe]</code></td>
<td><p>List of components, directives, and pipes visible to modules that import this module.</p> <td><p>Lista de componentes, directivas y pipes visibles a los módulos que importan este módulo.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code><b>providers:</b> [MyService, { provide: ... }]</code></td> <td><code><b>providers:</b> [MyService, { provide: ... }]</code></td>
<td><p>List of dependency injection providers visible both to the contents of this module and to importers of this module.</p> <td><p>Lista de proveedores de inyección de dependencias visibles tanto para los contenidos de este módulo como para los importadores de este módulo.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code><b>entryComponents:</b> [SomeComponent, OtherComponent]</code></td> <td><code><b>entryComponents:</b> [SomeComponent, OtherComponent]</code></td>
<td><p>List of components not referenced in any reachable template, for example dynamically created from code.</p></td> <td><p>Lista de componentes no referenciados en cualquier plantilla accesible, por ejemplo, creada dinámicamente a partir de código.</p></td>
</tr><tr> </tr><tr>
<td><code><b>bootstrap:</b> [MyAppComponent]</code></td> <td><code><b>bootstrap:</b> [MyAppComponent]</code></td>
<td><p>List of components to bootstrap when this module is bootstrapped.</p> <td><p>Lista de componentes a empaquetar cuando este módulo se inicia.</p>
</td> </td>
</tr> </tr>
</tbody></table> </tbody></table>
<table class="is-full-width is-fixed-layout"> <table class="is-full-width is-fixed-layout">
<tbody><tr> <tbody><tr>
<th>Template syntax</th> <th>Sintaxis de plantilla</th>
<th></th> <th></th>
</tr> </tr>
<tr> <tr>
<td><code>&lt;input <b>[value]</b>="firstName"&gt;</code></td> <td><code>&lt;input <b>[value]</b>="firstName"&gt;</code></td>
<td><p>Binds property <code>value</code> to the result of expression <code>firstName</code>.</p> <td><p>Vincula la propiedad <code>value</code> al resultado de la expresión <code>firstName</code>.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code>&lt;div <b>[attr.role]</b>="myAriaRole"&gt;</code></td> <td><code>&lt;div <b>[attr.role]</b>="myAriaRole"&gt;</code></td>
<td><p>Binds attribute <code>role</code> to the result of expression <code>myAriaRole</code>.</p> <td><p>Vincula el atributo <code>role</code> al resultado de la expresión <code>myAriaRole</code>.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code>&lt;div <b>[class.extra-sparkle]</b>="isDelightful"&gt;</code></td> <td><code>&lt;div <b>[class.extra-sparkle]</b>="isDelightful"&gt;</code></td>
<td><p>Binds the presence of the CSS class <code>extra-sparkle</code> on the element to the truthiness of the expression <code>isDelightful</code>.</p> <td><p>Vincula la presencia de la clase CSS <code>extra-sparkle</code> sobre el elemento a la veracidad de la expresión <code>isDelightful</code>.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code>&lt;div <b>[style.width.px]</b>="mySize"&gt;</code></td> <td><code>&lt;div <b>[style.width.px]</b>="mySize"&gt;</code></td>
<td><p>Binds style property <code>width</code> to the result of expression <code>mySize</code> in pixels. Units are optional.</p> <td><p>Vincula la propiedad de estilo <code>width</code> al resultado de la expresión <code>mySize</code> en píxeles. La unidad de medida es opcional.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code>&lt;button <b>(click)</b>="readRainbow($event)"&gt;</code></td> <td><code>&lt;button <b>(click)</b>="readRainbow($event)"&gt;</code></td>
<td><p>Calls method <code>readRainbow</code> when a click event is triggered on this button element (or its children) and passes in the event object.</p> <td><p>Llama al método <code>readRainbow</code> cuando se lanza un evento click en este elemento botón (o sus hijos) y pasa por argumento el objeto evento.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code>&lt;div title="Hello <b>{{ponyName}}</b>"&gt;</code></td> <td><code>&lt;div title="Hola <b>{{ponyName}}</b>"&gt;</code></td>
<td><p>Binds a property to an interpolated string, for example, "Hello Seabiscuit". Equivalent to: <td><p>Vincula una propiedad a una cadena interpolada, por ejemplo, "Hola Seabiscuit". Equivalente a:
<code>&lt;div [title]="'Hello ' + ponyName"&gt;</code></p> <code>&lt;div [title]="'Hola ' + ponyName"&gt;</code></p>
</td> </td>
</tr><tr> </tr><tr>
<td><code>&lt;p&gt;Hello <b>{{ponyName}}</b>&lt;/p&gt;</code></td> <td><code>&lt;p&gt;Hola <b>{{ponyName}}</b>&lt;/p&gt;</code></td>
<td><p>Binds text content to an interpolated string, for example, "Hello Seabiscuit".</p> <td><p>Vincula el contenido de texto a una cadena interpolada, por ejemplo, "Hola Seabiscuit".</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code>&lt;my-cmp <b>[(title)]</b>="name"&gt;</code></td> <td><code>&lt;my-cmp <b>[(title)]</b>="name"&gt;</code></td>
<td><p>Sets up two-way data binding. Equivalent to: <code>&lt;my-cmp [title]="name" (titleChange)="name=$event"&gt;</code></p> <td><p>Establece el two-way data binding. Equivalente a: <code>&lt;my-cmp [title]="name" (titleChange)="name=$event"&gt;</code></p>
</td> </td>
</tr><tr> </tr><tr>
<td><code>&lt;video <b>#movieplayer</b> ...&gt;<br> &lt;button <b>(click)</b>="movieplayer.play()"&gt;<br>&lt;/video&gt;</code></td> <td><code>&lt;video <b>#movieplayer</b> ...&gt;<br> &lt;button <b>(click)</b>="movieplayer.play()"&gt;<br>&lt;/video&gt;</code></td>
<td><p>Creates a local variable <code>movieplayer</code> that provides access to the <code>video</code> element instance in data-binding and event-binding expressions in the current template.</p> <td><p>Crea una variable local <code>movieplayer</code> que provee acceso a la instancia del elemento <code>video</code> en las expresiones de data-binding y event-binding de la actual plantilla.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code>&lt;p <b>*myUnless</b>="myExpression"&gt;...&lt;/p&gt;</code></td> <td><code>&lt;p <b>*myUnless</b>="myExpression"&gt;...&lt;/p&gt;</code></td>
<td><p>The <code>*</code> symbol turns the current element into an embedded template. Equivalent to: <td><p>El símbolo <code>*</code> convierte el elemento actual en una plantilla incrustada. Equivalente a:
<code>&lt;ng-template [myUnless]="myExpression"&gt;&lt;p&gt;...&lt;/p&gt;&lt;/ng-template&gt;</code></p> <code>&lt;ng-template [myUnless]="myExpression"&gt;&lt;p&gt;...&lt;/p&gt;&lt;/ng-template&gt;</code></p>
</td> </td>
</tr><tr> </tr><tr>
<td><code>&lt;p&gt;Card No.: <b>{{cardNumber | myCardNumberFormatter}}</b>&lt;/p&gt;</code></td> <td><code>&lt;p&gt;Card No.: <b>{{cardNumber | myCardNumberFormatter}}</b>&lt;/p&gt;</code></td>
<td><p>Transforms the current value of expression <code>cardNumber</code> via the pipe called <code>myCardNumberFormatter</code>.</p> <td><p>Transforma el valor actual de la expresión <code>cardNumber</code> a través de la pipe <code>myCardNumberFormatter</code>.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code>&lt;p&gt;Employer: <b>{{employer?.companyName}}</b>&lt;/p&gt;</code></td> <td><code>&lt;p&gt;Employer: <b>{{employer?.companyName}}</b>&lt;/p&gt;</code></td>
<td><p>The safe navigation operator (<code>?</code>) means that the <code>employer</code> field is optional and if <code>undefined</code>, the rest of the expression should be ignored.</p> <td><p>El operador de navegación seguro (<code>?</code>) significa que el campo <code>employer</code> es opcional y que si es <code>undefined</code>, el resto de la expresión debería ser ignorado.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code>&lt;<b>svg:</b>rect x="0" y="0" width="100" height="100"/&gt;</code></td> <td><code>&lt;<b>svg:</b>rect x="0" y="0" width="100" height="100"/&gt;</code></td>
<td><p>An SVG snippet template needs an <code>svg:</code> prefix on its root element to disambiguate the SVG element from an HTML component.</p> <td><p>Una plantilla de fragmento SVG necesita un prefijo <code>svg:</code> en su elemento raíz para distinguir el elemento SVG de un componente HTML.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code>&lt;<b>svg</b>&gt;<br> &lt;rect x="0" y="0" width="100" height="100"/&gt;<br>&lt;/<b>svg</b>&gt;</code></td> <td><code>&lt;<b>svg</b>&gt;<br> &lt;rect x="0" y="0" width="100" height="100"/&gt;<br>&lt;/<b>svg</b>&gt;</code></td>
<td><p>An <code>&lt;svg&gt;</code> root element is detected as an SVG element automatically, without the prefix.</p> <td><p>Un elemento raíz <code>&lt;svg&gt;</code> es detectado como un elemento SVG automáticamente, sin el prefijo.</p>
</td> </td>
</tr> </tr>
</tbody></table> </tbody></table>
<table class="is-full-width is-fixed-layout"> <table class="is-full-width is-fixed-layout">
<tbody><tr> <tbody><tr>
<th>Built-in directives</th> <th>Directivas incorporadas</th>
<th><p><code>import { CommonModule } from '@angular/common';</code> <th><p><code>import { CommonModule } from '@angular/common';</code>
</p> </p>
</th> </th>
</tr> </tr>
<tr> <tr>
<td><code>&lt;section <b>*ngIf</b>="showSection"&gt;</code></td> <td><code>&lt;section <b>*ngIf</b>="showSection"&gt;</code></td>
<td><p>Removes or recreates a portion of the DOM tree based on the <code>showSection</code> expression.</p> <td><p>Elimina o recrea una parte del árbol DOM basado en la expresión <code>showSection</code>.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code>&lt;li <b>*ngFor</b>="let item of list"&gt;</code></td> <td><code>&lt;li <b>*ngFor</b>="let item of list"&gt;</code></td>
<td><p>Turns the li element and its contents into a template, and uses that to instantiate a view for each item in list.</p> <td><p>Convierte el elemento li y su contenido en una plantilla, y lo utiliza para crear una vista por cada elemento de la lista.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code>&lt;div <b>[ngSwitch]</b>="conditionExpression"&gt;<br> &lt;ng-template <b>[<b>ngSwitchCase</b>]</b>="case1Exp"&gt;...&lt;/ng-template&gt;<br> &lt;ng-template <b>ngSwitchCase</b>="case2LiteralString"&gt;...&lt;/ng-template&gt;<br> &lt;ng-template <b>ngSwitchDefault</b>&gt;...&lt;/ng-template&gt;<br>&lt;/div&gt;</code></td> <td><code>&lt;div <b>[ngSwitch]</b>="conditionExpression"&gt;<br> &lt;ng-template <b>[<b>ngSwitchCase</b>]</b>="case1Exp"&gt;...&lt;/ng-template&gt;<br> &lt;ng-template <b>ngSwitchCase</b>="case2LiteralString"&gt;...&lt;/ng-template&gt;<br> &lt;ng-template <b>ngSwitchDefault</b>&gt;...&lt;/ng-template&gt;<br>&lt;/div&gt;</code></td>
<td><p>Conditionally swaps the contents of the div by selecting one of the embedded templates based on the current value of <code>conditionExpression</code>.</p> <td><p>Intercambia condicionalmente el contenido del div seleccionando una de las plantillas incrustadas en función del valor actual de <code>conditionExpression</code>.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code>&lt;div <b>[ngClass]</b>="{'active': isActive, 'disabled': isDisabled}"&gt;</code></td> <td><code>&lt;div <b>[ngClass]</b>="{'active': isActive, 'disabled': isDisabled}"&gt;</code></td>
<td><p>Binds the presence of CSS classes on the element to the truthiness of the associated map values. The right-hand expression should return {class-name: true/false} map.</p> <td><p>Vincula la presencia de clases CSS en el elemento a la veracidad de los valores de mapa asociados. La expresión de la derecha debería devolver el mapa {class-name: true/false}.</p>
</td> </td>
</tr> </tr>
<tr> <tr>
<td><code>&lt;div <b>[ngStyle]</b>="{'property': 'value'}"&gt;</code><br><code>&lt;div <b>[ngStyle]</b>="dynamicStyles()"&gt;</code></td> <td><code>&lt;div <b>[ngStyle]</b>="{'property': 'value'}"&gt;</code><br><code>&lt;div <b>[ngStyle]</b>="dynamicStyles()"&gt;</code></td>
<td><p>Allows you to assign styles to an HTML element using CSS. You can use CSS directly, as in the first example, or you can call a method from the component.</p> <p>Te permite asignar estilos a un elemento HTML usando CSS. Puedes usar CSS directamente, como en el primer ejemplo, o puedes llamar a un método desde el componente.</p>
</td> </td>
</tr> </tr>
</tbody></table> </tbody></table>
<table class="is-full-width is-fixed-layout"> <table class="is-full-width is-fixed-layout">
<tbody><tr> <tbody><tr>
<th>Forms</th> <th>Formularios</th>
<th><p><code>import { FormsModule } from '@angular/forms';</code> <th><p><code>import { FormsModule } from '@angular/forms';</code>
</p> </p>
</th> </th>
</tr> </tr>
<tr> <tr>
<td><code>&lt;input <b>[(ngModel)]</b>="userName"&gt;</code></td> <td><code>&lt;input <b>[(ngModel)]</b>="userName"&gt;</code></td>
<td><p>Provides two-way data-binding, parsing, and validation for form controls.</p> <td><p>Provee two-way data-binding, conversión y validación para controles de formulario.</p>
</td> </td>
</tr> </tr>
</tbody></table> </tbody></table>
<table class="is-full-width is-fixed-layout"> <table class="is-full-width is-fixed-layout">
<tbody><tr> <tbody><tr>
<th>Class decorators</th> <th>Decoradores de clases</th>
<th><p><code>import { Directive, ... } from '@angular/core';</code> <th><p><code>import { Directive, ... } from '@angular/core';</code>
</p> </p>
</th> </th>
</tr> </tr>
<tr> <tr>
<td><code><b>@Component({...})</b><br>class MyComponent() {}</code></td> <td><code><b>@Component({...})</b><br>class MyComponent() {}</code></td>
<td><p>Declares that a class is a component and provides metadata about the component.</p> <td><p>Declara que una clase es un componente y proporciona metadatos sobre el componente.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code><b>@Directive({...})</b><br>class MyDirective() {}</code></td> <td><code><b>@Directive({...})</b><br>class MyDirective() {}</code></td>
<td><p>Declares that a class is a directive and provides metadata about the directive.</p> <td><p>Declara que una clase es una directiva y proporciona metadatos sobre la directiva.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code><b>@Pipe({...})</b><br>class MyPipe() {}</code></td> <td><code><b>@Pipe({...})</b><br>class MyPipe() {}</code></td>
<td><p>Declares that a class is a pipe and provides metadata about the pipe.</p> <td><p>Declara que una clase es una pipe y proporciona metadatos sobre la pipe.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code><b>@Injectable()</b><br>class MyService() {}</code></td> <td><code><b>@Injectable()</b><br>class MyService() {}</code></td>
<td><p>Declares that a class can be provided and injected by other classes. Without this decorator, the compiler won't generate enough metadata to allow the class to be created properly when it's injected somewhere.</p> <td><p>Declara que una clase puede ser proporcionada e inyectada por otras clases. Sin este decorador, el compilador no generará suficientes metadatos para permitir que la clase se cree correctamente cuando se inyecta en alguna parte.</p>
</td> </td>
</tr> </tr>
</tbody></table> </tbody></table>
<table class="is-full-width is-fixed-layout"> <table class="is-full-width is-fixed-layout">
<tbody><tr> <tbody><tr>
<th>Directive configuration</th> <th>Configuración de Directiva</th>
<th><p><code>@Directive({ property1: value1, ... })</code> <th><p><code>@Directive({ property1: value1, ... })</code>
</p> </p>
</th> </th>
</tr> </tr>
<tr> <tr>
<td><code><b>selector:</b> '.cool-button:not(a)'</code></td> <td><code><b>selector:</b> '.cool-button:not(a)'</code></td>
<td><p>Specifies a CSS selector that identifies this directive within a template. Supported selectors include <code>element</code>, <td><p>Especifica un selector CSS que identifica esta directiva dentro de una plantilla. Los selectores compatibles incluyen <code>element</code>,
<code>[attribute]</code>, <code>.class</code>, and <code>:not()</code>.</p> <code>[attribute]</code>, <code>.class</code>, and <code>:not()</code>.</p>
<p>Does not support parent-child relationship selectors.</p> <p>No soporta selectores de relación padre-hijo.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code><b>providers:</b> [MyService, { provide: ... }]</code></td> <td><code><b>providers:</b> [MyService, { provide: ... }]</code></td>
<td><p>List of dependency injection providers for this directive and its children.</p> <td><p>Lista de proveedores de inyección de dependencia para esta directiva y sus hijos.</p>
</td> </td>
</tr> </tr>
</tbody></table> </tbody></table>
<table class="is-full-width is-fixed-layout"> <table class="is-full-width is-fixed-layout">
<tbody><tr> <tbody><tr>
<th>Component configuration</th> <th>Configuración de Componente</th>
<th><p> <th><p>
<code>@Component</code> extends <code>@Directive</code>, <code>@Component</code> extiende <code>@Directive</code>,
so the <code>@Directive</code> configuration applies to components as well</p> entonces la configuración de <code>@Directive</code> se aplica también a los componentes</p>
</th> </th>
</tr> </tr>
<tr> <tr>
<td><code><b>moduleId:</b> module.id</code></td> <td><code><b>moduleId:</b> module.id</code></td>
<td><p>If set, the <code>templateUrl</code> and <code>styleUrl</code> are resolved relative to the component.</p> <td><p>Si está presente, el <code>templateUrl</code> y <code>styleUrl</code> se resuelven en relación con el componente.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code><b>viewProviders:</b> [MyService, { provide: ... }]</code></td> <td><code><b>viewProviders:</b> [MyService, { provide: ... }]</code></td>
<td><p>List of dependency injection providers scoped to this component's view.</p> <td><p>Lista de proveedores de inyección de dependencias en la vista de este componente.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code><b>template:</b> 'Hello {{name}}'<br><b>templateUrl:</b> 'my-component.html'</code></td> <td><code><b>template:</b> 'Hola {{name}}'<br><b>templateUrl:</b> 'my-component.html'</code></td>
<td><p>Inline template or external template URL of the component's view.</p> <td><p>Plantilla en línea o URL de plantilla externa de la vista del componente.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code><b>styles:</b> ['.primary {color: red}']<br><b>styleUrls:</b> ['my-component.css']</code></td> <td><code><b>styles:</b> ['.primary {color: red}']<br><b>styleUrls:</b> ['my-component.css']</code></td>
<td><p>List of inline CSS styles or external stylesheet URLs for styling the components view.</p> <td><p>Lista de estilos CSS en línea o URL de hojas de estilo externas para estilar la vista del componente.</p>
</td> </td>
</tr> </tr>
</tbody></table> </tbody></table>
<table class="is-full-width is-fixed-layout"> <table class="is-full-width is-fixed-layout">
<tbody><tr> <tbody><tr>
<th>Class field decorators for directives and components</th> <th>Decoradores para los campos de la clase para directivas y componentes.</th>
<th><p><code>import { Input, ... } from '@angular/core';</code> <th><p><code>import { Input, ... } from '@angular/core';</code>
</p> </p>
</th> </th>
</tr> </tr>
<tr> <tr>
<td><code><b>@Input()</b> myProperty;</code></td> <td><code><b>@Input()</b> myProperty;</code></td>
<td><p>Declares an input property that you can update via property binding (example: <td><p>Declara una propiedad de entrada (input) que puede actualizar mediante el enlace de propiedad (property binding) (ejemplo:
<code>&lt;my-cmp [myProperty]="someExpression"&gt;</code>).</p> <code>&lt;my-cmp [myProperty]="someExpression"&gt;</code>).</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code><b>@Output()</b> myEvent = new EventEmitter();</code></td> <td><code><b>@Output()</b> myEvent = new EventEmitter();</code></td>
<td><p>Declares an output property that fires events that you can subscribe to with an event binding (example: <code>&lt;my-cmp (myEvent)="doSomething()"&gt;</code>).</p> <td><p>Declara una propiedad de salida (output) que dispara eventos a los que puedes suscribirse con un enlace de evento (event binding) (ejemplo: <code>&lt;my-cmp (myEvent)="doSomething()"&gt;</code>).</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code><b>@HostBinding('class.valid')</b> isValid;</code></td> <td><code><b>@HostBinding('class.valid')</b> isValid;</code></td>
<td><p>Binds a host element property (here, the CSS class <code>valid</code>) to a directive/component property (<code>isValid</code>).</p> <td><p>Vincula una propiedad del elemento anfitrión (aquí, la clase CSS <code>valid</code>) a una propiedad de directiva/componente (<code>isValid</code>).</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code><b>@HostListener('click', ['$event'])</b> onClick(e) {...}</code></td> <td><code><b>@HostListener('click', ['$event'])</b> onClick(e) {...}</code></td>
<td><p>Subscribes to a host element event (<code>click</code>) with a directive/component method (<code>onClick</code>), optionally passing an argument (<code>$event</code>).</p> <td><p>Se suscribe a un evento del elemento anfitrión (<code>click</code>) con un método de directiva/componente (<code>onClick</code>), opcionalmente, pasando un argumento (<code>$event</code>).</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code><b>@ContentChild(myPredicate)</b> myChildComponent;</code></td> <td><code><b>@ContentChild(myPredicate)</b> myChildComponent;</code></td>
<td><p>Binds the first result of the component content query (<code>myPredicate</code>) to a property (<code>myChildComponent</code>) of the class.</p> <td><p>Vincula el primer resultado de la consulta de contenido del componente (<code>myPredicate</code>) a una propiedad (<code>myChildComponent</code>) de la clase.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code><b>@ContentChildren(myPredicate)</b> myChildComponents;</code></td> <td><code><b>@ContentChildren(myPredicate)</b> myChildComponents;</code></td>
<td><p>Binds the results of the component content query (<code>myPredicate</code>) to a property (<code>myChildComponents</code>) of the class.</p> <td><p>Vincula los resultados de la consulta de contenido del componente (<code>myPredicate</code>) a una propiedad (<code>myChildComponents</code>) de la clase.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code><b>@ViewChild(myPredicate)</b> myChildComponent;</code></td> <td><code><b>@ViewChild(myPredicate)</b> myChildComponent;</code></td>
<td><p>Binds the first result of the component view query (<code>myPredicate</code>) to a property (<code>myChildComponent</code>) of the class. Not available for directives.</p> <td><p>Vincula el primer resultado de la consulta de vista del componente (<code>myPredicate</code>) a una propiedad (<code>myChildComponent</code>) de la clase. No disponible para directivas.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code><b>@ViewChildren(myPredicate)</b> myChildComponents;</code></td> <td><code><b>@ViewChildren(myPredicate)</b> myChildComponents;</code></td>
<td><p>Binds the results of the component view query (<code>myPredicate</code>) to a property (<code>myChildComponents</code>) of the class. Not available for directives.</p> <td><p>Vincula los resultados de la consulta de vista del componente (<code>myPredicate</code>) a una propiedad (<code>myChildComponents</code>) de la clase. No disponible para directivas.</p>
</td> </td>
</tr> </tr>
</tbody></table> </tbody></table>
<table class="is-full-width is-fixed-layout"> <table class="is-full-width is-fixed-layout">
<tbody><tr> <tbody><tr>
<th>Directive and component change detection and lifecycle hooks</th>
<th><p>(implemented as class methods) <th>Detección de cambios (change detection) y ciclos de vida (lifecycle hooks) en directivas y componentes</th>
<th><p>(implementado como métodos de clase)
</p> </p>
</th> </th>
</tr> </tr>
<tr> <tr>
<td><code><b>constructor(myService: MyService, ...)</b> { ... }</code></td> <td><code><b>constructor(myService: MyService, ...)</b> { ... }</code></td>
<td><p>Called before any other lifecycle hook. Use it to inject dependencies, but avoid any serious work here.</p> <td><p>Se llama antes que cualquier ciclo de vida. Úselo para inyectar dependencias, pero evite cualquier trabajo serio aquí.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code><b>ngOnChanges(changeRecord)</b> { ... }</code></td> <td><code><b>ngOnChanges(changeRecord)</b> { ... }</code></td>
<td><p>Called after every change to input properties and before processing content or child views.</p> <td><p>Se llama después de cada cambio en las propiedades de entrada (input) y antes de procesar contenido o vistas de hijos.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code><b>ngOnInit()</b> { ... }</code></td> <td><code><b>ngOnInit()</b> { ... }</code></td>
<td><p>Called after the constructor, initializing input properties, and the first call to <code>ngOnChanges</code>.</p> <td><p>Se llama después del constructor, inicializando propiedades de entrada (input), y la primera llamada a <code>ngOnChanges</code>.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code><b>ngDoCheck()</b> { ... }</code></td> <td><code><b>ngDoCheck()</b> { ... }</code></td>
<td><p>Called every time that the input properties of a component or a directive are checked. Use it to extend change detection by performing a custom check.</p> <td><p>Se llama cada vez que se verifican las propiedades de entrada (input) de un componente o una directiva. Úselo para extender la detección de cambios (change detection) realizando una verificación personalizada.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code><b>ngAfterContentInit()</b> { ... }</code></td> <td><code><b>ngAfterContentInit()</b> { ... }</code></td>
<td><p>Called after <code>ngOnInit</code> when the component's or directive's content has been initialized.</p> <td><p>Se llama después de <code>ngOnInit</code> cuando el contenido del componente o directiva ha sido inicializado.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code><b>ngAfterContentChecked()</b> { ... }</code></td> <td><code><b>ngAfterContentChecked()</b> { ... }</code></td>
<td><p>Called after every check of the component's or directive's content.</p> <td><p>Se llama después de cada verificación del contenido del componente o directiva.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code><b>ngAfterViewInit()</b> { ... }</code></td> <td><code><b>ngAfterViewInit()</b> { ... }</code></td>
<td><p>Called after <code>ngAfterContentInit</code> when the component's views and child views / the view that a directive is in has been initialized.</p> <td><p>Se llama después de <code>ngAfterContentInit</code> cuando las vistas del componente y las vistas hijas / la vista en la que se encuentra una directiva ha sido inicializado.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code><b>ngAfterViewChecked()</b> { ... }</code></td> <td><code><b>ngAfterViewChecked()</b> { ... }</code></td>
<td><p>Called after every check of the component's views and child views / the view that a directive is in.</p> <td><p>Se llama después de cada verificación de las vistas del componentes y las vistas hijas / la vista en la que se encuentra una directiva.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code><b>ngOnDestroy()</b> { ... }</code></td> <td><code><b>ngOnDestroy()</b> { ... }</code></td>
<td><p>Called once, before the instance is destroyed.</p> <td><p>Se llama una vez, antes de que la instancia se destruya.</p>
</td> </td>
</tr> </tr>
</tbody></table> </tbody></table>
<table class="is-full-width is-fixed-layout"> <table class="is-full-width is-fixed-layout">
<tbody><tr> <tbody><tr>
<th>Dependency injection configuration</th> <th>Configuración de inyección de dependencia</th>
<th></th> <th></th>
</tr> </tr>
<tr> <tr>
<td><code>{ <b>provide</b>: MyService, <b>useClass</b>: MyMockService }</code></td> <td><code>{ <b>provide</b>: MyService, <b>useClass</b>: MyMockService }</code></td>
<td><p>Sets or overrides the provider for <code>MyService</code> to the <code>MyMockService</code> class.</p> <td><p>Establece o sobre-escribe el proveedor para <code>MyService</code> en la clase <code>MyMockService</code>.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code>{ <b>provide</b>: MyService, <b>useFactory</b>: myFactory }</code></td> <td><code>{ <b>provide</b>: MyService, <b>useFactory</b>: myFactory }</code></td>
<td><p>Sets or overrides the provider for <code>MyService</code> to the <code>myFactory</code> factory function.</p> <td><p>Establece o sobre-escribe el proveedor para <code>MyService</code> en la factoría de función <code>myFactory</code>.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code>{ <b>provide</b>: MyValue, <b>useValue</b>: 41 }</code></td> <td><code>{ <b>provide</b>: MyValue, <b>useValue</b>: 41 }</code></td>
<td><p>Sets or overrides the provider for <code>MyValue</code> to the value <code>41</code>.</p> <td><p>Establece o sobre-escribe el proveedor para <code>MyValue</code> al valor <code>41</code>.</p>
</td> </td>
</tr> </tr>
</tbody></table> </tbody></table>
<table class="is-full-width is-fixed-layout"> <table class="is-full-width is-fixed-layout">
<tbody><tr> <tbody><tr>
<th>Routing and navigation</th> <th>Enrutamiento y navegación</th>
<th><p><code>import { Routes, RouterModule, ... } from '@angular/router';</code> <th><p><code>import { Routes, RouterModule, ... } from '@angular/router';</code>
</p> </p>
</th> </th>
</tr> </tr>
<tr> <tr>
<td><code>const routes: <b>Routes</b> = [<br> { path: '', component: HomeComponent },<br> { path: 'path/:routeParam', component: MyComponent },<br> { path: 'staticPath', component: ... },<br> { path: '**', component: ... },<br> { path: 'oldPath', redirectTo: '/staticPath' },<br> { path: ..., component: ..., data: { message: 'Custom' } }<br>]);<br><br>const routing = RouterModule.forRoot(routes);</code></td> <td><code>const routes: <b>Routes</b> = [<br> { path: '', component: HomeComponent },<br> { path: 'path/:routeParam', component: MyComponent },<br> { path: 'staticPath', component: ... },<br> { path: '**', component: ... },<br> { path: 'oldPath', redirectTo: '/staticPath' },<br> { path: ..., component: ..., data: { message: 'Custom' } }<br>]);<br><br>const routing = RouterModule.forRoot(routes);</code></td>
<td><p>Configures routes for the application. Supports static, parameterized, redirect, and wildcard routes. Also supports custom route data and resolve.</p> <td><p>Configura rutas para la aplicación. Soporta rutas estáticas, parametrizadas, de redireccionamiento y comodines. También soporta datos de ruta personalizados y los resuelve.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code><br>&lt;<b>router-outlet</b>&gt;&lt;/<b>router-outlet</b>&gt;<br>&lt;<b>router-outlet</b> name="aux"&gt;&lt;/<b>router-outlet</b>&gt;<br></code></td> <td><code><br>&lt;<b>router-outlet</b>&gt;&lt;/<b>router-outlet</b>&gt;<br>&lt;<b>router-outlet</b> name="aux"&gt;&lt;/<b>router-outlet</b>&gt;<br></code></td>
<td><p>Marks the location to load the component of the active route.</p> <td><p>Marca la ubicación para cargar el componente de la ruta activa.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code><br>&lt;a routerLink="/path"&gt;<br>&lt;a <b>[routerLink]</b>="[ '/path', routeParam ]"&gt;<br>&lt;a <b>[routerLink]</b>="[ '/path', { matrixParam: 'value' } ]"&gt;<br>&lt;a <b>[routerLink]</b>="[ '/path' ]" [queryParams]="{ page: 1 }"&gt;<br>&lt;a <b>[routerLink]</b>="[ '/path' ]" fragment="anchor"&gt;<br></code></td> <td><code><br>&lt;a routerLink="/path"&gt;<br>&lt;a <b>[routerLink]</b>="[ '/path', routeParam ]"&gt;<br>&lt;a <b>[routerLink]</b>="[ '/path', { matrixParam: 'value' } ]"&gt;<br>&lt;a <b>[routerLink]</b>="[ '/path' ]" [queryParams]="{ page: 1 }"&gt;<br>&lt;a <b>[routerLink]</b>="[ '/path' ]" fragment="anchor"&gt;<br></code></td>
<td><p>Creates a link to a different view based on a route instruction consisting of a route path, required and optional parameters, query parameters, and a fragment. To navigate to a root route, use the <code>/</code> prefix; for a child route, use the <code>./</code>prefix; for a sibling or parent, use the <code>../</code> prefix.</p> <td><p>Crea un enlace a una vista diferente basada en una instrucción de ruta que consta de un camino de de ruta, parámetros obligatorios y opcionales, parámetros de consulta y un fragmento. Para navegar a un camino de ruta, usa el prefijo <code>/</code>; para una ruta hija, usa el prefijo <code>./</code>; para un padre o hermano, usa el prefijo <code>../</code>.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code>&lt;a [routerLink]="[ '/path' ]" routerLinkActive="active"&gt;</code></td> <td><code>&lt;a [routerLink]="[ '/path' ]" routerLinkActive="active"&gt;</code></td>
<td><p>The provided classes are added to the element when the <code>routerLink</code> becomes the current active route.</p> <td><p>Las clases proporcionadas se agregan al elemento cuando el <code>routerLink</code> se convierte en la ruta activa actual.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code>class <b>CanActivate</b>Guard implements <b>CanActivate</b> {<br> canActivate(<br> route: ActivatedRouteSnapshot,<br> state: RouterStateSnapshot<br> ): Observable&lt;boolean|UrlTree&gt;|Promise&lt;boolean|UrlTree&gt;|boolean|UrlTree { ... }<br>}<br><br>{ path: ..., canActivate: [<b>CanActivate</b>Guard] }</code></td> <td><code>class <b>CanActivate</b>Guard implements <b>CanActivate</b> {<br> canActivate(<br> route: ActivatedRouteSnapshot,<br> state: RouterStateSnapshot<br> ): Observable&lt;boolean|UrlTree&gt;|Promise&lt;boolean|UrlTree&gt;|boolean|UrlTree { ... }<br>}<br><br>{ path: ..., canActivate: [<b>CanActivate</b>Guard] }</code></td>
<td><p>An interface for defining a class that the router should call first to determine if it should activate this component. Should return a boolean|UrlTree or an Observable/Promise that resolves to a boolean|UrlTree.</p> <td><p>Una interfaz para definir una clase que el enrutador debe llamar primero para determinar si debe activar este componente. Debe devolver un boolean|UrlTree o un Observable/Promise que se resuelba en un boolean|UrlTree.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code>class <b>CanDeactivate</b>Guard implements <b>CanDeactivate</b>&lt;T&gt; {<br> canDeactivate(<br> component: T,<br> route: ActivatedRouteSnapshot,<br> state: RouterStateSnapshot<br> ): Observable&lt;boolean|UrlTree&gt;|Promise&lt;boolean|UrlTree&gt;|boolean|UrlTree { ... }<br>}<br><br>{ path: ..., canDeactivate: [<b>CanDeactivate</b>Guard] }</code></td> <td><code>class <b>CanDeactivate</b>Guard implements <b>CanDeactivate</b>&lt;T&gt; {<br> canDeactivate(<br> component: T,<br> route: ActivatedRouteSnapshot,<br> state: RouterStateSnapshot<br> ): Observable&lt;boolean|UrlTree&gt;|Promise&lt;boolean|UrlTree&gt;|boolean|UrlTree { ... }<br>}<br><br>{ path: ..., canDeactivate: [<b>CanDeactivate</b>Guard] }</code></td>
<td><p>An interface for defining a class that the router should call first to determine if it should deactivate this component after a navigation. Should return a boolean|UrlTree or an Observable/Promise that resolves to a boolean|UrlTree.</p> <td><p>Una interfaz para definir una clase que el enrutador debería llamar primero para determinar si debería desactivar este componente después de una navegación. Debe devolver un boolean|UrlTree o un Observable/Promise que se resuelva a boolean|UrlTree.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code>class <b>CanActivateChild</b>Guard implements <b>CanActivateChild</b> {<br> canActivateChild(<br> route: ActivatedRouteSnapshot,<br> state: RouterStateSnapshot<br> ): Observable&lt;boolean|UrlTree&gt;|Promise&lt;boolean|UrlTree&gt;|boolean|UrlTree { ... }<br>}<br><br>{ path: ..., canActivateChild: [CanActivateGuard],<br> children: ... }</code></td> <td><code>class <b>CanActivateChild</b>Guard implements <b>CanActivateChild</b> {<br> canActivateChild(<br> route: ActivatedRouteSnapshot,<br> state: RouterStateSnapshot<br> ): Observable&lt;boolean|UrlTree&gt;|Promise&lt;boolean|UrlTree&gt;|boolean|UrlTree { ... }<br>}<br><br>{ path: ..., canActivateChild: [CanActivateGuard],<br> children: ... }</code></td>
<td><p>An interface for defining a class that the router should call first to determine if it should activate the child route. Should return a boolean|UrlTree or an Observable/Promise that resolves to a boolean|UrlTree.</p> <td><p>Una interfaz para definir una clase que el enrutador debe llamar primero para determinar si debe activar la ruta hija. Debe devolver un boolean|UrlTree o un Observable/Promise que se resuelva en un boolean|UrlTree.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code>class <b>Resolve</b>Guard implements <b>Resolve</b>&lt;T&gt; {<br> resolve(<br> route: ActivatedRouteSnapshot,<br> state: RouterStateSnapshot<br> ): Observable&lt;any&gt;|Promise&lt;any&gt;|any { ... }<br>}<br><br>{ path: ..., resolve: [<b>Resolve</b>Guard] }</code></td> <td><code>class <b>Resolve</b>Guard implements <b>Resolve</b>&lt;T&gt; {<br> resolve(<br> route: ActivatedRouteSnapshot,<br> state: RouterStateSnapshot<br> ): Observable&lt;any&gt;|Promise&lt;any&gt;|any { ... }<br>}<br><br>{ path: ..., resolve: [<b>Resolve</b>Guard] }</code></td>
<td><p>An interface for defining a class that the router should call first to resolve route data before rendering the route. Should return a value or an Observable/Promise that resolves to a value.</p> <td><p>Una interfaz para definir una clase que el enrutador debe llamar primero para resolver los datos de la ruta antes de representar la ruta. Debe devolver un valor o un Observable/Promise que se resuelva en un valor.</p>
</td> </td>
</tr><tr> </tr><tr>
<td><code>class <b>CanLoad</b>Guard implements <b>CanLoad</b> {<br> canLoad(<br> route: Route<br> ): Observable&lt;boolean|UrlTree&gt;|Promise&lt;boolean|UrlTree&gt;|boolean|UrlTree { ... }<br>}<br><br>{ path: ..., canLoad: [<b>CanLoad</b>Guard], loadChildren: ... }</code></td> <td><code>class <b>CanLoad</b>Guard implements <b>CanLoad</b> {<br> canLoad(<br> route: Route<br> ): Observable&lt;boolean|UrlTree&gt;|Promise&lt;boolean|UrlTree&gt;|boolean|UrlTree { ... }<br>}<br><br>{ path: ..., canLoad: [<b>CanLoad</b>Guard], loadChildren: ... }</code></td>
<td><p>An interface for defining a class that the router should call first to check if the lazy loaded module should be loaded. Should return a boolean|UrlTree or an Observable/Promise that resolves to a boolean|UrlTree.</p> <td><p>Una interfaz para definir una clase a la que el enrutador debe llamar primero para verificar si el módulo perezoso cargado (lazy loaded module) debe cargarse. Debe devolver un boolean|UrlTree o un Observable/Promise que se resuelva en un boolean|UrlTree.</p>
</td> </td>
</tr> </tr>
</tbody></table> </tbody></table>

View File

@ -0,0 +1,318 @@
# Observables compared to other techniques
You can often use observables instead of promises to deliver values asynchronously. Similarly, observables can take the place of event handlers. Finally, because observables deliver multiple values, you can use them where you might otherwise build and operate on arrays.
Observables behave somewhat differently from the alternative techniques in each of these situations, but offer some significant advantages. Here are detailed comparisons of the differences.
## Observables compared to promises
Observables are often compared to promises. Here are some key differences:
* Observables are declarative; computation does not start until subscription. Promises execute immediately on creation. This makes observables useful for defining recipes that can be run whenever you need the result.
* Observables provide many values. Promises provide one. This makes observables useful for getting multiple values over time.
* Observables differentiate between chaining and subscription. Promises only have `.then()` clauses. This makes observables useful for creating complex transformation recipes to be used by other part of the system, without causing the work to be executed.
* Observables `subscribe()` is responsible for handling errors. Promises push errors to the child promises. This makes observables useful for centralized and predictable error handling.
### Creation and subscription
* Observables are not executed until a consumer subscribes. The `subscribe()` executes the defined behavior once, and it can be called again. Each subscription has its own computation. Resubscription causes recomputation of values.
<code-example
path="comparing-observables/src/observables.ts"
header="src/observables.ts (observable)"
region="observable">
</code-example>
* Promises execute immediately, and just once. The computation of the result is initiated when the promise is created. There is no way to restart work. All `then` clauses (subscriptions) share the same computation.
<code-example
path="comparing-observables/src/promises.ts"
header="src/promises.ts (promise)"
region="promise">
</code-example>
### Chaining
* Observables differentiate between transformation function such as a map and subscription. Only subscription activates the subscriber function to start computing the values.
<code-example
path="comparing-observables/src/observables.ts"
header="src/observables.ts (chain)"
region="chain">
</code-example>
* Promises do not differentiate between the last `.then` clauses (equivalent to subscription) and intermediate `.then` clauses (equivalent to map).
<code-example
path="comparing-observables/src/promises.ts"
header="src/promises.ts (chain)"
region="chain">
</code-example>
### Cancellation
* Observable subscriptions are cancellable. Unsubscribing removes the listener from receiving further values, and notifies the subscriber function to cancel work.
<code-example
path="comparing-observables/src/observables.ts"
header="src/observables.ts (unsubcribe)"
region="unsubscribe">
</code-example>
* Promises are not cancellable.
### Error handling
* Observable execution errors are delivered to the subscriber's error handler, and the subscriber automatically unsubscribes from the observable.
<code-example
path="comparing-observables/src/observables.ts"
header="src/observables.ts (error)"
region="error">
</code-example>
* Promises push errors to the child promises.
<code-example
path="comparing-observables/src/promises.ts"
header="src/promises.ts (error)"
region="error">
</code-example>
### Cheat sheet
The following code snippets illustrate how the same kind of operation is defined using observables and promises.
<table>
<thead>
<tr>
<th>Operation</th>
<th>Observable</th>
<th>Promise</th>
</tr>
</thead>
<tbody>
<tr>
<td>Creation</td>
<td>
<pre>
new Observable((observer) => {
observer.next(123);
});</pre>
</td>
<td>
<pre>
new Promise((resolve, reject) => {
resolve(123);
});</pre>
</td>
</tr>
<tr>
<td>Transform</td>
<td><pre>obs.pipe(map((value) => value * 2));</pre></td>
<td><pre>promise.then((value) => value * 2);</pre></td>
</tr>
<tr>
<td>Subscribe</td>
<td>
<pre>
sub = obs.subscribe((value) => {
console.log(value)
});</pre>
</td>
<td>
<pre>
promise.then((value) => {
console.log(value);
});</pre>
</td>
</tr>
<tr>
<td>Unsubscribe</td>
<td><pre>sub.unsubscribe();</pre></td>
<td>Implied by promise resolution.</td>
</tr>
</tbody>
</table>
## Observables compared to events API
Observables are very similar to event handlers that use the events API. Both techniques define notification handlers, and use them to process multiple values delivered over time. Subscribing to an observable is equivalent to adding an event listener. One significant difference is that you can configure an observable to transform an event before passing the event to the handler.
Using observables to handle events and asynchronous operations can have the advantage of greater consistency in contexts such as HTTP requests.
Here are some code samples that illustrate how the same kind of operation is defined using observables and the events API.
<table>
<tr>
<th></th>
<th>Observable</th>
<th>Events API</th>
</tr>
<tr>
<td>Creation & cancellation</td>
<td>
<pre>// Setup
let clicks$ = fromEvent(buttonEl, click);
// Begin listening
let subscription = clicks$
.subscribe(e => console.log(Clicked, e))
// Stop listening
subscription.unsubscribe();</pre>
</td>
<td>
<pre>function handler(e) {
console.log(Clicked, e);
}
// Setup & begin listening
button.addEventListener(click, handler);
// Stop listening
button.removeEventListener(click, handler);
</pre>
</td>
</tr>
<tr>
<td>Subscription</td>
<td>
<pre>observable.subscribe(() => {
// notification handlers here
});</pre>
</td>
<td>
<pre>element.addEventListener(eventName, (event) => {
// notification handler here
});</pre>
</td>
</tr>
<tr>
<td>Configuration</td>
<td>Listen for keystrokes, but provide a stream representing the value in the input.
<pre>fromEvent(inputEl, 'keydown').pipe(
map(e => e.target.value)
);</pre>
</td>
<td>Does not support configuration.
<pre>element.addEventListener(eventName, (event) => {
// Cannot change the passed Event into another
// value before it gets to the handler
});</pre>
</td>
</tr>
</table>
## Observables compared to arrays
An observable produces values over time. An array is created as a static set of values. In a sense, observables are asynchronous where arrays are synchronous. In the following examples, ➞ implies asynchronous value delivery.
<table>
<tr>
<th></th>
<th>Observable</th>
<th>Array</th>
</tr>
<tr>
<td>Given</td>
<td>
<pre>obs: ➞1➞2➞3➞5➞7</pre>
<pre>obsB: ➞'a'➞'b'➞'c'</pre>
</td>
<td>
<pre>arr: [1, 2, 3, 5, 7]</pre>
<pre>arrB: ['a', 'b', 'c']</pre>
</td>
</tr>
<tr>
<td><pre>concat()</pre></td>
<td>
<pre>concat(obs, obsB)</pre>
<pre>➞1➞2➞3➞5➞7➞'a'➞'b'➞'c'</pre>
</td>
<td>
<pre>arr.concat(arrB)</pre>
<pre>[1,2,3,5,7,'a','b','c']</pre>
</td>
</tr>
<tr>
<td><pre>filter()</pre></td>
<td>
<pre>obs.pipe(filter((v) => v>3))</pre>
<pre>➞5➞7</pre>
</td>
<td>
<pre>arr.filter((v) => v>3)</pre>
<pre>[5, 7]</pre>
</td>
</tr>
<tr>
<td><pre>find()</pre></td>
<td>
<pre>obs.pipe(find((v) => v>3))</pre>
<pre>➞5</pre>
</td>
<td>
<pre>arr.find((v) => v>3)</pre>
<pre>5</pre>
</td>
</tr>
<tr>
<td><pre>findIndex()</pre></td>
<td>
<pre>obs.pipe(findIndex((v) => v>3))</pre>
<pre>➞3</pre>
</td>
<td>
<pre>arr.findIndex((v) => v>3)</pre>
<pre>3</pre>
</td>
</tr>
<tr>
<td><pre>forEach()</pre></td>
<td>
<pre>obs.pipe(tap((v) => {
console.log(v);
}))
1
2
3
5
7</pre>
</td>
<td>
<pre>arr.forEach((v) => {
console.log(v);
})
1
2
3
5
7</pre>
</td>
</tr>
<tr>
<td><pre>map()</pre></td>
<td>
<pre>obs.pipe(map((v) => -v))</pre>
<pre>➞-1➞-2➞-3➞-5➞-7</pre>
</td>
<td>
<pre>arr.map((v) => -v)</pre>
<pre>[-1, -2, -3, -5, -7]</pre>
</td>
</tr>
<tr>
<td><pre>reduce()</pre></td>
<td>
<pre>obs.pipe(reduce((s,v)=> s+v, 0))</pre>
<pre>➞18</pre>
</td>
<td>
<pre>arr.reduce((s,v) => s+v, 0)</pre>
<pre>18</pre>
</td>
</tr>
</table>

View File

@ -1,25 +1,24 @@
# Observables compared to other techniques # Observables en comparación con otras técnicas
You can often use observables instead of promises to deliver values asynchronously. Similarly, observables can take the place of event handlers. Finally, because observables deliver multiple values, you can use them where you might otherwise build and operate on arrays. A menudo puedes usar observables en lugar de promesas para entregar valores de forma asíncrona. Del mismo modo, los observables pueden reemplazar a los controladores de eventos. Finalmente, porque los observables entregan múltiples valores, puedes usarlos donde de otro modo podrías construir y operar con arrays.
Observables behave somewhat differently from the alternative techniques in each of these situations, but offer some significant advantages. Here are detailed comparisons of the differences. Los observables se comportan de manera algo diferente a las técnicas alternativas en cada una de estas situaciones, pero ofrecen algunas ventajas significativas. Aquí hay comparaciones detalladas de las diferencias.
## Observables compared to promises ## Observables en comparación con promesas
Observables are often compared to promises. Here are some key differences: Los observables a menudo se comparan con las promesas. Aquí hay algunas diferencias clave:
* Observables are declarative; computation does not start until subscription. Promises execute immediately on creation. This makes observables useful for defining recipes that can be run whenever you need the result. * Los observables son declarativos; La ejecución no comienza hasta la suscripción. Las promesas se ejecutan inmediatamente después de la creación. Esto hace que los observables sean útiles para definir recetas que se pueden ejecutar cuando necesites el resultado.
* Observables provide many values. Promises provide one. This makes observables useful for getting multiple values over time. * Los observables proporcionan muchos valores. Las promesas proporcionan un valor. Esto hace que los observables sean útiles para obtener múltiples valores a lo largo del tiempo.
* Observables differentiate between chaining and subscription. Promises only have `.then()` clauses. This makes observables useful for creating complex transformation recipes to be used by other part of the system, without causing the work to be executed. * Los observables diferencian entre encadenamiento y suscripción. Las promesas solo tienen cláusulas `.then ()`. Esto hace que los observables sean útiles para crear recetas de transformación complejas para ser utilizadas por otra parte del sistema, sin que el trabajo se ejecute.
* Observables `subscribe()` is responsible for handling errors. Promises push errors to the child promises. This makes observables useful for centralized and predictable error handling. * Observables `subscribe()` es responsable de manejar los errores. Las promesas empujan los errores a promesas hijas. Esto hace que los observables sean útiles para el manejo centralizado y predecible de errores.
### Creación y suscripción
### Creation and subscription * Los observables no se ejecutan hasta que un consumidor se suscribe. El `subscribe()` ejecuta el comportamiento definido una vez, y se puede volver a llamar. Cada suscripción tiene su propia computación. La resuscripción provoca la recomputación de los valores.
* Observables are not executed until a consumer subscribes. The `subscribe()` executes the defined behavior once, and it can be called again. Each subscription has its own computation. Resubscription causes recomputation of values.
<code-example <code-example
path="comparing-observables/src/observables.ts" path="comparing-observables/src/observables.ts"
@ -27,7 +26,7 @@ Observables are often compared to promises. Here are some key differences:
region="observable"> region="observable">
</code-example> </code-example>
* Promises execute immediately, and just once. The computation of the result is initiated when the promise is created. There is no way to restart work. All `then` clauses (subscriptions) share the same computation. * Las promesas se ejecutan de inmediato, y solo una vez. La computación del resultado se inicia cuando se crea la promesa. No hay forma de reiniciar el trabajo. Todas las cláusulas `then` (suscripciones) comparten la misma computación.
<code-example <code-example
path="comparing-observables/src/promises.ts" path="comparing-observables/src/promises.ts"
@ -35,9 +34,9 @@ Observables are often compared to promises. Here are some key differences:
region="promise"> region="promise">
</code-example> </code-example>
### Chaining ### Encadenamiento
* Observables differentiate between transformation function such as a map and subscription. Only subscription activates the subscriber function to start computing the values. * Los observables diferencian entre la función de transformación, como `map` y `subscription`. Solo la suscripción activa la función de suscriptor para comenzar a calcular los valores.
<code-example <code-example
path="comparing-observables/src/observables.ts" path="comparing-observables/src/observables.ts"
@ -45,7 +44,7 @@ Observables are often compared to promises. Here are some key differences:
region="chain"> region="chain">
</code-example> </code-example>
* Promises do not differentiate between the last `.then` clauses (equivalent to subscription) and intermediate `.then` clauses (equivalent to map). * Las promesas no diferencian entre las últimas cláusulas `.then` (equivalentes al subscription) y las cláusulas intermedias `.then` (equivalentes al map).
<code-example <code-example
path="comparing-observables/src/promises.ts" path="comparing-observables/src/promises.ts"
@ -53,9 +52,9 @@ Observables are often compared to promises. Here are some key differences:
region="chain"> region="chain">
</code-example> </code-example>
### Cancellation ### Cancelación
* Observable subscriptions are cancellable. Unsubscribing removes the listener from receiving further values, and notifies the subscriber function to cancel work. * Las suscripciones de los observables son cancelables. La cancelación de la suscripción evita que el oyente reciba más valores y notifica a la función del suscriptor que cancele el trabajo.
<code-example <code-example
path="comparing-observables/src/observables.ts" path="comparing-observables/src/observables.ts"
@ -63,11 +62,11 @@ Observables are often compared to promises. Here are some key differences:
region="unsubscribe"> region="unsubscribe">
</code-example> </code-example>
* Promises are not cancellable. * Las promesas no son cancelables.
### Error handling ### Manejo de errores
* Observable execution errors are delivered to the subscriber's error handler, and the subscriber automatically unsubscribes from the observable. * Los errores de ejecución en observables se entregan al controlador de errores del suscriptor, y el suscriptor cancela automáticamente la suscripción del observable.
<code-example <code-example
path="comparing-observables/src/observables.ts" path="comparing-observables/src/observables.ts"
@ -75,7 +74,7 @@ Observables are often compared to promises. Here are some key differences:
region="error"> region="error">
</code-example> </code-example>
* Promises push errors to the child promises. * Las promesas empujan los errores a las promesas hijas.
<code-example <code-example
path="comparing-observables/src/promises.ts" path="comparing-observables/src/promises.ts"
@ -83,9 +82,9 @@ Observables are often compared to promises. Here are some key differences:
region="error"> region="error">
</code-example> </code-example>
### Cheat sheet ### Hoja de trucos
The following code snippets illustrate how the same kind of operation is defined using observables and promises. Los siguientes fragmentos de código ilustran cómo se define el mismo tipo de operación utilizando observables y promesas.
<table> <table>
<thead> <thead>
@ -139,13 +138,13 @@ promise.then((value) => {
</tbody> </tbody>
</table> </table>
## Observables compared to events API ## Observables en comparación con eventos API
Observables are very similar to event handlers that use the events API. Both techniques define notification handlers, and use them to process multiple values delivered over time. Subscribing to an observable is equivalent to adding an event listener. One significant difference is that you can configure an observable to transform an event before passing the event to the handler. Los observables son muy similares a los controladores de eventos que usan la API de eventos. Ambas técnicas definen manejadores de notificaciones y las utilizan para procesar múltiples valores entregados a lo largo del tiempo. Suscribirse a un observable es equivalente a agregar un detector de eventos. Una diferencia significativa es que puedes configurar un observable para transformar un evento antes de pasar el evento al controlador.
Using observables to handle events and asynchronous operations can have the advantage of greater consistency in contexts such as HTTP requests. El uso de observables para manejar eventos y operaciones asíncronas puede tener la ventaja de una mayor coherencia en contextos como las solicitudes HTTP.
Here are some code samples that illustrate how the same kind of operation is defined using observables and the events API. Aquí hay algunos ejemplos de código que ilustran cómo se define el mismo tipo de operación usando observables y la API de eventos.
<table> <table>
<tr> <tr>
@ -205,9 +204,9 @@ button.removeEventListener(click, handler);
</table> </table>
## Observables compared to arrays ## Observables en comparación con arrays
An observable produces values over time. An array is created as a static set of values. In a sense, observables are asynchronous where arrays are synchronous. In the following examples, ➞ implies asynchronous value delivery. Un observable produce valores a lo largo del tiempo. Se crea un array como un conjunto estático de valores. En cierto sentido, los observables son asíncronos mientras que los arrays son síncronos. En los siguientes ejemplos, ➞ implica entrega de valor asíncrono.
<table> <table>
<tr> <tr>

View File

@ -0,0 +1,104 @@
# Complex animation sequences
#### Prerequisites
A basic understanding of the following concepts:
* [Introduction to Angular animations](guide/animations)
* [Transition and triggers](guide/transition-and-triggers)
<hr>
So far, we've learned simple animations of single HTML elements. Angular also lets you animate coordinated sequences, such as an entire grid or list of elements as they enter and leave a page. You can choose to run multiple animations in parallel, or run discrete animations sequentially, one following another.
Functions that control complex animation sequences are as follows:
* `query()` finds one or more inner HTML elements.
* `stagger()` applies a cascading delay to animations for multiple elements.
* [`group()`](api/animations/group) runs multiple animation steps in parallel.
* `sequence()` runs animation steps one after another.
{@a complex-sequence}
## Animate multiple elements using query() and stagger() functions
The `query()` function allows you to find inner elements within the element that is being animated. This function targets specific HTML elements within a parent component and applies animations to each element individually. Angular intelligently handles setup, teardown, and cleanup as it coordinates the elements across the page.
The `stagger()` function allows you to define a timing gap between each queried item that is animated and thus animates elements with a delay between them.
The Filter/Stagger tab in the live example shows a list of heroes with an introductory sequence. The entire list of heroes cascades in, with a slight delay from top to bottom.
The following example demonstrates how to use `query()` and `stagger()` functions on the entry of an animated element.
* Use `query()` to look for an element entering the page that meets certain criteria.
* For each of these elements, use `style()` to set the same initial style for the element. Make it invisible and use `transform` to move it out of position so that it can slide into place.
* Use `stagger()` to delay each animation by 30 milliseconds.
* Animate each element on screen for 0.5 seconds using a custom-defined easing curve, simultaneously fading it in and un-transforming it.
<code-example path="animations/src/app/hero-list-page.component.ts" header="src/app/hero-list-page.component.ts" region="page-animations" language="typescript"></code-example>
## Parallel animation using group() function
You've seen how to add a delay between each successive animation. But you may also want to configure animations that happen in parallel. For example, you may want to animate two CSS properties of the same element but use a different `easing` function for each one. For this, you can use the animation [`group()`](api/animations/group) function.
<div class="alert is-helpful">
**Note:** The [`group()`](api/animations/group) function is used to group animation *steps*, rather than animated elements.
</div>
In the following example, using groups on both `:enter` and `:leave` allow for two different timing configurations. They're applied to the same element in parallel, but run independently.
<code-example path="animations/src/app/hero-list-groups.component.ts" region="animationdef" header="src/app/hero-list-groups.component.ts (excerpt)" language="typescript"></code-example>
## Sequential vs. parallel animations
Complex animations can have many things happening at once. But what if you want to create an animation involving several animations happening one after the other? Earlier we used [`group()`](api/animations/group) to run multiple animations all at the same time, in parallel.
A second function called `sequence()` lets you run those same animations one after the other. Within `sequence()`, the animation steps consist of either `style()` or `animate()` function calls.
* Use `style()` to apply the provided styling data immediately.
* Use `animate()` to apply styling data over a given time interval.
## Filter animation example
Let's take a look at another animation on the live example page. Under the Filter/Stagger tab, enter some text into the **Search Heroes** text box, such as `Magnet` or `tornado`.
The filter works in real time as you type. Elements leave the page as you type each new letter and the filter gets progressively stricter. The heroes list gradually re-enters the page as you delete each letter in the filter box.
The HTML template contains a trigger called `filterAnimation`.
<code-example path="animations/src/app/hero-list-page.component.html" header="src/app/hero-list-page.component.html" region="filter-animations"></code-example>
The component file contains three transitions.
<code-example path="animations/src/app/hero-list-page.component.ts" header="src/app/hero-list-page.component.ts" region="filter-animations" language="typescript"></code-example>
The animation does the following:
* Ignores any animations that are performed when the user first opens or navigates to this page. The filter narrows what is already there, so it assumes that any HTML elements to be animated already exist in the DOM.
* Performs a filter match for matches.
For each match:
* Hides the element by making it completely transparent and infinitely narrow, by setting its opacity and width to 0.
* Animates in the element over 300 milliseconds. During the animation, the element assumes its default width and opacity.
* If there are multiple matching elements, staggers in each element starting at the top of the page, with a 50-millisecond delay between each element.
## Animation sequence summary
Angular functions for animating multiple elements start with `query()` to find inner elements, for example gathering all images within a `<div>`. The remaining functions, `stagger()`, [`group()`](api/animations/group), and `sequence()`, apply cascades or allow you to control how multiple animation steps are applied.
## More on Angular animations
You may also be interested in the following:
* [Introduction to Angular animations](guide/animations)
* [Transition and triggers](guide/transition-and-triggers)
* [Reusable animations](guide/reusable-animations)
* [Route transition animations](guide/route-animations)

View File

@ -1,104 +1,105 @@
# Complex animation sequences # Secuencias de animación complejas
#### Prerequisites #### Requisitos
A basic understanding of the following concepts: Una comprensión básica de los siguientes conceptos:
* [Introduction to Angular animations](guide/animations) - [Introducción a animaciones Angular](guide/animations)
* [Transition and triggers](guide/transition-and-triggers) - [Transición y triggers](guide/transition-and-triggers)
<hr> <hr>
So far, we've learned simple animations of single HTML elements. Angular also lets you animate coordinated sequences, such as an entire grid or list of elements as they enter and leave a page. You can choose to run multiple animations in parallel, or run discrete animations sequentially, one following another. Hasta ahora, hemos aprendido animaciones simples de elementos HTML individuales. Angular también te permite animar secuencias coordinadas, como un grid completo o una lista de elementos cuando entran y salen de una página. Puedes elegir ejecutar varias animaciones en paralelo, o ejecutar animaciones discretas secuencialmente, una tras otra.
Functions that control complex animation sequences are as follows: Las funciones que controlan secuencias de animación complejas son las siguientes:
* `query()` finds one or more inner HTML elements. - `query()` encuentra uno o más elementos HTML internos.
* `stagger()` applies a cascading delay to animations for multiple elements. - `stagger()` aplica un retraso en cascada a las animaciones para varios elementos.
* [`group()`](api/animations/group) runs multiple animation steps in parallel. - [`group()`](api/animations/group) ejecuta varios pasos de animación en paralelo.
* `sequence()` runs animation steps one after another. - `sequence()` ejecuta pasos de animación uno tras otro.
{@a complex-sequence} {@a complex-sequence}
## Animate multiple elements using query() and stagger() functions ## Animar varios elementos usando las funciones query() y stagger()
The `query()` function allows you to find inner elements within the element that is being animated. This function targets specific HTML elements within a parent component and applies animations to each element individually. Angular intelligently handles setup, teardown, and cleanup as it coordinates the elements across the page. La función `query()` permite encontrar elementos internos dentro del elemento que estás animando. Esta función se dirige a elementos HTML específicos dentro de un componente principal y aplica animaciones a cada elemento individualmente. Angular maneja de manera inteligente la configuración, el desmontaje y la limpieza a medida que coordina los elementos en la página.
The `stagger()` function allows you to define a timing gap between each queried item that is animated and thus animates elements with a delay between them. La función `stagger()` permite definir un intervalo de tiempo entre cada elemento consultado que está animado y, por lo tanto, anima elementos con un retraso entre ellos.
The Filter/Stagger tab in the live example shows a list of heroes with an introductory sequence. The entire list of heroes cascades in, with a slight delay from top to bottom. La pestaña Filter/Stagger en el ejemplo en vivo muestra una lista de héroes con una secuencia introductoria. La lista completa de héroes entra en cascada, con un ligero retraso de arriba a abajo.
The following example demonstrates how to use `query()` and `stagger()` functions on the entry of an animated element. El siguiente ejemplo demuestra cómo utilizar las funciones `query()` y `stagger()` en la entrada de un elemento animado.
* Use `query()` to look for an element entering the page that meets certain criteria. - Usa `query()` para buscar un elemento que ingrese a la página que cumpla con ciertos criterios.
* For each of these elements, use `style()` to set the same initial style for the element. Make it invisible and use `transform` to move it out of position so that it can slide into place. - Para cada uno de estos elementos, usa `style()` para establecer el mismo estilo inicial para el elemento. Hazlo invisible y usa `transform` para moverlo fuera de su posición para que pueda deslizarse a su lugar.
* Use `stagger()` to delay each animation by 30 milliseconds. - Usa `stagger()` para retrasar cada animación en 30 milisegundos.
* Animate each element on screen for 0.5 seconds using a custom-defined easing curve, simultaneously fading it in and un-transforming it. - Anima cada elemento en la pantalla durante 0,5 segundos utilizando una curva de easing (suavizado) definida a medida, desvaneciéndolo y deshaciéndolo simultáneamente.
<code-example path="animations/src/app/hero-list-page.component.ts" header="src/app/hero-list-page.component.ts" region="page-animations" language="typescript"></code-example> <code-example path="animations/src/app/hero-list-page.component.ts" header="src/app/hero-list-page.component.ts" region="page-animations" language="typescript"></code-example>
## Parallel animation using group() function ## Animación paralela usando la función group()
You've seen how to add a delay between each successive animation. But you may also want to configure animations that happen in parallel. For example, you may want to animate two CSS properties of the same element but use a different `easing` function for each one. For this, you can use the animation [`group()`](api/animations/group) function. Has visto cómo agregar un retraso entre cada animación sucesiva. Pero es posible que también quieras configurar animaciones que suceden en paralelo. Por ejemplo, es posible que quieras animar dos propiedades CSS del mismo elemento pero utilizar una función de `easing` diferente para cada una. Para ello, puedes utilizar la función de animación [`group()`](api/animations/group).
<div class="alert is-helpful"> <div class="alert is-helpful">
**Note:** The [`group()`](api/animations/group) function is used to group animation *steps*, rather than animated elements. **Nota:** La función [`group()`](api/animations/group) se usa para agrupar _pasos_ de animación, en lugar de elementos animados.
</div> </div>
In the following example, using groups on both `:enter` and `:leave` allow for two different timing configurations. They're applied to the same element in parallel, but run independently. En el siguiente ejemplo, el uso de grupos tanto en `:enter` como en `:leave` permite dos configuraciones de tiempo diferentes. Se aplican al mismo elemento en paralelo, pero se ejecutan de forma independiente.
<code-example path="animations/src/app/hero-list-groups.component.ts" region="animationdef" header="src/app/hero-list-groups.component.ts (excerpt)" language="typescript"></code-example> <code-example path="animations/src/app/hero-list-groups.component.ts" region="animationdef" header="src/app/hero-list-groups.component.ts (excerpt)" language="typescript"></code-example>
## Sequential vs. parallel animations ## Animaciones secuenciales vs paralelas
Complex animations can have many things happening at once. But what if you want to create an animation involving several animations happening one after the other? Earlier we used [`group()`](api/animations/group) to run multiple animations all at the same time, in parallel. Las animaciones complejas pueden tener muchas cosas sucediendo a la vez. Pero, ¿qué sucede si quieres crear una animación que involucre varias animaciones sucediendo una tras otra? Anteriormente usamos [`group()`](api/animations/group) para ejecutar múltiples animaciones al mismo tiempo, en paralelo.
A second function called `sequence()` lets you run those same animations one after the other. Within `sequence()`, the animation steps consist of either `style()` or `animate()` function calls. Una segunda función llamada `sequence()` permite ejecutar esas mismas animaciones una tras otra. Dentro de `sequence()`, los pasos de la animación consisten en llamadas de función `style()` o `animate()`
* Use `style()` to apply the provided styling data immediately. - Usa `style()` para aplicar los datos de estilo proporcionados inmediatamente.
* Use `animate()` to apply styling data over a given time interval. - Usa `animate()` para aplicar datos de estilo en un intervalo de tiempo determinado.
## Filter animation example ## Ejemplo de animación de filtro
Let's take a look at another animation on the live example page. Under the Filter/Stagger tab, enter some text into the **Search Heroes** text box, such as `Magnet` or `tornado`. Echemos un vistazo a otra animación en la página de ejemplo. En la pestaña Filter/Stagger, ingresa un texto en el cuadro de texto **Search Heroes**, como `Magnet` o `tornado`.
The filter works in real time as you type. Elements leave the page as you type each new letter and the filter gets progressively stricter. The heroes list gradually re-enters the page as you delete each letter in the filter box. El filtro funciona en tiempo real a medida que escribe. Los elementos abandonan la página a medida que escribe cada nueva letra y el filtro se vuelve progresivamente más estricto. La lista de héroes vuelve a entrar gradualmente en la página a medida que eliminas cada letra en la caja de filtro.
The HTML template contains a trigger called `filterAnimation`. La plantilla HTML contiene un trigger llamado `filterAnimation`.
<code-example path="animations/src/app/hero-list-page.component.html" header="src/app/hero-list-page.component.html" region="filter-animations"></code-example> <code-example path="animations/src/app/hero-list-page.component.html" header="src/app/hero-list-page.component.html" region="filter-animations"></code-example>
The component file contains three transitions. El archivo del componente contiene tres transiciones.
<code-example path="animations/src/app/hero-list-page.component.ts" header="src/app/hero-list-page.component.ts" region="filter-animations" language="typescript"></code-example> <code-example path="animations/src/app/hero-list-page.component.ts" header="src/app/hero-list-page.component.ts" region="filter-animations" language="typescript"></code-example>
The animation does the following: La animación hace lo siguiente:
* Ignores any animations that are performed when the user first opens or navigates to this page. The filter narrows what is already there, so it assumes that any HTML elements to be animated already exist in the DOM. - Ignora las animaciones que se realizan cuando el usuario abre o navega por primera vez a esta página. El filtro reduce lo que ya está allí, por lo que asume que los elementos HTML que se van a animar ya existen en el DOM.
* Performs a filter match for matches. - Realiza un filtro de coincidencia.
For each match: Para cada coincidencia:
* Hides the element by making it completely transparent and infinitely narrow, by setting its opacity and width to 0. - Oculta el elemento haciéndolo completamente transparente e infinitamente estrecho, estableciendo su opacidad y ancho en 0.
* Animates in the element over 300 milliseconds. During the animation, the element assumes its default width and opacity. - Anima el elemento más de 300 milisegundos. Durante la animación, el elemento asume su ancho y opacidad predeterminados.
* If there are multiple matching elements, staggers in each element starting at the top of the page, with a 50-millisecond delay between each element. - Si hay varios elementos coincidentes, se escalona en cada elemento comenzando en la parte superior de la página, con un retraso de 50 milisegundos entre cada elemento.
## Animation sequence summary ## Resumen de la secuencia de animación
Angular functions for animating multiple elements start with `query()` to find inner elements, for example gathering all images within a `<div>`. The remaining functions, `stagger()`, [`group()`](api/animations/group), and `sequence()`, apply cascades or allow you to control how multiple animation steps are applied. Las funciones Angular para animar múltiples elementos comienzan con `query()` para encontrar elementos internos, por ejemplo, reuniendo todas las imágenes dentro de un `<div>`. Las funciones restantes, `stagger()`, [`group()`](api/animations/group) y `sequence()`, aplican cascadas o te permiten controlar cómo se aplican múltiples pasos de animación.
## More on Angular animations ## Más sobre animaciones en Angular
You may also be interested in the following: También puedes estar interesado en lo siguiente:
* [Introduction to Angular animations](guide/animations) - [Introducción a animaciones Angular](guide/animations)
* [Transition and triggers](guide/transition-and-triggers) - [Transición y triggers](guide/transition-and-triggers)
* [Reusable animations](guide/reusable-animations) - [Animaicones reusables](guide/reusable-animations)
* [Route transition animations](guide/route-animations) - [Animaciones en transición de ruta](guide/route-animations)

View File

@ -0,0 +1,245 @@
# Creating libraries
This page provides a conceptual overview of how you can create and publish new libraries to extend Angular functionality.
If you find that you need to solve the same problem in more than one app (or want to share your solution with other developers), you have a candidate for a library.
A simple example might be a button that sends users to your company website, that would be included in all apps that your company builds.
## Getting started
Use the Angular CLI to generate a new library skeleton in a new workspace with the following commands.
<code-example language="bash">
ng new my-workspace --create-application=false
cd my-workspace
ng generate library my-lib
</code-example>
The `ng generate` command creates the `projects/my-lib` folder in your workspace, which contains a component and a service inside an NgModule.
<div class="alert is-helpful">
For more details on how a library project is structured, refer to the [Library project files](guide/file-structure#library-project-files) section of the [Project File Structure guide](guide/file-structure).
You can use the monorepo model to use the same workspace for multiple projects.
See [Setting up for a multi-project workspace](guide/file-structure#multiple-projects).
</div>
When you generate a new library, the workspace configuration file, `angular.json`, is updated with a project of type 'library'.
<code-example format="json">
"projects": {
...
"my-lib": {
"root": "projects/my-lib",
"sourceRoot": "projects/my-lib/src",
"projectType": "library",
"prefix": "lib",
"architect": {
"build": {
"builder": "@angular-devkit/build-ng-packagr:build",
...
</code-example>
You can build, test, and lint the project with CLI commands:
<code-example language="bash">
ng build my-lib
ng test my-lib
ng lint my-lib
</code-example>
Notice that the configured builder for the project is different from the default builder for app projects.
This builder, among other things, ensures that the library is always built with the [AOT compiler](guide/aot-compiler), without the need to specify the `--prod` flag.
To make library code reusable you must define a public API for it. This "user layer" defines what is available to consumers of your library. A user of your library should be able to access public functionality (such as NgModules, service providers and general utility functions) through a single import path.
The public API for your library is maintained in the `public-api.ts` file in your library folder.
Anything exported from this file is made public when your library is imported into an application.
Use an NgModule to expose services and components.
Your library should supply documentation (typically a README file) for installation and maintenance.
## Refactoring parts of an app into a library
To make your solution reusable, you need to adjust it so that it does not depend on app-specific code.
Here are some things to consider in migrating application functionality to a library.
* Declarations such as components and pipes should be designed as stateless, meaning they dont rely on or alter external variables. If you do rely on state, you need to evaluate every case and decide whether it is application state or state that the library would manage.
* Any observables that the components subscribe to internally should be cleaned up and disposed of during the lifecycle of those components.
* Components should expose their interactions through inputs for providing context, and outputs for communicating events to other components.
* Check all internal dependencies.
* For custom classes or interfaces used in components or service, check whether they depend on additional classes or interfaces that also need to be migrated.
* Similarly, if your library code depends on a service, that service needs to be migrated.
* If your library code or its templates depend on other libraries (such as Angular Material, for instance), you must configure your library with those dependencies.
* Consider how you provide services to client applications.
* Services should declare their own providers (rather than declaring providers in the NgModule or a component), so that they are *tree-shakable*. This allows the compiler to leave the service out of the bundle if it never gets injected into the application that imports the library. For more about this, see [Tree-shakable providers](guide/dependency-injection-providers#tree-shakable-providers).
* If you register global service providers or share providers across multiple NgModules, use the [`forRoot()` and `forChild()` design patterns](guide/singleton-services) provided by the [RouterModule](api/router/RouterModule).
* If your library provides optional services that might not be used by all client applications, support proper tree-shaking for that case by using the [lightweight token design pattern](guide/lightweight-injection-tokens).
{@a integrating-with-the-cli}
## Integrating with the CLI using code-generation schematics
A library typically includes *reusable code* that defines components, services, and other Angular artifacts (pipes, directives, and so on) that you simply import into a project.
A library is packaged into an npm package for publishing and sharing.
This package can also include [schematics](guide/glossary#schematic) that provide instructions for generating or transforming code directly in your project, in the same way that the CLI creates a generic new component with `ng generate component`.
A schematic that is packaged with a library can, for example, provide the Angular CLI with the information it needs to generate a component that configures and uses a particular feature, or set of features, defined in that library.
One example of this is Angular Material's navigation schematic which configures the CDK's `BreakpointObserver` and uses it with Material's `MatSideNav` and `MatToolbar` components.
You can create and include the following kinds of schematics.
* Include an installation schematic so that `ng add` can add your library to a project.
* Include generation schematics in your library so that `ng generate` can scaffold your defined artifacts (components, services, tests, and so on) in a project.
* Include an update schematic so that `ng update` can update your librarys dependencies and provide migrations for breaking changes in new releases.
What you include in your library depends on your task.
For example, you could define a schematic to create a dropdown that is pre-populated with canned data to show how to add it to an app.
If you want a dropdown that would contain different passed-in values each time, your library could define a schematic to create it with a given configuration. Developers could then use `ng generate` to configure an instance for their own app.
Suppose you want to read a configuration file and then generate a form based on that configuration.
If that form will need additional customization by the developer who is using your library, it might work best as a schematic.
However, if the forms will always be the same and not need much customization by developers, then you could create a dynamic component that takes the configuration and generates the form.
In general, the more complex the customization, the more useful the schematic approach.
To learn more, see [Schematics Overview](guide/schematics) and [Schematicsfor Libraries](guide/schematics-for-libraries).
## Publishing your library
Use the Angular CLI and the npm package manager to build and publish your library as an npm package.
Before publishing a library to NPM, build it using the `--prod` flag which will use the older compiler and runtime known as View Engine instead of Ivy.
<code-example language="bash">
ng build my-lib --prod
cd dist/my-lib
npm publish
</code-example>
If you've never published a package in npm before, you must create a user account. Read more in [Publishing npm Packages](https://docs.npmjs.com/getting-started/publishing-npm-packages).
<div class="alert is-important">
For now, it is not recommended to publish Ivy libraries to NPM because Ivy generated code is not backward compatible with View Engine, so apps using View Engine will not be able to consume them. Furthermore, the internal Ivy instructions are not yet stable, which can potentially break consumers using a different Angular version from the one used to build the library.
When a published library is used in an Ivy app, the Angular CLI will automatically convert it to Ivy using a tool known as the Angular compatibility compiler (`ngcc`). Thus, publishing your libraries using the View Engine compiler ensures that they can be transparently consumed by both View Engine and Ivy apps.
</div>
{@a lib-assets}
## Managing assets in a library
Starting with version 9.x of the [ng-packagr](https://github.com/ng-packagr/ng-packagr/blob/master/README.md) tool, you can configure the tool to automatically copy assets into your library package as part of the build process.
You can use this feature when your library needs to publish optional theming files, Sass mixins, or documentation (like a changelog).
* Learn how to [copy assets into your library as part of the build](https://github.com/ng-packagr/ng-packagr/blob/master/docs/copy-assets.md).
* Learn more about how to use the tool to [embed assets in CSS](https://github.com/ng-packagr/ng-packagr/blob/master/docs/embed-assets-css.md).
## Linked libraries
While working on a published library, you can use [npm link](https://docs.npmjs.com/cli/link) to avoid reinstalling the library on every build.
The library must be rebuilt on every change.
When linking a library, make sure that the build step runs in watch mode, and that the library's `package.json` configuration points at the correct entry points.
For example, `main` should point at a JavaScript file, not a TypeScript file.
## Use TypeScript path mapping for peer dependencies
Angular libraries should list all `@angular/*` dependencies as peer dependencies.
This ensures that when modules ask for Angular, they all get the exact same module.
If a library lists `@angular/core` in `dependencies` instead of `peerDependencies`, it might get a different Angular module instead, which would cause your application to break.
While developing a library, you must install all peer dependencies through `devDependencies` to ensure that the library compiles properly.
A linked library will then have its own set of Angular libraries that it uses for building, located in its `node_modules` folder.
However, this can cause problems while building or running your application.
To get around this problem you can use TypeScript path mapping to tell TypeScript that it should load some modules from a specific location.
List all the peer dependencies that your library uses in the workspace TypeScript configuration file `./tsconfig.json`, and point them at the local copy in the app's `node_modules` folder.
```
{
"compilerOptions": {
// ...
// paths are relative to `baseUrl` path.
"paths": {
"@angular/*": [
"./node_modules/@angular/*"
]
}
}
}
```
This mapping ensures that your library always loads the local copies of the modules it needs.
## Using your own library in apps
You don't have to publish your library to the npm package manager in order to use it in your own apps, but you do have to build it first.
To use your own library in an app:
* Build the library. You cannot use a library before it is built.
<code-example language="bash">
ng build my-lib
</code-example>
* In your apps, import from the library by name:
```
import { myExport } from 'my-lib';
```
### Building and rebuilding your library
The build step is important if you haven't published your library as an npm package and then installed the package back into your app from npm.
For instance, if you clone your git repository and run `npm install`, your editor will show the `my-lib` imports as missing if you haven't yet built your library.
<div class="alert is-helpful">
When you import something from a library in an Angular app, Angular looks for a mapping between the library name and a location on disk.
When you install a library package, the mapping is in the `node_modules` folder. When you build your own library, it has to find the mapping in your `tsconfig` paths.
Generating a library with the Angular CLI automatically adds its path to the `tsconfig` file.
The Angular CLI uses the `tsconfig` paths to tell the build system where to find the library.
</div>
If you find that changes to your library are not reflected in your app, your app is probably using an old build of the library.
You can rebuild your library whenever you make changes to it, but this extra step takes time.
*Incremental builds* functionality improves the library-development experience.
Every time a file is changed a partial build is performed that emits the amended files.
Incremental builds can be run as a background process in your dev environment. To take advantage of this feature add the `--watch` flag to the build command:
<code-example language="bash">
ng build my-lib --watch
</code-example>
<div class="alert is-important">
The CLI `build` command uses a different builder and invokes a different build tool for libraries than it does for applications.
* The build system for apps, `@angular-devkit/build-angular`, is based on `webpack`, and is included in all new Angular CLI projects.
* The build system for libraries is based on `ng-packagr`. It is only added to your dependencies when you add a library using `ng generate library my-lib`.
The two build systems support different things, and even where they support the same things, they do those things differently.
This means that the TypeScript source can result in different JavaScript code in a built library than it would in a built application.
For this reason, an app that depends on a library should only use TypeScript path mappings that point to the *built library*.
TypeScript path mappings should *not* point to the library source `.ts` files.
</div>

View File

@ -1,16 +1,13 @@
# Creating libraries # Creando librerías
You can create and publish new libraries to extend Angular functionality. If you find that you need to solve the same problem in more than one app (or want to share your solution with other developers), you have a candidate for a library. Está pagina provee una vista conceptual de como puedes crear y publicar nuevas librerías para extender las funcionalidades de Angular.
A simple example might be a button that sends users to your company website, that would be included in all apps that your company builds. Si necesitas resolver el mismo problema en mas de una aplicación (o quiere compartir tu solución con otros desarrolladores), tienes un candidato para una librería.
Un ejemplo simple puede ser un botón que envía a los usuarios hacia el sitio web de tu empresa, que sería incluido en todas las aplicaciones que tu empresa crea.
<div class="alert is-helpful"> ## Empezando
<p>For more details on how a library project is structured you can refer the <a href="guide/file-structure#library-project-files">Library Project Files</a></p>
</div>
## Getting started Usa el Angular CLI para generar un nuevo esqueleto de librería, en nuevo espacio de trabajo con los siguiente comandos.
Use the Angular CLI to generate a new library skeleton with the following command:
<code-example language="bash"> <code-example language="bash">
ng new my-workspace --create-application=false ng new my-workspace --create-application=false
@ -18,12 +15,17 @@ Use the Angular CLI to generate a new library skeleton with the following comman
ng generate library my-lib ng generate library my-lib
</code-example> </code-example>
El comando `ng generate` crea la carpeta `projects/my-lib` en el espacio de trabajo, que contiene un componente y un servicio dentro de un NgModule.
<div class="alert is-helpful"> <div class="alert is-helpful">
<p>You can use the monorepo model to use the same workspace for multiple projects. See <a href="guide/file-structure#multiple-projects">Setting up for a multi-project workspace</a>.</p>
Para más detalles sobre como una librería es estructurada, refiérase a los [Archivos de Librería](guide/file-structure#library-project-files) en la sección de [Guía de estructura de archivos](guide/file-structure).
Puedes usar un modelo de monorepo para usar el mismo espacio de trabajo con multiples proyectos. Véase [Configuración para espacio de trabajo multiproyecto](guide/file-structure#multiple-projects).
</div> </div>
This creates the `projects/my-lib` folder in your workspace, which contains a component and a service inside an NgModule. Cuando se genera una nueva librería, el archivo de configuración del espacio de trabajo, `angular.json`, es actualizado con un proyecto de tipo 'library'.
The workspace configuration file, `angular.json`, is updated with a project of type 'library'.
<code-example format="json"> <code-example format="json">
"projects": { "projects": {
@ -39,7 +41,7 @@ The workspace configuration file, `angular.json`, is updated with a project of t
... ...
</code-example> </code-example>
You can build, test, and lint the project with CLI commands: Puedes crear, probar y comprobar con los comandos de CLI:
<code-example language="bash"> <code-example language="bash">
ng build my-lib ng build my-lib
@ -47,71 +49,78 @@ You can build, test, and lint the project with CLI commands:
ng lint my-lib ng lint my-lib
</code-example> </code-example>
Notice that the configured builder for the project is different from the default builder for app projects. Puedes notar que el constructor configurado para el proyecto es diferente que el constructor por defecto para proyectos.
This builder, among other things, ensures that the library is always built with the [AOT compiler](guide/aot-compiler), without the need to specify the `--prod` flag. El constructor, entre otras cosas, asegura que la librería siempre este construida con el [compilador AOT](guide/aot-compiler), sin la necesidad de especificar la bandera `--prod`.
To make library code reusable you must define a public API for it. This "user layer" defines what is available to consumers of your library. A user of your library should be able to access public functionality (such as NgModules, service providers and general utility functions) through a single import path. Para hacer el código de la librería reusable debes definir una API pública para ella. Esta "capa de usuario" define que esta disponible para los consumidores de tu librería. Un usuario de tu librería debería ser capaz de acceder a la funcionalidad publica (como NgModules, servicios, proveedores y en general funciones de utilidad) mediante una sola ruta.
The public API for your library is maintained in the `public-api.ts` file in your library folder. La API pública para tu librería es mantenida en el archivo `public-api.ts` en tu carpeta de librería.
Anything exported from this file is made public when your library is imported into an application. Cualquier cosa exportada desde este archivo se hace publica cuando tu librería es importada dentro de una aplicación.
Use an NgModule to expose services and components. Usa un NgModule para exponer los servicios y componentes.
Your library should supply documentation (typically a README file) for installation and maintenance. Tu libería debería suministrar documentatión (típicamente en el archivo README) para la instalación y mantenimiento.
## Refactoring parts of an app into a library ## Refactorizando partes de una app dentro de un librería
To make your solution reusable, you need to adjust it so that it does not depend on app-specific code. Para hacer tu solución reusable, necesitas ajustarla para que no dependa del código específico de la aplicación.
Here are some things to consider in migrating application functionality to a library. Aquí algunas cosas para considerar al migrar la funcionalidad de la aplicación a una librería.
* Declarations such as components and pipes should be designed as stateless, meaning they dont rely on or alter external variables. If you do rely on state, you need to evaluate every case and decide whether it is application state or state that the library would manage. * Declaraciones tales como componentes y pipes deberían ser diseñados como 'stateless' (sin estado), lo que significa que no dependen ni alteran variables externas. Si tu dependes del estado, necesitas evaluar cada caso y decidir el estado de la aplicación o el estado que la aplicación administraría.
* Any observables that the components subscribe to internally should be cleaned up and disposed of during the lifecycle of those components. * Cualquier observable al cual los componentes se suscriban internamente deberían ser limpiados y desechados durante el ciclo de vida de esos componentes.
* Components should expose their interactions through inputs for providing context, and outputs for communicating events to other components. * Los componentes deberían exponer sus interacciones a través de 'inputs' para proporcionar contexto y 'outputs' para comunicar los eventos hacia otros componentes.
* Services should declare their own providers (rather than declaring providers in the NgModule or a component), so that they are *tree-shakable*. This allows the compiler to leave the service out of the bundle if it never gets injected into the application that imports the library. For more about this, see [Tree-shakable providers](guide/dependency-injection-providers#tree-shakable-providers). * Verifique todas las dependencias internas.
* Para clases personalizadas o interfaces usadas en componentes o servicios, verifique si dependen en clases adicionales o interfaces que también necesiten ser migradas.
* Del mismo modo, si tu código de librería depende de un servicio, este servicio necesita ser migrado.
* Si tu código de librería o sus plantillas dependen de otras librerías (como Angular Material), debes configurar tu librería con esas dependencias.
* If you register global service providers or share providers across multiple NgModules, use the [`forRoot()` and `forChild()` patterns](guide/singleton-services) provided by the [RouterModule](api/router/RouterModule). * Considere como proporcionar servicios a las aplicaciones cliente.
* Check all internal dependencies. * Los servicios deberían declarar sus propios proveedores (en lugar de declarar los proveedores en el NgModule o en un componente). Esto le permite al compilador dejar los servicios fuera del 'bundle' si este nunca fue inyectado dentro de la aplicación que importa la librería, véase [proveedores Tree-shakable](guide/dependency-injection-providers#tree-shakable-providers)
* For custom classes or interfaces used in components or service, check whether they depend on additional classes or interfaces that also need to be migrated. * Si registras proveedores globales o compartes proveedores a través de múltiples NgModules, usa el [`forRoot()` y `forChild()` como patrones de diseño](guide/singleton-services) proporcionados por el [RouterModule](api/router/RouterModule).
* Similarly, if your library code depends on a service, that service needs to be migrated. * Si tu librería proporciona servicios opcionales que podrían no ser usados por todos las aplicaciones cliente, soporte apropiadamente el 'tree-shaking' para esos casos usando el [patrón de diseño de token ligero](guide/lightweight-injection-tokens).
* If your library code or its templates depend on other libraries (such a Angular Material, for instance), you must configure your library with those dependencies.
## Reusable code and schematics
A library typically includes *reusable code* that defines components, services, and other Angular artifacts (pipes, directives, and so on) that you simply import into a project.
A library is packaged into an npm package for publishing and sharing, and this package can also include [schematics](guide/glossary#schematic) that provide instructions for generating or transforming code directly in your project, in the same way that the CLI creates a generic skeleton app with `ng generate component`.
A schematic that is combined with a library can, for example, provide the Angular CLI with the information it needs to generate a particular component defined in that library.
What you include in your library is determined by the kind of task you are trying to accomplish.
For example, if you want a dropdown with some canned data to show how to add it to your app, your library could define a schematic to create it.
For a component like a dropdown that would contain different passed-in values each time, you could provide it as a component in a shared library.
Suppose you want to read a configuration file and then generate a form based on that configuration.
If that form will need additional customization by the user, it might work best as a schematic.
However, if the forms will always be the same and not need much customization by developers, then you could create a dynamic component that takes the configuration and generates the form.
In general, the more complex the customization, the more useful the schematic approach.
{@a integrating-with-the-cli} {@a integrating-with-the-cli}
## Integrating with the CLI ## Integración con el CLI usando generación de código con los schematics.
A library can include [schematics](guide/glossary#schematic) that allow it to integrate with the Angular CLI. Comúnmente una librería incluye *código reusable* que define componentes, servicios y otros Artefactos de Angular (pipes, directivas y etc.) que tu simplemente importas a un proyecto.
Una librería es empaquetada dentro de un paquete npm para publicar y compartir.
* Include an installation schematic so that `ng add` can add your library to a project. Este paquete también puede incluir [schematics](guide/glossary#schematic) que proporciona instrucciones para generar o transformar código directamente un tu proyecto, de la misma forma que el CLI crea un nuevo componente genérico con `ng generate component`.
* Include generation schematics in your library so that `ng generate` can scaffold your defined artifacts (components, services, tests, and so on) in a project. Un 'schematic' empaquetado con una librería puede por ejemplo proporcionar al Angular CLI la información que necesita para generar un componente que configura y usa una particular característica o conjunto de características, definido en la librería.
* Include an update schematic so that `ng update` can update your librarys dependencies and provide migrations for breaking changes in new releases. Un ejemplo de esto es el 'schematic' de navegación de Angular Material el cual configura los CDK's `BreakpointObserver` y lo usa con los componentes `MatSideNav` y `MatToolbar` de Angular Material.
To learn more, see [Schematics Overview](guide/schematics) and [Schematicsfor Libraries](guide/schematics-for-libraries). Puedes crear e incluir los siguientes tipos de 'schematics'.
## Publishing your library * Incluye un 'schematic' de instalación para que con `ng add` puedas agregar tu libería a un proyecto.
Use the Angular CLI and the npm package manager to build and publish your library as an npm package. * Incluye un 'schematic' de generación en tu librería para que con `ng generate` puedas hacer scaffolding de sus artefactos (componentes, servicios, pruebas y etc) en un proyecto.
Before publishing a library to NPM, build it using the `--prod` flag which will use the older compiler and runtime known as View Engine instead of Ivy. * Incluye un 'schematic' de actualización para que con `ng update` puedas actualizar las dependencias de tu librería y proporcionar migraciones para cambios importantes en un nuevo release.
Lo que incluya tu librería depende de tu tarea.
Por ejemplo, podrías definir un 'schematic' para crear un desplegable (dropdown) que esta pre-poblado con datos para mostrar como agregarlo a una aplicación.
Si quieres un desplegable (dropdown) que contendrá valores diferentes cada vez, tu librería podría definir un 'schematic' para crearlo con una configuración dada. Los desarrolladores podrán entonces usar `ng generate` para configurar una instancia para sus propias aplicaciones.
Supón que quieres leer un archivo de configuración y entonces generar una formulario con base a la configuración.
Si este formulario necesita personalización adicional por parte del desarrollador que esta usando tu librería, esto podría trabajar mejor como un 'schematic'.
Sin embargo, si el formulario siempre será el mismo y no necesita de mucha personalización por parte de los desarrolladores, entonces podría crear un componente dinámico que tome la configuración y genere el formulario.
En general, entre más compleja sea personalización, la más util será en enfoque de un 'schematic'.
Para aprender más, véase [Vista general de Schematics](guide/schematics) y [Schematicspara librerías](guide/schematics-for-libraries).
{@a publishing-your-library}
## Publicando tu librería
Usa el Angular CLI y el gestor de paquetes npm para construir y publicar tu librería como un paquete npm.
Antes de publicar una librería a NPM, constrúyela usando la bandera `--prod` la cúal usará el compilador y tiempo de ejecución (runtime) más antiguos como 'View Engine' en vez de 'Ivy'.
<code-example language="bash"> <code-example language="bash">
ng build my-lib --prod ng build my-lib --prod
@ -119,48 +128,50 @@ cd dist/my-lib
npm publish npm publish
</code-example> </code-example>
If you've never published a package in npm before, you must create a user account. Read more in [Publishing npm Packages](https://docs.npmjs.com/getting-started/publishing-npm-packages). Si nunca has publicado un paquete en npm antes, tu debes crear un cuenta. Lee más en [Publicando paquetes npm](https://docs.npmjs.com/getting-started/publishing-npm-packages).
<div class="alert is-important"> <div class="alert is-important">
For now, it is not recommended to publish Ivy libraries to NPM because Ivy generated code is not backward compatible with View Engine, so apps using View Engine will not be able to consume them. Furthermore, the internal Ivy instructions are not yet stable, which can potentially break consumers using a different Angular version from the one used to build the library. Por ahora, no es recomendando publicar librerías con Ivy hacia NPM por que Ivy genera código que no es retrocompatible con 'View Engine', entonces las aplicaciones usando 'View Engine' no podrán consumirlas. Además, las instrucciones internas de IVY no son estables aun, lo cual puede romper potencialmente a los consumidores que usan una diferente versión de Angular a la que uso para construir la libería.
When a published library is used in an Ivy app, the Angular CLI will automatically convert it to Ivy using a tool known as the Angular compatibility compiler (`ngcc`). Thus, publishing your libraries using the View Engine compiler ensures that they can be transparently consumed by both View Engine and Ivy apps. Cuando una librería publicada es usada en una aplicación con Ivy, el Angular CLI automáticamente la convertirá a Ivy usando una herramienta conocida como el compilador de compatibilidad Angular (`ngcc`). Por lo tanto, publicar tus librerías usado el compilador 'View Engine' garantiza que ellas puede ser consumidas de forma transparente por ambos motores 'View Engine' y 'Ivy'.
</div> </div>
{@a lib-assets} {@a lib-assets}
## Managing assets in a library ## Gestionando activos (assets) en una librería.
Starting with version 9.x of the [ng-packagr](https://github.com/ng-packagr/ng-packagr/blob/master/README.md) tool, you can configure the tool to automatically copy assets into your library package as part of the build process. Desde la versión 9.x de la herramienta [ng-packagr](https://github.com/ng-packagr/ng-packagr/blob/master/README.md), puedes configurar la herramienta para que automáticamente copie los activos (assets) dentro de el paquete de librería como parte del proceso de construcción.
You can use this feature when your library needs to publish optional theming files, Sass mixins, or documentation (like a changelog). Puedes usar esta característica cuando tu librería necesite publicar archivos de temas opcionales, funciones de Sass o documentación (como un registro de cambios 'changelog').
* Learn how to [copy assets into your library as part of the build](https://github.com/ng-packagr/ng-packagr/blob/master/docs/copy-assets.md). * Aprende como [copiar activos (assets) dentro de tu librería como parte de la construcción](https://github.com/ng-packagr/ng-packagr/blob/master/docs/copy-assets.md).
* Learn more about how to use the tool to [embed assets in CSS](https://github.com/ng-packagr/ng-packagr/blob/master/docs/embed-assets-css.md). * Aprende más acerca de como usar la herramienta para [incrustar activos (assets) de CSS](https://github.com/ng-packagr/ng-packagr/blob/master/docs/embed-assets-css.md).
## Linked libraries ## Vinculando librerías
While working on a published library, you can use [npm link](https://docs.npmjs.com/cli/link) to avoid reinstalling the library on every build. Mientras trabajas en un librería publicada, puedes usar [npm link](https://docs.npmjs.com/cli/link) para evitar re instalar la librería en cada construcción.
The library must be rebuilt on every change. La librería debe ser reconstruida en cada cambio.
When linking a library, make sure that the build step runs in watch mode, and that the library's `package.json` configuration points at the correct entry points. Cuando vinculas una librería, asegurate que el paso de construir corra en modo vigía (watch mode) y que el `package.json` de la librería configure los puntos de entrada correctos.
For example, `main` should point at a JavaScript file, not a TypeScript file. Por ejemplo, `main` debería apuntar a un archivo JavaScript, no a un archivo TypeScript.
## Use TypeScript path mapping for peer dependencies ## Utiliza el mapeo de rutas de TypeScript por las dependencias de pares.
Angular libraries should list all `@angular/*` dependencies as peer dependencies. Las librerías de Angular deben enumerar todas las dependencias `@angular/*` como dependencias de pares.
This ensures that when modules ask for Angular, they all get the exact same module. Esto garantiza que cuando los módulos solicitan Angular, todos ellos obtienen exactamente el mismo módulo.
If a library lists `@angular/core` in `dependencies` instead of `peerDependencies`, it might get a different Angular module instead, which would cause your application to break. Si tu librería lista `@angular/core` en `dependencies` en vez de en `peerDependencies`, podría obtener un módulo Angular diferente, lo qué haría que tu aplicación se rompiera.
While developing a library, you must install all peer dependencies through `devDependencies` to ensure that the library compiles properly. Cuando desarrollas una librería, tu debes instalar todas las dependencias de pares mediante `devDependencies` para garantizar que la librería compile apropiadamente.
A linked library will then have its own set of Angular libraries that it uses for building, located in its `node_modules` folder. Una librería vinculada tendrá su propio conjunto de librerías Angular que usa para construir, ubicados en su carpeta `node_modules`.
However, this can cause problems while building or running your application.
To get around this problem you can use TypeScript path mapping to tell TypeScript that it should load some modules from a specific location. Sin embargo, esto puede causar problemas mientras construyes o corres tu aplicación.
List all the peer dependencies that your library uses in the workspace TypeScript configuration file `./tsconfig.json`, and point them at the local copy in the app's `node_modules` folder.
Para evitar este problema tu puedes usar el mapeo de rutas de TypeScript para indicarle a TypeScript que este debería cargar algunos módulos desde una ubicación especifica.
Enumera todas las dependencias de pares que tu librería usa en el archivo de configuración `./tsconfig.json` del espacio de trabajo de TypeScript, y apúntalos a la copia local en la carpeta `node_modules` de la aplicación.
``` ```
{ {
@ -176,47 +187,47 @@ List all the peer dependencies that your library uses in the workspace TypeScrip
} }
``` ```
This mapping ensures that your library always loads the local copies of the modules it needs. Este mapeador garantiza que tu librería siempre cargue las copias locales del módulo que necesita.
## Using your own library in apps ## Usando tu propia librería en aplicaciones.
You don't have to publish your library to the npm package manager in order to use it in your own apps, but you do have to build it first. No tienes que publicar tu librería hacia el gestor de paquetes npm para usarla en tus propias aplicaciones, pero tienes que construirla primero.
To use your own library in an app: Para usar tu propia librería en tu aplicación:
* Build the library. You cannot use a library before it is built. * Construye la librería. No puedes usar una librería antes que se construya.
<code-example language="bash"> <code-example language="bash">
ng build my-lib ng build my-lib
</code-example> </code-example>
* In your apps, import from the library by name: * En tus aplicaciones, importa la librería por el nombre:
``` ```
import { myExport } from 'my-lib'; import { myExport } from 'my-lib';
``` ```
### Building and rebuilding your library ### Construyendo y re construyendo tu librería.
The build step is important if you haven't published your library as an npm package and then installed the package back into your app from npm. El paso de construir es importante si no tienes publicada tu librería como un paquete npm y luego ha instalado el paquete de nuevo dentro tu aplicación desde npm.
For instance, if you clone your git repository and run `npm install`, your editor will show the `my-lib` imports as missing if you haven't yet built your library. Por ejemplo, si clonas tu repositorio git y corres `npm install`, tu editor mostrará la importación de `my-lib` como perdida si no tienes aun construida tu librería.
<div class="alert is-helpful"> <div class="alert is-helpful">
When you import something from a library in an Angular app, Angular looks for a mapping between the library name and a location on disk. Cuando importas algo desde una librería en una aplicación Angular, Angular busca un mapeo entre el nombre de librería y una ubicación en disco.
When you install a library package, the mapping is in the `node_modules` folder. When you build your own library, it has to find the mapping in your `tsconfig` paths. Cuando instalas un paquete de librería, el mapeo esta en la carpeta `node_modules`. Cuando construyes tu propia librería, tiene que encontrar el mapeo en tus rutas de `tsconfig`.
Generating a library with the Angular CLI automatically adds its path to the `tsconfig` file. Generando una librería con el Angular CLI automáticamente agrega su ruta en el archivo `tsconfig`.
The Angular CLI uses the `tsconfig` paths to tell the build system where to find the library. El Angular CLI usa las rutas `tsconfig` para indicarle al sistema construido donde encontrar la librería.
</div> </div>
If you find that changes to your library are not reflected in your app, your app is probably using an old build of the library. Si descubres que los cambios en tu librería no son reflejados en tu aplicación, tu aplicación probablemente esta usando una construcción antigua de la librería.
You can rebuild your library whenever you make changes to it, but this extra step takes time. Puedes re construir tu librería cada vez que hagas cambios en esta, pero este paso extra toma tiempo.
*Incremental builds* functionality improves the library-development experience. Las *construcciones incrementales* funcionalmente mejoran la experiencia de desarrollo de librerías.
Every time a file is changed a partial build is performed that emits the amended files. Cada vez que un archivo es cambiando una construcción parcial es realizada y esta emite los archivos modificados.
Incremental builds can be run as a background process in your dev environment. To take advantage of this feature add the `--watch` flag to the build command: Las *Construcciones incrementales* puede ser ejecutadas como un proceso en segundo plano en tu entorno de desarrollo. Para aprovechar esta característica agrega la bandera `--watch` al comando de construcción:
<code-example language="bash"> <code-example language="bash">
ng build my-lib --watch ng build my-lib --watch
@ -224,15 +235,15 @@ ng build my-lib --watch
<div class="alert is-important"> <div class="alert is-important">
The CLI `build` command uses a different builder and invokes a different build tool for libraries than it does for applications. El comando `build` del CLI utiliza un constructor diferente e invoca una herramienta de construcción diferente para las librerías que para las aplicaciones.
* The build system for apps, `@angular-devkit/build-angular`, is based on `webpack`, and is included in all new Angular CLI projects. * El sistema de construcción para aplicaciones, `@angular-devkit/build-angular`, esta basado en `webpack`, y esta incluida en todos los nuevos proyectos de Angular CLI.
* The build system for libraries is based on `ng-packagr`. It is only added to your dependencies when you add a library using `ng generate library my-lib`. * El sistema de construcción esta basado en `ng-packagr`. Este es solo agregado en tus dependencias cuando agregas una librería usando `ng generate library my-lib`.
The two build systems support different things, and even where they support the same things, they do those things differently. Los dos sistemas de construcción soportan diferentes cosas e incluso si ellos soportan las mismas cosas, ellos hacen esas cosas de forma diferente.
This means that the TypeScript source can result in different JavaScript code in a built library than it would in a built application. Esto quiere decir que la fuente de TypeScript puede generar en código JavaScript diferente en una librería construida que en una aplicación construida.
For this reason, an app that depends on a library should only use TypeScript path mappings that point to the *built library*. Por esta razón, una aplicación que depende de una librería debería solo usar el mapeo de rutas de TypeScript que apunte a la *librería construida*.
TypeScript path mappings should *not* point to the library source `.ts` files. El mapeo de rutas de TypeScript no debería apuntar hacia los archivos `.ts` fuente de la librería.
</div> </div>

View File

@ -14,7 +14,7 @@ established through the components' [view objects](guide/glossary#view).
Each component has a *host view*, and can have additional *embedded views*. Each component has a *host view*, and can have additional *embedded views*.
An embedded view in component A is the An embedded view in component A is the
host view of component B, which can in turn have embedded view. host view of component B, which can in turn have embedded view.
This means that there is a [view hierarchy](guide/glossary#view-hierarchy) for each component, This means that there is a [view hierarchy](guide/glossary#view-tree) for each component,
of which that component's host view is the root. of which that component's host view is the root.
There is an API for navigating *down* the view hierarchy. There is an API for navigating *down* the view hierarchy.

View File

@ -448,13 +448,13 @@ When targeting older browsers, [polyfills](guide/browser-support#polyfills) can
To maximize compatibility, you could ship a single bundle that includes all your compiled code, plus any polyfills that may be needed. To maximize compatibility, you could ship a single bundle that includes all your compiled code, plus any polyfills that may be needed.
Users with modern browsers, however, shouldn't have to pay the price of increased bundle size that comes with polyfills they don't need. Users with modern browsers, however, shouldn't have to pay the price of increased bundle size that comes with polyfills they don't need.
Differential loading, which is supported by default in Angular CLI version 8 and higher, solves this problem. Differential loading, which is supported in Angular CLI version 8 and higher, can help solve this problem.
Differential loading is a strategy that allows your web application to support multiple browsers, but only load the necessary code that the browser needs. When differential loading is enabled (which is the default) the CLI builds two separate bundles as part of your deployed application. Differential loading is a strategy that allows your web application to support multiple browsers, but only load the necessary code that the browser needs. When differential loading is enabled the CLI builds two separate bundles as part of your deployed application.
* The first bundle contains modern ES2015 syntax, takes advantage of built-in support in modern browsers, ships fewer polyfills, and results in a smaller bundle size. * The first bundle contains modern ES2015 syntax. This bundle takes advantage of built-in support in modern browsers, ships fewer polyfills, and results in a smaller bundle size.
* The second bundle contains code in the old ES5 syntax, along with all necessary polyfills. This results in a larger bundle size, but supports older browsers. * The second bundle contains code in the old ES5 syntax, along with all necessary polyfills. This second bundle is larger, but supports older browsers.
### Differential builds ### Differential builds
@ -463,9 +463,9 @@ The [`ng build` CLI command](cli/build) queries the browser configuration and th
The following configurations determine your requirements. The following configurations determine your requirements.
* Browsers list * Browserslist
The `browserslist` configuration file is included in your application [project structure](guide/file-structure#application-configuration-files) and provides the minimum browsers your application supports. See the [Browserslist spec](https://github.com/browserslist/browserslist) for complete configuration options. The Browserslist configuration file is included in your application [project structure](guide/file-structure#application-configuration-files) and provides the minimum browsers your application supports. See the [Browserslist spec](https://github.com/browserslist/browserslist) for complete configuration options.
* TypeScript configuration * TypeScript configuration
@ -509,16 +509,27 @@ Each script tag has a `type="module"` or `nomodule` attribute. Browsers with nat
### Configuring differential loading ### Configuring differential loading
Differential loading is supported by default with version 8 and later of the Angular CLI. To include differential loading in your application builds, you must configure the Browserslist and TypeScript configuration files in your application project.
For each application project in your workspace, you can configure how builds are produced based on the `browserslist` and `tsconfig.json` configuration files in your application project.
For a newly created Angular application, legacy browsers such as IE 9-11 are ignored, and the compilation target is ES2015. The following examples show a `browserlistrc` and `tsconfig.json` file for a newly created Angular application. In this configuration, legacy browsers such as IE 9-11 are ignored, and the compilation target is ES2015.
<code-example language="none" header="browserslist"> <code-example language="none" header="browserslistrc">
> 0.5% # This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
last 2 versions # For additional information regarding the format and rule options, please see:
# https://github.com/browserslist/browserslist#queries
# For the full list of supported browsers by the Angular framework, please see:
# https://angular.io/guide/browser-support
# You can see what browsers were selected by your queries by running:
# npx browserslist
last 1 Chrome version
last 1 Firefox version
last 2 Edge major versions
last 2 Safari major version
last 2 iOS major versions
Firefox ESR Firefox ESR
not dead
not IE 9-11 # For IE 9-11 support, remove 'not'. not IE 9-11 # For IE 9-11 support, remove 'not'.
</code-example> </code-example>
@ -549,36 +560,24 @@ not IE 9-11 # For IE 9-11 support, remove 'not'.
</code-example> </code-example>
The default configuration creates two builds, with differential loading enabled.
<div class="alert is-important"> <div class="alert is-important">
To see which browsers are supported with the default configuration and determine which settings meet to your browser support requirements, see the [Browserslist compatibility page](https://browserl.ist/?q=%3E+0.5%25%2C+last+2+versions%2C+Firefox+ESR%2C+not+dead%2C+not+IE+9-11). To see which browsers are supported and determine which settings meet to your browser support requirements, see the [Browserslist compatibility page](https://browserl.ist/?q=%3E+0.5%25%2C+last+2+versions%2C+Firefox+ESR%2C+not+dead%2C+not+IE+9-11).
</div> </div>
The `browserslist` configuration allows you to ignore browsers without ES2015 support. In this case, a single build is produced. The Browserslist configuration allows you to ignore browsers without ES2015 support. In this case, a single build is produced.
If your `browserslist` configuration includes support for any legacy browsers, the build target in the TypeScript configuration determines whether the build will support differential loading. If your Browserslist configuration includes support for any legacy browsers, the build target in the TypeScript configuration determines whether the build will support differential loading.
{@a configuration-table } {@a configuration-table }
| browserslist | ES target | Build result | | Browserslist | ES target | Build result |
| -------- | -------- | -------- | | -------- | -------- | -------- |
| ES5 support disabled | es2015 | Single build, ES5 not required | | ES5 support disabled | es2015 | Single build, ES5 not required |
| ES5 support enabled | es5 | Single build w/conditional polyfills for ES5 only | | ES5 support enabled | es5 | Single build w/conditional polyfills for ES5 only |
| ES5 support enabled | es2015 | Differential loading (two builds w/conditional polyfills) | | ES5 support enabled | es2015 | Differential loading (two builds w/conditional polyfills) |
### Opting out of differential loading
Differential loading can be explicitly disabled if it causes unexpected issues, or if you need to target ES5 specifically for legacy browser support.
To explicitly disable differential loading and create an ES5 build:
- Enable the `dead` or `IE` browsers in the `browserslist` configuration file by removing the `not` keyword in front of them.
- To create a single ES5 build, set the target in the `compilerOptions` to `es5`.
{@a test-and-serve} {@a test-and-serve}
## Local development in older browsers ## Local development in older browsers

View File

@ -58,12 +58,12 @@ v9 - v12
| `@angular/core` | [`ANALYZE_FOR_ENTRY_COMPONENTS`](api/core/ANALYZE_FOR_ENTRY_COMPONENTS) | <!--v9--> v11 | | `@angular/core` | [`ANALYZE_FOR_ENTRY_COMPONENTS`](api/core/ANALYZE_FOR_ENTRY_COMPONENTS) | <!--v9--> v11 |
| `@angular/router` | [`loadChildren` string syntax](#loadChildren) | <!--v9--> v11 | | `@angular/router` | [`loadChildren` string syntax](#loadChildren) | <!--v9--> v11 |
| `@angular/core/testing` | [`TestBed.get`](#testing) | <!--v9--> v12 | | `@angular/core/testing` | [`TestBed.get`](#testing) | <!--v9--> v12 |
| `@angular/core/testing` | [`async`](#testing) | <!--v9--> v12 |
| `@angular/router` | [`ActivatedRoute` params and `queryParams` properties](#activatedroute-props) | unspecified | | `@angular/router` | [`ActivatedRoute` params and `queryParams` properties](#activatedroute-props) | unspecified |
| template syntax | [`/deep/`, `>>>`, and `::ng-deep`](#deep-component-style-selector) | <!--v7--> unspecified | | template syntax | [`/deep/`, `>>>`, and `::ng-deep`](#deep-component-style-selector) | <!--v7--> unspecified |
| browser support | [`IE 9 and 10, IE mobile`](#ie-9-10-and-mobile) | <!--v10--> v11 | | browser support | [`IE 9 and 10, IE mobile`](#ie-9-10-and-mobile) | <!--v10--> v11 |
For information about Angular CDK and Angular Material deprecations, see the [changelog](https://github.com/angular/components/blob/master/CHANGELOG.md).
## Deprecated APIs ## Deprecated APIs
@ -109,6 +109,7 @@ Tip: In the [API reference section](api) of this doc site, deprecated APIs are i
| API | Replacement | Deprecation announced | Notes | | API | Replacement | Deprecation announced | Notes |
| --- | ----------- | --------------------- | ----- | | --- | ----------- | --------------------- | ----- |
| [`TestBed.get`](api/core/testing/TestBed#get) | [`TestBed.inject`](api/core/testing/TestBed#inject) | v9 | Same behavior, but type safe. | | [`TestBed.get`](api/core/testing/TestBed#get) | [`TestBed.inject`](api/core/testing/TestBed#inject) | v9 | Same behavior, but type safe. |
| [`async`](api/core/testing/async) | [`waitForAsync`](api/core/testing/waitForAsync) | v10 | Same behavior, but rename to avoid confusion. |
{@a forms} {@a forms}
@ -478,7 +479,7 @@ The final decision was made on three key points:
{@a wrapped-value} {@a wrapped-value}
### `WrappedValue` ### `WrappedValue`
The purpose of `WrappedValue` is to allow the same object instance to be treated as different for the purposes of change detection. The purpose of `WrappedValue` is to allow the same object instance to be treated as different for the purposes of change detection.
It is commonly used with the `async` pipe in the case where the `Observable` produces the same instance of the value. It is commonly used with the `async` pipe in the case where the `Observable` produces the same instance of the value.
@ -488,7 +489,7 @@ No replacement is planned for this deprecation.
If you rely on the behavior that the same object instance should cause change detection, you have two options: If you rely on the behavior that the same object instance should cause change detection, you have two options:
- Clone the resulting value so that it has a new identity. - Clone the resulting value so that it has a new identity.
- Explicitly call [`ChangeDetectorRef.detectChanges()`](api/core/ChangeDetectorRef#detectchanges) to force the update. - Explicitly call [`ChangeDetectorRef.detectChanges()`](api/core/ChangeDetectorRef#detectchanges) to force the update.
{@a deprecated-cli-flags} {@a deprecated-cli-flags}
## Deprecated CLI APIs and Options ## Deprecated CLI APIs and Options

View File

@ -0,0 +1,104 @@
# Feature modules
Feature modules are NgModules for the purpose of organizing code.
For the final sample app with a feature module that this page describes,
see the <live-example></live-example>.
<hr>
As your app grows, you can organize code relevant for a specific feature.
This helps apply clear boundaries for features. With feature modules,
you can keep code related to a specific functionality or feature
separate from other code. Delineating areas of your
app helps with collaboration between developers and teams, separating
directives, and managing the size of the root module.
## Feature modules vs. root modules
A feature module is an organizational best practice, as opposed to a concept of the core Angular API. A feature module delivers a cohesive set of functionality focused on a
specific application need such as a user workflow, routing, or forms.
While you can do everything within the root module, feature modules
help you partition the app into focused areas. A feature module
collaborates with the root module and with other modules through
the services it provides and the components, directives, and
pipes that it shares.
## How to make a feature module
Assuming you already have an app that you created with the [Angular CLI](cli), create a feature
module using the CLI by entering the following command in the
root project directory. Replace `CustomerDashboard` with the
name of your module. You can omit the "Module" suffix from the name because the CLI appends it:
```sh
ng generate module CustomerDashboard
```
This causes the CLI to create a folder called `customer-dashboard` with a file inside called `customer-dashboard.module.ts` with the following contents:
```typescript
import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";
@NgModule({
imports: [CommonModule],
declarations: [],
})
export class CustomerDashboardModule {}
```
The structure of an NgModule is the same whether it is a root module or a feature module. In the CLI generated feature module, there are two JavaScript import statements at the top of the file: the first imports `NgModule`, which, like the root module, lets you use the `@NgModule` decorator; the second imports `CommonModule`, which contributes many common directives such as `ngIf` and `ngFor`. Feature modules import `CommonModule` instead of `BrowserModule`, which is only imported once in the root module. `CommonModule` only contains information for common directives such as `ngIf` and `ngFor` which are needed in most templates, whereas `BrowserModule` configures the Angular app for the browser which needs to be done only once.
The `declarations` array is available for you to add declarables, which
are components, directives, and pipes that belong exclusively to this particular module. To add a component, enter the following command at the command line where `customer-dashboard` is the directory where the CLI generated the feature module and `CustomerDashboard` is the name of the component:
```sh
ng generate component customer-dashboard/CustomerDashboard
```
This generates a folder for the new component within the customer-dashboard folder and updates the feature module with the `CustomerDashboardComponent` info:
<code-example path="feature-modules/src/app/customer-dashboard/customer-dashboard.module.ts" region="customer-dashboard-component" header="src/app/customer-dashboard/customer-dashboard.module.ts"></code-example>
The `CustomerDashboardComponent` is now in the JavaScript import list at the top and added to the `declarations` array, which lets Angular know to associate this new component with this feature module.
## Importing a feature module
To incorporate the feature module into your app, you have to let the root module, `app.module.ts`, know about it. Notice the `CustomerDashboardModule` export at the bottom of `customer-dashboard.module.ts`. This exposes it so that other modules can get to it. To import it into the `AppModule`, add it to the imports in `app.module.ts` and to the `imports` array:
<code-example path="feature-modules/src/app/app.module.ts" region="app-module" header="src/app/app.module.ts"></code-example>
Now the `AppModule` knows about the feature module. If you were to add any service providers to the feature module, `AppModule` would know about those too, as would any other feature modules. However, NgModules dont expose their components.
## Rendering a feature modules component template
When the CLI generated the `CustomerDashboardComponent` for the feature module, it included a template, `customer-dashboard.component.html`, with the following markup:
<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"></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 `CustomerDashboardComponent`:
<code-example path="feature-modules/src/app/customer-dashboard/customer-dashboard.module.ts" region="component-exports" header="src/app/customer-dashboard/customer-dashboard.module.ts"></code-example>
Next, in the `AppComponent`, `app.component.html`, add the tag `<app-customer-dashboard>`:
<code-example path="feature-modules/src/app/app.component.html" region="app-component-template" header="src/app/app.component.html"></code-example>
Now, in addition to the title that renders by default, the `CustomerDashboardComponent` template renders too:
<div class="lightbox">
<img src="generated/images/guide/feature-modules/feature-module.png" alt="feature module component">
</div>
<hr />
## More on NgModules
You may also be interested in the following:
- [Lazy Loading Modules with the Angular Router](guide/lazy-loading-ngmodules).
- [Providers](guide/providers).
- [Types of Feature Modules](guide/module-types).

View File

@ -1,106 +1,79 @@
# Feature modules # Módulos de funcionalidades
Feature modules are NgModules for the purpose of organizing code. Los módulos de funcionalidades son NgModules con el propósito de organizar el código.
For the final sample app with a feature module that this page describes, Para la aplicación de muestra final con un módulo de funcionalidades que se describe en esta página,
see the <live-example></live-example>. ver el <live-example> </live-example>.
<hr> <hr>
As your app grows, you can organize code relevant for a specific feature. A medida que tu aplicación crece, puedes organizar el código relevante para una funcionalidad específica. Esto ayuda a aplicar límites claros para las funcionalidades. Con módulos de funcionalidades,
This helps apply clear boundaries for features. With feature modules, puedes mantener el código relacionado con una funcionalidad o característica específica
you can keep code related to a specific functionality or feature separado de otro código. Delinear áreas de suaplicación ayuda con la colaboración entre desarrolladores y equipos, separando directivas y gestionar el tamaño del módulo raíz.
separate from other code. Delineating areas of your
app helps with collaboration between developers and teams, separating
directives, and managing the size of the root module.
## Módulos de funcionalidades frente a módulos raíz
## Feature modules vs. root modules Un módulo de funcionalidades es una mejor práctica organizativa, a diferencia de un concepto de la API angular principal. Un módulo de funcionalidades ofrece un conjunto coherente de funcionalidades centradas en una necesidad de aplicación específica, como un flujo de trabajo, enrutamiento o formularios de usuario. Si bien puede hacer todo dentro del módulo raíz, los módulos de funcionalidades lo ayudan a dividir la aplicación en áreas específicas. Un módulo de funcionalidades colabora con el módulo raíz y con otros módulos a través de los servicios que proporciona y los componentes, directivas y canalizaciones que comparte.
A feature module is an organizational best practice, as opposed to a concept of the core Angular API. A feature module delivers a cohesive set of functionality focused on a ## Cómo hacer un módulo de funcionalidades
specific application need such as a user workflow, routing, or forms.
While you can do everything within the root module, feature modules
help you partition the app into focused areas. A feature module
collaborates with the root module and with other modules through
the services it provides and the components, directives, and
pipes that it shares.
## How to make a feature module Suponiendo que ya tienes una aplicación que creó con la [CLI Angular](cli), crea un módulo de funcionalidades usando la CLI ingresando el siguiente comando en el directorio raíz del proyecto. Reemplaza `CustomerDashboard` con el nombre de tu módulo. Puedes omitir el sufijo "Módulo" / "Module" del nombre porque la CLI lo agrega:
Assuming you already have an app that you created with the [Angular CLI](cli), create a feature
module using the CLI by entering the following command in the
root project directory. Replace `CustomerDashboard` with the
name of your module. You can omit the "Module" suffix from the name because the CLI appends it:
```sh ```sh
ng generate module CustomerDashboard ng generate module CustomerDashboard
``` ```
Esto hace que la CLI cree una carpeta llamada `customer-dashboard` con un archivo dentro llamado` customer-dashboard.module.ts` con el siguiente contenido:
This causes the CLI to create a folder called `customer-dashboard` with a file inside called `customer-dashboard.module.ts` with the following contents:
```typescript ```typescript
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
@NgModule({ @NgModule({
imports: [ imports: [CommonModule],
CommonModule declarations: [],
],
declarations: []
}) })
export class CustomerDashboardModule { } export class CustomerDashboardModule {}
``` ```
The structure of an NgModule is the same whether it is a root module or a feature module. In the CLI generated feature module, there are two JavaScript import statements at the top of the file: the first imports `NgModule`, which, like the root module, lets you use the `@NgModule` decorator; the second imports `CommonModule`, which contributes many common directives such as `ngIf` and `ngFor`. Feature modules import `CommonModule` instead of `BrowserModule`, which is only imported once in the root module. `CommonModule` only contains information for common directives such as `ngIf` and `ngFor` which are needed in most templates, whereas `BrowserModule` configures the Angular app for the browser which needs to be done only once. La estructura de un NgModule es la misma si es un módulo raíz o un módulo de funcionalidades. En el módulo de funcionalidades generado por CLI, hay dos declaraciones de importación de JavaScript en la parte superior del archivo: la primera importa `NgModule`, que, como el módulo raíz, le permite usar el decorador `@NgModule`; el segundo importa `CommonModule`, que aporta muchas directivas comunes como `ngIf` y `ngFor`. Los módulos de funcionalidades importan `CommonModule` en lugar de `BrowserModule`, que solo se importa una vez en el módulo raíz. `CommonModule` solo contiene información para directivas comunes como `ngIf` y `ngFor` que se necesitan en la mayoría de las plantillas, mientras que `BrowserModule` configura la aplicación Angular para el navegador, lo cual debe hacerse solo una vez.
The `declarations` array is available for you to add declarables, which La matriz `declaraciones` está disponible para que agregue declarables, que son componentes, directivas y canalizaciones que pertenecen exclusivamente a este módulo en particular. Para agregar un componente, ingresa el siguiente comando en la línea de comando donde `customer-dashboard` es el directorio donde la CLI generó el módulo de funciones y CustomerDashboard` es el nombre del componente:
are components, directives, and pipes that belong exclusively to this particular module. To add a component, enter the following command at the command line where `customer-dashboard` is the directory where the CLI generated the feature module and `CustomerDashboard` is the name of the component:
```sh ```sh
ng generate component customer-dashboard/CustomerDashboard ng generate component customer-dashboard/CustomerDashboard
``` ```
This generates a folder for the new component within the customer-dashboard folder and updates the feature module with the `CustomerDashboardComponent` info: Esto genera una carpeta para el nuevo componente dentro de la carpeta del panel del cliente y actualiza el módulo de funcionalidades con la información de `CustomerDashboardComponent`:
<code-example path="feature-modules/src/app/customer-dashboard/customer-dashboard.module.ts" region="customer-dashboard-component" header="src/app/customer-dashboard/customer-dashboard.module.ts"></code-example> <code-example path="feature-modules/src/app/customer-dashboard/customer-dashboard.module.ts" region="customer-dashboard-component" header="src/app/customer-dashboard/customer-dashboard.module.ts"></code-example>
El `CustomerDashboardComponent` ahora se encuentra en la lista de importación de JavaScript en la parte superior y se agregó a la matriz de `declaraciones`, lo que le permite a Angular asociar este nuevo componente con este módulo de funciones.
## Importación de un módulo de funcionalidades
The `CustomerDashboardComponent` is now in the JavaScript import list at the top and added to the `declarations` array, which lets Angular know to associate this new component with this feature module. Para incorporar el módulo de funcionalidades en tu aplicación, debes informar al módulo raíz, `app.module.ts`. Observa la exportación de "CustomerDashboardModule" en la parte inferior de `customer-dashboard.module.ts`. Esto lo expone para que otros módulos puedan acceder a él. Para importarlo en el `AppModule`, agrégalo a las importaciones en` app.module.ts` y al arreglo de `import`:
## Importing a feature module
To incorporate the feature module into your app, you have to let the root module, `app.module.ts`, know about it. Notice the `CustomerDashboardModule` export at the bottom of `customer-dashboard.module.ts`. This exposes it so that other modules can get to it. To import it into the `AppModule`, add it to the imports in `app.module.ts` and to the `imports` array:
<code-example path="feature-modules/src/app/app.module.ts" region="app-module" header="src/app/app.module.ts"></code-example> <code-example path="feature-modules/src/app/app.module.ts" region="app-module" header="src/app/app.module.ts"></code-example>
Ahora el `AppModule` conoce el módulo de funcionalidades. Si tuviera que agregar cualquier proveedor de servicios al módulo de funcionalidades, `AppModule` también lo conocería, al igual que cualquier otro módulo de funcionalidades. Sin embargo, los NgModules no exponen sus componentes.
Now the `AppModule` knows about the feature module. If you were to add any service providers to the feature module, `AppModule` would know about those too, as would any other feature modules. However, NgModules dont expose their components. ## Representación de la plantilla de componente de un módulo de funcionalidades
Cuando la CLI generó el `CustomerDashboardComponent` para el módulo de funcionalidades, incluyó una plantilla, `customer-dashboard.component.html`, con el siguiente marcado:
## Rendering a feature modules component template
When the CLI generated the `CustomerDashboardComponent` for the feature module, it included a template, `customer-dashboard.component.html`, with the following markup:
<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"></code-example> <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"></code-example>
Para ver este HTML en el `AppComponent`, primero tienes que exportar el `CustomerDashboardComponent` en el `CustomerDashboardModule`. En `customer-dashboard.module.ts`, justo debajo de la matriz de `declaraciones`, agrega una matriz de `exportaciones` que contenga `CustomerDashboardComponent`:
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`:
<code-example path="feature-modules/src/app/customer-dashboard/customer-dashboard.module.ts" region="component-exports" header="src/app/customer-dashboard/customer-dashboard.module.ts"></code-example> <code-example path="feature-modules/src/app/customer-dashboard/customer-dashboard.module.ts" region="component-exports" header="src/app/customer-dashboard/customer-dashboard.module.ts"></code-example>
Luego, en el `AppComponent`, `app.component.html`, agrega la etiqueta `<app-customer-dashboard>`:
Next, in the `AppComponent`, `app.component.html`, add the tag `<app-customer-dashboard>`:
<code-example path="feature-modules/src/app/app.component.html" region="app-component-template" header="src/app/app.component.html"></code-example> <code-example path="feature-modules/src/app/app.component.html" region="app-component-template" header="src/app/app.component.html"></code-example>
Ahora, además del título que se representa de forma predeterminada, la plantilla `CustomerDashboardComponent` también se representa:
Now, in addition to the title that renders by default, the `CustomerDashboardComponent` template renders too:
<div class="lightbox"> <div class="lightbox">
<img src="generated/images/guide/feature-modules/feature-module.png" alt="feature module component"> <img src="generated/images/guide/feature-modules/feature-module.png" alt="feature module component">
@ -108,9 +81,10 @@ Now, in addition to the title that renders by default, the `CustomerDashboardCom
<hr /> <hr />
## More on NgModules ## Más sobre NgModules
You may also be interested in the following: También te puede interesar lo siguiente:
* [Lazy Loading Modules with the Angular Router](guide/lazy-loading-ngmodules).
* [Providers](guide/providers). - [Módulos de carga diferida con el enrutador angular](guide/lazy-loading-ngmodules).
* [Types of Feature Modules](guide/module-types). - [Proveedores](guide/providers).
- [Tipos de módulos de funciones](guide/module-types).

View File

@ -91,7 +91,7 @@ Angular components, templates, and styles go here.
| `src/app/` FILES | PURPOSE | | `src/app/` FILES | PURPOSE |
| :-------------------------- | :------------------------------------------| | :-------------------------- | :------------------------------------------|
| `app/app.component.ts` | Defines the logic for the app's root component, named `AppComponent`. The view associated with this root component becomes the root of the [view hierarchy](guide/glossary#view-hierarchy) as you add components and services to your application. | | `app/app.component.ts` | Defines the logic for the app's root component, named `AppComponent`. The view associated with this root component becomes the root of the [view hierarchy](guide/glossary#view-tree) as you add components and services to your application. |
| `app/app.component.html` | Defines the HTML template associated with the root `AppComponent`. | | `app/app.component.html` | Defines the HTML template associated with the root `AppComponent`. |
| `app/app.component.css` | Defines the base CSS stylesheet for the root `AppComponent`. | | `app/app.component.css` | Defines the base CSS stylesheet for the root `AppComponent`. |
| `app/app.component.spec.ts` | Defines a unit test for the root `AppComponent`. | | `app/app.component.spec.ts` | Defines a unit test for the root `AppComponent`. |

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -39,7 +39,7 @@ To prepare your app for translations, you should have a basic understanding of t
* [Templates](guide/glossary#template "Definition of a template") * [Templates](guide/glossary#template "Definition of a template")
* [Components](guide/glossary#component "Definition of a component") * [Components](guide/glossary#component "Definition of a component")
* [Angular CLI](guide/glossary#command-line-interface-cli "Definition of CLI") command-line tool for managing the Angular development cycle * [Angular CLI](guide/glossary#cli "Definition of CLI") command-line tool for managing the Angular development cycle
* [Extensible Markup Language (XML)](https://www.w3.org/XML/ "W3C: Extensible Markup Language (XML)") used for translation files * [Extensible Markup Language (XML)](https://www.w3.org/XML/ "W3C: Extensible Markup Language (XML)") used for translation files
## Steps to localize your app ## Steps to localize your app
@ -534,13 +534,13 @@ The following example shows both translation units after translating:
## Merge translations into the app ## Merge translations into the app
To merge the completed translations into the app, use the [Angular CLI](guide/glossary#command-line-interface-cli "Definition of CLI") to build a copy of the app's distributable files for each locale. To merge the completed translations into the app, use the [Angular CLI](guide/glossary#cli "Definition of CLI") to build a copy of the app's distributable files for each locale.
The build process replaces the original text with translated text, and sets the `LOCALE_ID` token for each distributable copy of the app. The build process replaces the original text with translated text, and sets the `LOCALE_ID` token for each distributable copy of the app.
It also loads and registers the locale data. It also loads and registers the locale data.
After merging, you can serve each distributable copy of the app using server-side language detection or different subdirectories, as described in the next section about [deploying multiple locales](#deploy-locales). After merging, you can serve each distributable copy of the app using server-side language detection or different subdirectories, as described in the next section about [deploying multiple locales](#deploy-locales).
The build process uses [ahead-of-time (AOT) compilation](guide/glossary#ahead-of-time-aot-compilation) to produce a small, fast, The build process uses [ahead-of-time (AOT) compilation](guide/glossary#aot) to produce a small, fast,
ready-to-run app. With Ivy in Angular version 9, AOT is used by default for both ready-to-run app. With Ivy in Angular version 9, AOT is used by default for both
development and production builds, and AOT is required to localize component templates. development and production builds, and AOT is required to localize component templates.
@ -610,7 +610,7 @@ To use your locale definition in the build configuration, use the `"localize"` o
<div class="alert is-helpful"> <div class="alert is-helpful">
Note: [Ahead-of-time (AOT) compilation](guide/glossary#ahead-of-time-aot-compilation) is required to localize component templates. Note: [Ahead-of-time (AOT) compilation](guide/glossary#aot) is required to localize component templates.
If you changed this setting, set `"aot"` to `true` in order to use AOT. If you changed this setting, set `"aot"` to `true` in order to use AOT.
</div> </div>

View File

@ -208,7 +208,7 @@ about the event and gives that data to the parent.
The child's template has two controls. The first is an HTML `<input>` with a The child's template has two controls. The first is an HTML `<input>` with a
[template reference variable](guide/template-reference-variables) , `#newItem`, [template reference variable](guide/template-reference-variables) , `#newItem`,
where the user types in an item name. Whatever the user types where the user types in an item name. Whatever the user types
into the `<input>` gets stored in the `value` property of the `#newItem` variable. into the `<input>` gets stored in the `#newItem` variable.
<code-example path="inputs-outputs/src/app/item-output/item-output.component.html" region="child-output" header="src/app/item-output/item-output.component.html"></code-example> <code-example path="inputs-outputs/src/app/item-output/item-output.component.html" region="child-output" header="src/app/item-output/item-output.component.html"></code-example>
@ -218,7 +218,7 @@ an event binding because the part to the left of the equal
sign is in parentheses, `(click)`. sign is in parentheses, `(click)`.
The `(click)` event is bound to the `addNewItem()` method in the child component class which The `(click)` event is bound to the `addNewItem()` method in the child component class which
takes as its argument whatever the value of `#newItem.value` property is. takes as its argument whatever the value of `#newItem` is.
Now the child component has an `@Output()` Now the child component has an `@Output()`
for sending data to the parent and a method for raising an event. for sending data to the parent and a method for raising an event.

View File

@ -0,0 +1,37 @@
# Overview of Angular libraries
Many applications need to solve the same general problems, such as presenting a unified user interface, presenting data, and allowing data entry.
Developers can create general solutions for particular domains that can be adapted for re-use in different apps.
Such a solution can be built as Angular *libraries* and these libraries can be published and shared as *npm packages*.
An Angular library is an Angular [project](guide/glossary#project) that differs from an app in that it cannot run on its own.
A library must be imported and used in an app.
Libraries extend Angular's base functionality. For example, to add [reactive forms](guide/reactive-forms) to an app, add the library package using `ng add @angular/forms`, then import the `ReactiveFormsModule` from the `@angular/forms` library in your application code.
Similarly, adding the [service worker](guide/service-worker-intro) library to an Angular application is one of the steps for turning an application into a [Progressive Web App](https://developers.google.com/web/progressive-web-apps/) (PWA).
[Angular Material](https://material.angular.io/) is an example of a large, general-purpose library that provides sophisticated, reusable, and adaptable UI components.
Any app developer can use these and other libraries that have been published as npm packages by the Angular team or by third parties. See [Using Published Libraries](guide/using-libraries).
## Creating libraries
If you have developed functionality that is suitable for reuse, you can create your own libraries.
These libraries can be used locally in your workspace, or you can publish them as [npm packages](guide/npm-packages) to share with other projects or other Angular developers.
These packages can be published to the npm registry, a private npm Enterprise registry, or a private package management system that supports npm packages.
See [Creating Libraries](guide/creating-libraries).
Whether you decide to package functionality as a library is an architectural decision, similar to deciding whether a piece of functionality is a component or a service, or deciding on the scope of a component.
Packaging functionality as a library forces the artifacts in the library to be decoupled from the application's business logic.
This can help to avoid various bad practices or architecture mistakes that can make it difficult to decouple and reuse code in the future.
Putting code into a separate library is more complex than simply putting everything in one app.
It requires more of an investment in time and thought for managing, maintaining, and updating the library.
This complexity can pay off, however, when the library is being used in multiple apps.
<div class="alert is-helpful">
Note that libraries are intended to be used by Angular apps.
To add Angular functionality to non-Angular web apps, you can use [Angular custom elements](guide/elements).
</div>

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