feat(NgTemplateOutlet): Make NgTemplateOutlet compatible with * syntax

BREAKING CHANGE:

- Deprecate `ngOutletContext`. Use `ngTemplateOutletContext` instead
This commit is contained in:
Misko Hevery
2016-12-11 21:42:20 -08:00
committed by Matias Niemelä
parent 31322e73b7
commit c0178de0e2
5 changed files with 111 additions and 22 deletions

View File

@ -15,42 +15,47 @@ import {Directive, EmbeddedViewRef, Input, OnChanges, SimpleChanges, TemplateRef
*
* @howToUse
* ```
* <template [ngTemplateOutlet]="templateRefExpression"
* [ngOutletContext]="objectExpression">
* </template>
* <ng-container *ngTemplateOutlet="templateRefExp; context: contextExp"></ng-container>
* ```
*
* @description
*
* You can attach a context object to the `EmbeddedViewRef` by setting `[ngOutletContext]`.
* `[ngOutletContext]` should be an object, the object's keys will be the local template variables
* available within the `TemplateRef`.
* You can attach a context object to the `EmbeddedViewRef` by setting `[ngTemplateOutletContext]`.
* `[ngTemplateOutletContext]` should be an object, the object's keys will be available for binding
* by the local template `let` declarations.
*
* Note: using the key `$implicit` in the context object will set it's value as default.
*
* # Example
*
* {@example common/ngTemplateOutlet/ts/module.ts region='NgTemplateOutlet'}
*
* @experimental
*/
@Directive({selector: '[ngTemplateOutlet]'})
export class NgTemplateOutlet implements OnChanges {
private _viewRef: EmbeddedViewRef<any>;
private _context: Object;
private _templateRef: TemplateRef<any>;
@Input() public ngTemplateOutletContext: Object;
@Input() public ngTemplateOutlet: TemplateRef<any>;
constructor(private _viewContainerRef: ViewContainerRef) {}
/**
* @deprecated v4.0.0 - Renamed to ngTemplateOutletContext.
*/
@Input()
set ngOutletContext(context: Object) { this._context = context; }
@Input()
set ngTemplateOutlet(templateRef: TemplateRef<Object>) { this._templateRef = templateRef; }
set ngOutletContext(context: Object) { this.ngTemplateOutletContext = context; }
ngOnChanges(changes: SimpleChanges) {
if (this._viewRef) {
this._viewContainerRef.remove(this._viewContainerRef.indexOf(this._viewRef));
}
if (this._templateRef) {
this._viewRef = this._viewContainerRef.createEmbeddedView(this._templateRef, this._context);
if (this.ngTemplateOutlet) {
this._viewRef = this._viewContainerRef.createEmbeddedView(
this.ngTemplateOutlet, this.ngTemplateOutletContext);
}
}
}

View File

@ -84,8 +84,8 @@ export function main() {
}));
it('should display template if context is null', async(() => {
const template =
`<tpl-refs #refs="tplRefs"><template>foo</template></tpl-refs><template [ngTemplateOutlet]="currentTplRef" [ngOutletContext]="null"></template>`;
const template = `<tpl-refs #refs="tplRefs"><template>foo</template></tpl-refs>` +
`<ng-content *ngTemplateOutlet="currentTplRef; context: null"></ng-content>`;
fixture = createTestComponent(template);
detectChangesAndExpectText('');
@ -97,7 +97,8 @@ export function main() {
it('should reflect initial context and changes', async(() => {
const template =
`<tpl-refs #refs="tplRefs"><template let-foo="foo"><span>{{foo}}</span></template></tpl-refs><template [ngTemplateOutlet]="currentTplRef" [ngOutletContext]="context"></template>`;
`<tpl-refs #refs="tplRefs"><template let-foo="foo"><span>{{foo}}</span></template></tpl-refs>` +
`<ng-content *ngTemplateOutlet="currentTplRef; context: context"></ng-content>`;
fixture = createTestComponent(template);
fixture.detectChanges();
@ -114,7 +115,8 @@ export function main() {
it('should reflect user defined $implicit property in the context', async(() => {
const template =
`<tpl-refs #refs="tplRefs"><template let-ctx><span>{{ctx.foo}}</span></template></tpl-refs><template [ngTemplateOutlet]="currentTplRef" [ngOutletContext]="context"></template>`;
`<tpl-refs #refs="tplRefs"><template let-ctx><span>{{ctx.foo}}</span></template></tpl-refs>` +
`<ng-content *ngTemplateOutlet="currentTplRef; context: context"></ng-content>`;
fixture = createTestComponent(template);
fixture.detectChanges();
@ -128,7 +130,8 @@ export function main() {
it('should reflect context re-binding', async(() => {
const template =
`<tpl-refs #refs="tplRefs"><template let-shawshank="shawshank"><span>{{shawshank}}</span></template></tpl-refs><template [ngTemplateOutlet]="currentTplRef" [ngOutletContext]="context"></template>`;
`<tpl-refs #refs="tplRefs"><template let-shawshank="shawshank"><span>{{shawshank}}</span></template></tpl-refs>` +
`<ng-content *ngTemplateOutlet="currentTplRef; context: context"></ng-content>`;
fixture = createTestComponent(template);
fixture.detectChanges();
@ -162,4 +165,4 @@ function createTestComponent(template: string): ComponentFixture<TestComponent>
return TestBed.overrideComponent(TestComponent, {set: {template: template}})
.configureTestingModule({schemas: [NO_ERRORS_SCHEMA]})
.createComponent(TestComponent);
}
}