Skip to content

Commit

Permalink
refactor(common): create an NgFor alias for NgForOf directive (#4…
Browse files Browse the repository at this point in the history
…7309)

This commit adds a re-export of the `NgForOf` class as `NgFor` to improve the DX for cases when the directive is used as standalone. Developers can import `NgFor` class, which better matches the `ngFor` attribute used in a template.

PR Close #47309
  • Loading branch information
AndrewKushnir authored and dylhunn committed Sep 9, 2022
1 parent 7e0de5b commit 710d1da
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 6 deletions.
4 changes: 3 additions & 1 deletion goldens/public-api/common/index.md
Expand Up @@ -450,7 +450,7 @@ export class NgComponentOutlet implements OnChanges, OnDestroy {
}

// @public
export class NgForOf<T, U extends NgIterable<T> = NgIterable<T>> implements DoCheck {
class NgForOf<T, U extends NgIterable<T> = NgIterable<T>> implements DoCheck {
constructor(_viewContainer: ViewContainerRef, _template: TemplateRef<NgForOfContext<T, U>>, _differs: IterableDiffers);
ngDoCheck(): void;
set ngForOf(ngForOf: U & NgIterable<T> | undefined | null);
Expand All @@ -464,6 +464,8 @@ export class NgForOf<T, U extends NgIterable<T> = NgIterable<T>> implements DoCh
// (undocumented)
static ɵfac: i0.ɵɵFactoryDeclaration<NgForOf<any, any>, never>;
}
export { NgForOf as NgFor }
export { NgForOf }

// @public (undocumented)
export class NgForOfContext<T, U extends NgIterable<T> = NgIterable<T>> {
Expand Down
2 changes: 1 addition & 1 deletion packages/common/src/common.ts
Expand Up @@ -20,7 +20,7 @@ export {registerLocaleData} from './i18n/locale_data';
export {Plural, NumberFormatStyle, FormStyle, Time, TranslationWidth, FormatWidth, NumberSymbol, WeekDay, getNumberOfCurrencyDigits, getCurrencySymbol, getLocaleDayPeriods, getLocaleDayNames, getLocaleMonthNames, getLocaleId, getLocaleEraNames, getLocaleWeekEndRange, getLocaleFirstDayOfWeek, getLocaleDateFormat, getLocaleDateTimeFormat, getLocaleExtraDayPeriodRules, getLocaleExtraDayPeriods, getLocalePluralCase, getLocaleTimeFormat, getLocaleNumberSymbol, getLocaleNumberFormat, getLocaleCurrencyCode, getLocaleCurrencyName, getLocaleCurrencySymbol, getLocaleDirection} from './i18n/locale_data_api';
export {parseCookieValue as ɵparseCookieValue} from './cookie';
export {CommonModule} from './common_module';
export {NgClass, NgForOf, NgForOfContext, NgIf, NgIfContext, NgPlural, NgPluralCase, NgStyle, NgSwitch, NgSwitchCase, NgSwitchDefault, NgTemplateOutlet, NgComponentOutlet} from './directives/index';
export {NgClass, NgFor, NgForOf, NgForOfContext, NgIf, NgIfContext, NgPlural, NgPluralCase, NgStyle, NgSwitch, NgSwitchCase, NgSwitchDefault, NgTemplateOutlet, NgComponentOutlet} from './directives/index';
export {DOCUMENT} from './dom_tokens';
export {AsyncPipe, DatePipe, DATE_PIPE_DEFAULT_TIMEZONE, I18nPluralPipe, I18nSelectPipe, JsonPipe, LowerCasePipe, CurrencyPipe, DecimalPipe, PercentPipe, SlicePipe, UpperCasePipe, TitleCasePipe, KeyValuePipe, KeyValue} from './pipes/index';
export {PLATFORM_BROWSER_ID as ɵPLATFORM_BROWSER_ID, PLATFORM_SERVER_ID as ɵPLATFORM_SERVER_ID, PLATFORM_WORKER_APP_ID as ɵPLATFORM_WORKER_APP_ID, PLATFORM_WORKER_UI_ID as ɵPLATFORM_WORKER_UI_ID, isPlatformBrowser, isPlatformServer, isPlatformWorkerApp, isPlatformWorkerUi} from './platform_id';
Expand Down
4 changes: 3 additions & 1 deletion packages/common/src/directives/index.ts
Expand Up @@ -7,9 +7,10 @@
*/

import {Provider} from '@angular/core';

import {NgClass} from './ng_class';
import {NgComponentOutlet} from './ng_component_outlet';
import {NgForOf, NgForOfContext} from './ng_for_of';
import {NgFor, NgForOf, NgForOfContext} from './ng_for_of';
import {NgIf, NgIfContext} from './ng_if';
import {NgPlural, NgPluralCase} from './ng_plural';
import {NgStyle} from './ng_style';
Expand All @@ -19,6 +20,7 @@ import {NgTemplateOutlet} from './ng_template_outlet';
export {
NgClass,
NgComponentOutlet,
NgFor,
NgForOf,
NgForOfContext,
NgIf,
Expand Down
5 changes: 5 additions & 0 deletions packages/common/src/directives/ng_for_of.ts
Expand Up @@ -290,6 +290,11 @@ export class NgForOf<T, U extends NgIterable<T> = NgIterable<T>> implements DoCh
}
}

// Also export the `NgForOf` class as `NgFor` to improve the DX for
// cases when the directive is used as standalone, so the class name
// matches the CSS selector (*ngFor).
export {NgForOf as NgFor};

function applyViewChange<T>(
view: EmbeddedViewRef<NgForOfContext<T>>, record: IterableChangeRecord<T>) {
view.context.$implicit = record.item;
Expand Down
21 changes: 20 additions & 1 deletion packages/common/test/directives/ng_for_spec.ts
Expand Up @@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/

import {CommonModule, NgForOf} from '@angular/common';
import {CommonModule, NgFor, NgForOf} from '@angular/common';
import {Component} from '@angular/core';
import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
import {By} from '@angular/platform-browser/src/dom/debug/by';
Expand Down Expand Up @@ -408,6 +408,25 @@ let thisArg: any;

expect(fixture.nativeElement.textContent).toBe('1|2|3|');
});

