From 86b2b2504f336e9ae69dfbc46c6731468781b944 Mon Sep 17 00:00:00 2001 From: Chuck Jazdzewski Date: Wed, 25 Jan 2017 13:45:06 -0800 Subject: [PATCH] feat(common): rename underlying `NgFor` class and add a type parameter (#14104) Note, this affects the underlying class and should not affect usage. DEPRECATION: - the `NgFor` class is now deprecated. Use `NgForOf` instead. IMPORTANT: Only the `NgFor` class is deprecated, not the `ngFor` directive. The `*ngFor` and related directives are unaffected by this change as references to the `NgFor` class generated from templates will be automatically converted to references to `NgForOf` without requiring any template modifications. - `TrackByFn` is now deprecated. Use `TrackByFunction` instead. Migration: - Replace direct references to the `NgFor` class to `NgForOf`. - Replace references to `TrackByFn` to `TrackByFunction`. BREAKING CHANGE: A definition of `Iterable` is now required to correctly compile Angular applications. Support for `Iterable` is not required at runtime but a type definition `Iterable` must be available. `NgFor`, and now `NgForOf`, already supports `Iterable` at runtime. With this change the type definition is updated to reflect this support. Migration: - add "es2015.iterable.ts" to your tsconfig.json "libs" fields. Part of #12398 PR Close #14104 --- modules/@angular/common/src/common.ts | 2 +- modules/@angular/common/src/common_module.ts | 12 +- .../@angular/common/src/directives/index.ts | 11 +- .../directives/{ng_for.ts => ng_for_of.ts} | 287 +++++++++++------- modules/@angular/core/src/change_detection.ts | 2 +- .../src/change_detection/change_detection.ts | 2 +- .../differs/default_iterable_differ.ts | 17 +- .../differs/iterable_differs.ts | 24 +- .../language-service/src/expressions.ts | 9 +- .../@angular/language-service/src/types.ts | 5 + .../language-service/src/typescript_host.ts | 2 + tools/public_api_guard/common/index.d.ts | 14 +- tools/public_api_guard/core/index.d.ts | 22 +- 13 files changed, 263 insertions(+), 146 deletions(-) rename modules/@angular/common/src/directives/{ng_for.ts => ng_for_of.ts} (54%) diff --git a/modules/@angular/common/src/common.ts b/modules/@angular/common/src/common.ts index 19e1680a2d..822e288f5e 100644 --- a/modules/@angular/common/src/common.ts +++ b/modules/@angular/common/src/common.ts @@ -14,6 +14,6 @@ export * from './location/index'; export {NgLocaleLocalization, NgLocalization} from './localization'; export {CommonModule} from './common_module'; -export {NgClass, NgFor, NgIf, NgPlural, NgPluralCase, NgStyle, NgSwitch, NgSwitchCase, NgSwitchDefault, NgTemplateOutlet, NgComponentOutlet} from './directives/index'; +export {NgClass, NgFor, NgForOf, NgIf, NgPlural, NgPluralCase, NgStyle, NgSwitch, NgSwitchCase, NgSwitchDefault, NgTemplateOutlet, NgComponentOutlet} from './directives/index'; export {AsyncPipe, DatePipe, I18nPluralPipe, I18nSelectPipe, JsonPipe, LowerCasePipe, CurrencyPipe, DecimalPipe, PercentPipe, SlicePipe, UpperCasePipe, TitleCasePipe} from './pipes/index'; export {VERSION} from './version'; diff --git a/modules/@angular/common/src/common_module.ts b/modules/@angular/common/src/common_module.ts index 849d0a547f..7c4bc29d10 100644 --- a/modules/@angular/common/src/common_module.ts +++ b/modules/@angular/common/src/common_module.ts @@ -8,14 +8,15 @@ import {NgModule} from '@angular/core'; -import {COMMON_DIRECTIVES} from './directives/index'; +import {COMMON_DEPRECATED_DIRECTIVES, COMMON_DIRECTIVES} from './directives/index'; import {NgLocaleLocalization, NgLocalization} from './localization'; import {COMMON_PIPES} from './pipes/index'; + // Note: This does not contain the location providers, // as they need some platform specific implementations to work. /** - * The module that includes all the basic Angular directives like {@link NgIf}, {@link NgFor}, ... + * The module that includes all the basic Angular directives like {@link NgIf}, {@link NgForOf}, ... * * @stable */ @@ -28,3 +29,10 @@ import {COMMON_PIPES} from './pipes/index'; }) export class CommonModule { } + +/** + * A module to contain deprecated directives. + */ +@NgModule({declarations: [COMMON_DEPRECATED_DIRECTIVES], exports: [COMMON_DEPRECATED_DIRECTIVES]}) +export class CommonDeprecatedModule { +} \ No newline at end of file diff --git a/modules/@angular/common/src/directives/index.ts b/modules/@angular/common/src/directives/index.ts index 38ba2878d8..74497ba25a 100644 --- a/modules/@angular/common/src/directives/index.ts +++ b/modules/@angular/common/src/directives/index.ts @@ -10,7 +10,7 @@ import {Provider} from '@angular/core'; import {NgClass} from './ng_class'; import {NgComponentOutlet} from './ng_component_outlet'; -import {NgFor} from './ng_for'; +import {NgFor, NgForOf} from './ng_for_of'; import {NgIf} from './ng_if'; import {NgPlural, NgPluralCase} from './ng_plural'; import {NgStyle} from './ng_style'; @@ -21,6 +21,7 @@ export { NgClass, NgComponentOutlet, NgFor, + NgForOf, NgIf, NgPlural, NgPluralCase, @@ -32,6 +33,7 @@ export { }; + /** * A collection of Angular directives that are likely to be used in each and every Angular * application. @@ -39,7 +41,7 @@ export { export const COMMON_DIRECTIVES: Provider[] = [ NgClass, NgComponentOutlet, - NgFor, + NgForOf, NgIf, NgTemplateOutlet, NgStyle, @@ -49,3 +51,8 @@ export const COMMON_DIRECTIVES: Provider[] = [ NgPlural, NgPluralCase, ]; + +/** + * A colletion of deprecated directives that are no longer part of the core module. + */ +export const COMMON_DEPRECATED_DIRECTIVES: Provider[] = [NgFor]; \ No newline at end of file diff --git a/modules/@angular/common/src/directives/ng_for.ts b/modules/@angular/common/src/directives/ng_for_of.ts similarity index 54% rename from modules/@angular/common/src/directives/ng_for.ts rename to modules/@angular/common/src/directives/ng_for_of.ts index 8624f0a92c..e8f0103422 100644 --- a/modules/@angular/common/src/directives/ng_for.ts +++ b/modules/@angular/common/src/directives/ng_for_of.ts @@ -6,12 +6,12 @@ * found in the LICENSE file at https://angular.io/license */ -import {ChangeDetectorRef, Directive, DoCheck, EmbeddedViewRef, Input, IterableChangeRecord, IterableChanges, IterableDiffer, IterableDiffers, OnChanges, SimpleChanges, TemplateRef, TrackByFn, ViewContainerRef, isDevMode} from '@angular/core'; +import {ChangeDetectorRef, Directive, DoCheck, EmbeddedViewRef, Input, IterableChangeRecord, IterableChanges, IterableDiffer, IterableDiffers, NgIterable, OnChanges, SimpleChanges, TemplateRef, TrackByFunction, ViewContainerRef, forwardRef, isDevMode} from '@angular/core'; import {getTypeNameForDebugging} from '../facade/lang'; -export class NgForRow { - constructor(public $implicit: any, public index: number, public count: number) {} +export class NgForOfRow { + constructor(public $implicit: T, public index: number, public count: number) {} get first(): boolean { return this.index === 0; } @@ -23,9 +23,177 @@ export class NgForRow { } /** - * The `NgFor` directive instantiates a template once per item from an iterable. The context for - * each instantiated template inherits from the outer context with the given loop variable set - * to the current item from the iterable. + * The `NgForOf` directive instantiates a template once per item from an iterable. The context + * for each instantiated template inherits from the outer context with the given loop variable + * set to the current item from the iterable. + * + * ### Local Variables + * + * `NgForOf` provides several exported values that can be aliased to local variables: + * + * * `index` will be set to the current loop iteration for each template context. + * * `first` will be set to a boolean value indicating whether the item is the first one in the + * iteration. + * * `last` will be set to a boolean value indicating whether the item is the last one in the + * iteration. + * * `even` will be set to a boolean value indicating whether this item has an even index. + * * `odd` will be set to a boolean value indicating whether this item has an odd index. + * + * ### Change Propagation + * + * When the contents of the iterator changes, `NgForOf` makes the corresponding changes to the DOM: + * + * * When an item is added, a new instance of the template is added to the DOM. + * * When an item is removed, its template instance is removed from the DOM. + * * When items are reordered, their respective templates are reordered in the DOM. + * * Otherwise, the DOM element for that item will remain the same. + * + * Angular uses object identity to track insertions and deletions within the iterator and reproduce + * those changes in the DOM. This has important implications for animations and any stateful + * controls (such as `` elements which accept user input) that are present. Inserted rows can + * be animated in, deleted rows can be animated out, and unchanged rows retain any unsaved state + * such as user input. + * + * It is possible for the identities of elements in the iterator to change while the data does not. + * This can happen, for example, if the iterator produced from an RPC to the server, and that + * RPC is re-run. Even if the data hasn't changed, the second response will produce objects with + * different identities, and Angular will tear down the entire DOM and rebuild it (as if all old + * elements were deleted and all new elements inserted). This is an expensive operation and should + * be avoided if possible. + * + * To customize the default tracking algorithm, `NgForOf` supports `trackBy` option. + * `trackBy` takes a function which has two arguments: `index` and `item`. + * If `trackBy` is given, Angular tracks changes by the return value of the function. + * + * ### Syntax + * + * - `
  • ...
  • ` + * - `
  • ...
  • ` + * + * With `