diff --git a/apps/angular/4-typed-context-outlet/src/app/app.component.ts b/apps/angular/4-typed-context-outlet/src/app/app.component.ts index d608bec2c..a6f1e821b 100644 --- a/apps/angular/4-typed-context-outlet/src/app/app.component.ts +++ b/apps/angular/4-typed-context-outlet/src/app/app.component.ts @@ -1,19 +1,27 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { ListDirective } from './directives/list.directive'; +import { PersonDirective } from './directives/person.directive'; import { ListComponent } from './list.component'; +import { Person } from './model/person'; import { PersonComponent } from './person.component'; @Component({ - imports: [PersonComponent, ListComponent], + imports: [PersonComponent, ListComponent, PersonDirective, ListDirective], selector: 'app-root', template: ` - + {{ name }}: {{ age }} - + {{ student.name }}: {{ student.age }} - {{ i }} @@ -27,7 +35,7 @@ import { PersonComponent } from './person.component'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class AppComponent { - person = { + person: Person = { name: 'toto', age: 3, }; diff --git a/apps/angular/4-typed-context-outlet/src/app/directives/list.directive.spec.ts b/apps/angular/4-typed-context-outlet/src/app/directives/list.directive.spec.ts new file mode 100644 index 000000000..44b075f6e --- /dev/null +++ b/apps/angular/4-typed-context-outlet/src/app/directives/list.directive.spec.ts @@ -0,0 +1,8 @@ +import { ListDirective } from './list.directive'; + +describe('ListDirective', () => { + it('should create an instance', () => { + const directive = new ListDirective(); + expect(directive).toBeTruthy(); + }); +}); diff --git a/apps/angular/4-typed-context-outlet/src/app/directives/list.directive.ts b/apps/angular/4-typed-context-outlet/src/app/directives/list.directive.ts new file mode 100644 index 000000000..970cb0685 --- /dev/null +++ b/apps/angular/4-typed-context-outlet/src/app/directives/list.directive.ts @@ -0,0 +1,42 @@ +import { + Directive, + inject, + Input, + TemplateRef, + ViewContainerRef, +} from '@angular/core'; + +interface ListStudentTemplateContext { + $implicit: Ctx; + appList: Ctx; + index: number; +} + +@Directive({ + selector: 'ng-template[listTemplateDirective]', +}) +export class ListDirective { + private readonly tpl = + inject>>(TemplateRef); + + private readonly vcr = inject(ViewContainerRef); + + @Input() set listOf(list: Ctx[] | readonly Ctx[] | null | undefined) { + const arr = (list ?? []) as Ctx[]; + this.vcr.clear(); + arr.forEach((item, index) => { + this.vcr.createEmbeddedView(this.tpl, { + $implicit: item, + appList: item, + index, + }); + }); + } + + static ngTemplateContextGuard( + _dir: ListDirective, + ctx: unknown, + ): ctx is ListStudentTemplateContext { + return true; + } +} diff --git a/apps/angular/4-typed-context-outlet/src/app/directives/person.directive.spec.ts b/apps/angular/4-typed-context-outlet/src/app/directives/person.directive.spec.ts new file mode 100644 index 000000000..5c3828c30 --- /dev/null +++ b/apps/angular/4-typed-context-outlet/src/app/directives/person.directive.spec.ts @@ -0,0 +1,8 @@ +import { PersonDirective } from './person.directive'; + +describe('PersonDirective', () => { + it('should create an instance', () => { + const directive = new PersonDirective(); + expect(directive).toBeTruthy(); + }); +}); diff --git a/apps/angular/4-typed-context-outlet/src/app/directives/person.directive.ts b/apps/angular/4-typed-context-outlet/src/app/directives/person.directive.ts new file mode 100644 index 000000000..25ee8e683 --- /dev/null +++ b/apps/angular/4-typed-context-outlet/src/app/directives/person.directive.ts @@ -0,0 +1,20 @@ +import { Directive, inject, TemplateRef } from '@angular/core'; + +interface PersonTemplateContext { + $implicit: string; + age: number; +} + +@Directive({ + selector: 'ng-template[personTemplate]', +}) +export class PersonDirective { + private readonly tpl = inject>; + + static ngTemplateContextGuard( + _dir: PersonDirective, + ctx: unknown, + ): ctx is PersonTemplateContext { + return true; + } +} diff --git a/apps/angular/4-typed-context-outlet/src/app/model/person.ts b/apps/angular/4-typed-context-outlet/src/app/model/person.ts new file mode 100644 index 000000000..9026b9f23 --- /dev/null +++ b/apps/angular/4-typed-context-outlet/src/app/model/person.ts @@ -0,0 +1,4 @@ +export interface Person { + name: string; + age: number; +}