Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Reusable Components & Directives: Deep Dive
Search
Manfred Steyer
PRO
October 27, 2022
Programming
430
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Reusable Components & Directives: Deep Dive
Manfred Steyer
PRO
October 27, 2022
More Decks by Manfred Steyer
See All by Manfred Steyer
Generative UI & AI-Assistants for Your Angular Solutions
manfredsteyer
PRO
1
430
Generative UI & AI-Assistants for Your Angular Solutions
manfredsteyer
PRO
0
180
Nostalgia Meets Technology: Super Mario with TypeScript
manfredsteyer
PRO
0
260
Signal Forms: Details & Live Coding @enterJS 2026 in Mannheim
manfredsteyer
PRO
0
280
Strategic Design in the Frontend: Moduliths & Micro Frontends @DDDEurope
manfredsteyer
PRO
0
190
Agentic UI
manfredsteyer
PRO
0
290
Signal Forms: Beyond the Basics @ngBaguette 2026 in Paris
manfredsteyer
PRO
0
330
Agentic UI beyond Chats Architecture Patterns & Open Standards @ngMunich 05/2026
manfredsteyer
PRO
0
280
Agentic AI in the Frontend: Architectures with Open Standards @iJS London 2026
manfredsteyer
PRO
0
200
Other Decks in Programming
See All in Programming
170k Jobs a Day on GKE: Scaling Mercari's CI Platform - and What's Next for AI-Native Development
junyaokabe
0
120
AI Engineeringは、AIプロダクトだけのものか? 〜AIがソフトウェアを作る時代の新しい当たり前〜 / No AI in your product. AI Engineering in your development.
rkaga
5
530
Jindong: Introducing Declarative Haptics in Compose Multiplatform
l2hyunwoo
0
130
DynamoDBの基礎を振り返りながらベクトル検索機能を理解する
musan
2
200
ソフトウェアエンジニアにとっての生成AI - 特性を知って使い倒す / generative ai for software enginner
kishida
7
2.1k
Hono + Inertia + React で LP を構築した話
oukayuka
2
160
複数の Claude Code が"放置"されてしまう問題をCLI ダッシュボードを自作して解決した話
sumihiro3
1
730
コンパウンドプロダクト開発のためのローカルプロセスマネージャー再発明 #layerxgo
izumin5210
0
340
源内ハンズオン概要編
hideg
0
210
片田舎のおっさん、 Swift Buildのダイアモンド問題解決の不具合修正PRを出すが、解決方法がキャッシュをしないようにすることであり、ビルド時間が伸びると言われてマージされないので高速化もする/swiftbuild
yimajo
0
280
How I Won Prize Money at a Hackathon Using Codex and Symphony Alpha
yasei_no_otoko
0
120
Go 1.27 における memory allocation の高速化
andpad
0
320
Featured
See All Featured
First, design no harm
axbom
PRO
2
1.3k
Heart Work Chapter 1 - Part 1
lfama
PRO
8
36k
WCS-LA-2024
lcolladotor
0
810
VelocityConf: Rendering Performance Case Studies
addyosmani
331
25k
Skip the Path - Find Your Career Trail
mkilby
1
190
Docker and Python
trallard
47
4.1k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
68
57k
RailsConf 2023
tenderlove
30
1.5k
Raft: Consensus for Rubyists
vanstee
141
7.6k
Code Reviewing Like a Champion
maltzj
528
40k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.6k
Transcript
@ManfredSteyer
@ManfredSteyer Contents • Interacting with Content • Interacting with View
• Working with Handles • Providers vs. ViewProviders
@ManfredSteyer Contents • Attribute Directives • Templates and View Containers
• Structural Directives
@ManfredSteyer Why is this Intersting? • Reusable Components (Component Libraries)
• Better Understanding for Angular
@ManfredSteyer Manfred Steyer
@ManfredSteyer
@ManfredSteyer Case Study #1: Tabbed Pane
@ManfredSteyer Tabbed Pane <app-tabbed-pane> <app-tab title="Upcoming Flights"> <p>No upcoming flights!</p>
</app-tab> <app-tab title="Operated Flights"> <p>No operated flights!</p> </app-tab> <app-tab title="Cancelled Flights"> <p>No cancelled flights!</p> </app-tab> </app-tabbed-pane>
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer View vs. Content @Component({ selector: 'tab', template: ` <div
*ngIf="visible"> <h1>{{title}}</h1> <div> <ng-content></ng-content> </div> </div> ` }) export class TabComponent { @Input() title: string; visible: boolean = true; } Content <tab title="Booked"> Sample Text ... </tab> View
@ManfredSteyer Hooks 1) ngOnChanges 2) ngOnInit 3) ngDoCheck 4) ngAfterContentInit
5) ngAfterContentChecked 6) ngAfterViewInit 7) ngAfterViewChecked 8) ngOnDestroy
@ManfredSteyer Hooks 1) ngOnChanges 2) ngOnInit 3) ngDoCheck 4) ngAfterContentInit
5) ngAfterContentChecked 6) ngAfterViewInit 7) ngAfterViewChecked 8) ngOnDestroy
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer Handles <app-tabbed-pane #pane> […] </app-tabbed-pane> Current Page: {{ pane.currentPage
}}
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer Providers @Component({ providers: [NavigatorService] }) export class TabbedPaneComponent {
[…] }
@ManfredSteyer Providers @Component({ providers: [NavigatorService] // Visible in View and
Content }) export class TabbedPaneComponent { […] }
@ManfredSteyer View Providers @Component({ viewProviders: [NavigatorService] // Visible only in
View }) export class TabbedPaneComponent { […] }
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer Directives • „Components without Templates“ • Add behavior to
an element • Examples: ngModel, ngClass, ngStyle
@ManfredSteyer Case Study <button appClickWithWarning>Delete</button>
@ManfredSteyer Simple Example @Directive({ selector: '[appClickWithWarning]' }) export class ClickWithWarningDirective
implements OnInit { constructor(private elementRef: ElementRef) { } ngOnInit(): void { this.elementRef .nativeElement.setAttribute('class', 'btn btn-danger'); } }
@ManfredSteyer Calling a Directive <button appClickWithWarning>Delete</button> Host-Element
@ManfredSteyer Bindings @Directive({ selector: '[appClickWithWarning]' }) export class ClickWithWarningDirective implements
OnInit { @Input() warning = 'Are you sure?'; @Output() appClickWithWarning = new EventEmitter(); }
@ManfredSteyer Bindings @Directive({ selector: '[appClickWithWarning]' }) export class ClickWithWarningDirective implements
OnInit { @Input() warning = 'Are you sure?'; @Output() appClickWithWarning = new EventEmitter(); @HostBinding('class') classBinding = 'btn btn-danger'; }
@ManfredSteyer Bindings @Directive({ selector: '[appClickWithWarning]' }) export class ClickWithWarningDirective implements
OnInit { @Input() warning = 'Are you sure?'; @Output() appClickWithWarning = new EventEmitter(); @HostBinding('class') classBinding = 'btn btn-danger'; @HostListener('click', ['$event']) handleClick($event: MouseEvent): void { … } }
@ManfredSteyer Calling the Directive <button (appClickWithWarning)="delete()" message="Sure?">Delete</button>
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer Example: Tooltip <input [appTooltip]="tmpl"> <ng-template #tmpl> <h3>2 Tips for
Success</h3> <ol> <li>Don't tell everything!</li> </ol> </ng-template> ViewContainer
@ManfredSteyer Implementation @Directive({ selector: '[appTooltip]' }) export class TooltipDirective implements
OnInit { @Input('appTooltip') template: TemplateRef<unknown>; constructor(private host: ElementRef, private viewContainer: ViewContainerRef) { } ngOnInit(): void { this.viewContainer.createEmbeddedView(this.template); } }
@ManfredSteyer Implementation export class TooltipDirective implements OnInit { private viewRef:
EmbeddedViewRef<unknown>; @Input('appTooltip') template: TemplateRef<unknown>; constructor( private host: ElementRef, private viewContainer: ViewContainerRef) { } ngOnInit(): void { this.viewRef = this.viewContainer.createEmbeddedView(this.template); […] } }
@ManfredSteyer Mouse-Events const elm = this.host.nativeElement as HTMLElement; elm.addEventListener('mouseover', ()
=> { […] }); elm.addEventListener('mouseout', () => { […] });
@ManfredSteyer Iterate over Projected Root Nodes this.viewRef.rootNodes.forEach(nativeElement => { nativeElement.hidden
= true; }); <input [appTooltip]="tmpl"> <ng-template #tmpl> <h3>2 Tips for Success</h3> <ol> <li>Don't tell everything!</li> </ol> </ng-template> Root Nodes
@ManfredSteyer
@ManfredSteyer Passing Parameters to Templates this.viewContainer.createEmbeddedView(this.template, { $implicit: 'Tooltip!', helpLink:
'http://www.google.com' }); Context
@ManfredSteyer Using Parameters in Template <ng-template #tmpl let-title let-link="helpLink"> <h3>{{title}}</h3>
<p> Deletes EVERYTHING! </p> <a [href]="link">More</a> </ng-template>
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer ViewContainer • createEmbeddedView • createComponent
@ManfredSteyer
@ManfredSteyer TemplateOutletDirective Insert Template in Placeholder <div *templateOutlet="tmpl"></div> <ng-template #tmpl>Hallo
Welt!</ng-template>
@ManfredSteyer ComponentOutletDirective Insert Component in Placeholder <div *componentOutlet="FlightSearchComponent"></div>
@ManfredSteyer
@ManfredSteyer ContentChildren • @ContentChildren(MyComponentOrDirective, { read: ElementRef | ViewContainerRef })
• Same for @ContentChild, @ViewChildren, @ViewChild
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer Structural Directive <div *ngFor="let f of flights; index as
i"> <pre>{{i}}: {{ f | json }}</pre> </div> Template Micro Syntax
@ManfredSteyer ngFor Implementation Structural Directive <div *ngFor="let f of flights;
index as i"> <pre>{{i}}: {{ f | json }}</pre> </div> Template
@ManfredSteyer $implicit ngForOf index Structural Directive <div *ngFor="let f of
flights; index as i"> <pre>{{i}}: {{ f | json }}</pre> </div> Template context
@ManfredSteyer Syntax Sugar <div *ngFor="let f of flights; index as
i"> <pre>{{i}}: {{ f | json }}</pre> </div> <ng-template ngFor let-f [ngForOf]="flights" let-i="index"> <div> <pre>{{i}}: {{ f | json }}</pre> </div> </ng-template>
@ManfredSteyer Case Study #2: DataTable
@ManfredSteyer DataTable <app-data-table [data]="flights"> <div *appTableField="let data as 'id'">{{data}}</div> <div
*appTableField="let data as 'from'">{{data}}</div> <div *appTableField="let data as 'to'">{{data}}</div> <div *appTableField="let data as 'date'"> {{data | date:'dd.MM.yyyy HH:mm'}} </div> </app-data-table>
@ManfredSteyer
@ManfredSteyer
@ManfredSteyer Summary • Attribute Directive with Input, Output, HostBinding, HostListener
• ElementRef, TemplateRef, ViewContrainerRef • *ngComponentOutlet, *ngTemplateOutlet • Struktruelle Direktive: Template + Micro Syntax
@ManfredSteyer
@ManfredSteyer 2 1 3 4
@ManfredSteyer Case Study #3: Formatting/Parsing Dates <input [(ngModel)]="date" appDate name="date">
@ManfredSteyer
@ManfredSteyer Case Study #3a: DateControl <app-date [(ngModel)]="date"></app-date>
@ManfredSteyer