it('should be available as a standalone directive using an `NgFor` alias', () => {
@Component({
selector: 'test-component',
imports: [NgFor],
template: `
<ng-container *ngFor="let item of items">{{ item }}|</ng-container>
`,
standalone: true,
})
class TestComponent {
items = [1, 2, 3];
}

const fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges();

expect(fixture.nativeElement.textContent).toBe('1|2|3|');
});
});
}

Expand Down
Expand Up @@ -24,7 +24,7 @@ import {TemplateCheckFactory, TemplateCheckWithVisitor, TemplateContext} from '.
* `CommonModule` is included, the `ngSwitch` would also be covered.
*/
export const KNOWN_CONTROL_FLOW_DIRECTIVES = new Map([
['ngIf', 'NgIf'], ['ngFor', 'NgForOf'], ['ngSwitchCase', 'NgSwitchCase'],
['ngIf', 'NgIf'], ['ngFor', 'NgFor'], ['ngSwitchCase', 'NgSwitchCase'],
['ngSwitchDefault', 'NgSwitchDefault']
]);

Expand Down
Expand Up @@ -282,7 +282,7 @@ function getTemplateLocationDetails(lView: LView): string {
* that the `CommonModule` should also be included.
*/
export const KNOWN_CONTROL_FLOW_DIRECTIVES = new Map([
['ngIf', 'NgIf'], ['ngFor', 'NgForOf'], ['ngSwitchCase', 'NgSwitchCase'],
['ngIf', 'NgIf'], ['ngFor', 'NgFor'], ['ngSwitchCase', 'NgSwitchCase'],
['ngSwitchDefault', 'NgSwitchDefault']
]);
/**
Expand Down

0 comments on commit 710d1da

Please sign in to comment.