Cracking the Angular Renderer
Chau Tran
twitter.com/@nartc1410
github.com/nartc
What is Angular Renderer?
@Component({
/* ... */
})
export class SomeComponent {
constructor(private readonly renderer: Renderer2) {}
}
@Component({
/* ... */
})
export class SomeComponent {
@ViewChild('someElement', { static: true }) someElement!: ElementRef<HTMLElement>;
constructor(private readonly renderer: Renderer2) {}
ngOnInit() {
this.renderer.setAttribute(this.someElement.nativeElement, 'attrName', 'attrValue');
}
}
@Component({
/* ... */
})
export class SomeComponent {
@ViewChild('someElement', { static: true }) someElement!: ElementRef<HTMLElement>;
/* no longer needed
constructor(private readonly renderer: Renderer2) {}
*/
ngOnInit() {
this.someElement.nativeElement.setAttribute('attrName', 'attrValue')
/*
this.renderer.setAttribute(this.someElement.nativeElement, 'attrName', 'attrValue');
*/
}
}
So ... why?
The example only shows how you would interact with the current Renderer
Have you wondered what provides the current Renderer?
import { bootstrapApplication } from '@angular/platform-browser';
import { platformNativeScript, runNativeScriptAngularApp } from '@nativescript/angular';
https://docs.nativescript.org/tutorial/angular.html
import { platformTerminalDynamic } from 'platform-terminal';
https://github.com/Tibing/platform-terminal
Yeah, Angular is platform agnostic
Platform Browser
Platform Browser
@Component({
template: `
<div>This is inside the div</div>
<app-parent />
`,
imports: [ParentComponent],
})
export class AppComponent {
title = 'ng-renderer';
}
Platform Browser
Component
Template
Platform Browser
Component
Template
Compiler
Platform Browser
Component
Template
Compiler
Template
Instructions
Platform Browser
Component
Template
Compiler
Template
Instructions
Renderer
Platform Browser
Component
Template
Compiler
Template
Instructions
Renderer
Platform
Platform Browser
the bridge between your template and the platform
Component
Template
Compiler
Template
Instructions
Renderer
Platform
Platform Browser
the bridge between Angular Core and the platform
Angular
Core
Renderer
Platform
Platform Browser
class AppComponent {
constructor() {
this.title = 'ng-renderer';
}
}
AppComponent.ɵfac = function AppComponent_Factory(t) {
return new (t || AppComponent)();
};
AppComponent.ɵcmp = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineComponent"]({
type: AppComponent,
selectors: [["app-root"]],
standalone: true,
features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵStandaloneFeature"]],
decls: 3,
vars: 0,
template: function AppComponent_Template(rf, ctx) {
if (rf & 1) {
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](0, "div");
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵtext"](1, "This is inside the div");
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]();
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelement"](2, "app-parent");
}
},
dependencies: [_parent_component__WEBPACK_IMPORTED_MODULE_0__.Parent],
encapsulation: 2
});`
Platform Browser
class AppComponent {
constructor() {
this.title = 'ng-renderer';
}
}
AppComponent.ɵfac = function AppComponent_Factory(t) {
return new (t || AppComponent)();
};
AppComponent.ɵcmp = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineComponent"]({
type: AppComponent,
selectors: [["app-root"]],
standalone: true,
features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵStandaloneFeature"]],
decls: 3,
vars: 0,
template: function AppComponent_Template(rf, ctx) {
if (rf & 1) {
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](0, "div");
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵtext"](1, "This is inside the div");
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]();
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelement"](2, "app-parent");
}
},
dependencies: [_parent_component__WEBPACK_IMPORTED_MODULE_0__.Parent],
encapsulation: 2
});`
@Component({
template: `
<div>This is inside the div</div>
<app-parent />
`,
imports: [ParentComponent],
})
export class AppComponent {
title = 'ng-renderer';
}
Platform Browser
class AppComponent {
constructor() {
this.title = 'ng-renderer';
}
}
AppComponent.ɵfac = function AppComponent_Factory(t) {
return new (t || AppComponent)();
};
AppComponent.ɵcmp = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineComponent"]({
type: AppComponent,
selectors: [["app-root"]],
standalone: true,
features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵStandaloneFeature"]],
decls: 3,
vars: 0,
template: function AppComponent_Template(rf, ctx) {
if (rf & 1) {
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](0, "div");
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵtext"](1, "This is inside the div");
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]();
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelement"](2, "app-parent");
}
},
dependencies: [_parent_component__WEBPACK_IMPORTED_MODULE_0__.Parent],
encapsulation: 2
});`
Platform Browser
class AppComponent {
constructor() {
this.title = 'ng-renderer';
}
}
AppComponent.ɵfac = function AppComponent_Factory(t) {
return new (t || AppComponent)();
};
AppComponent.ɵcmp = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineComponent"]({
type: AppComponent,
selectors: [["app-root"]],
standalone: true,
features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵStandaloneFeature"]],
decls: 3,
vars: 0,
template: function AppComponent_Template(rf, ctx) {
if (rf & 1) {
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](0, "div");
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵtext"](1, "This is inside the div");
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]();
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelement"](2, "app-parent");
}
},
dependencies: [_parent_component__WEBPACK_IMPORTED_MODULE_0__.Parent],
encapsulation: 2
});`
Platform Browser
class AppComponent {
constructor() {
this.title = 'ng-renderer';
}
}
AppComponent.ɵfac = function AppComponent_Factory(t) {
return new (t || AppComponent)();
};
AppComponent.ɵcmp = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineComponent"]({
type: AppComponent,
selectors: [["app-root"]],
standalone: true,
features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵStandaloneFeature"]],
decls: 3,
vars: 0,
template: function AppComponent_Template(rf, ctx) {
if (rf & 1) {
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](0, "div");
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵtext"](1, "This is inside the div");
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]();
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelement"](2, "app-parent");
}
},
dependencies: [_parent_component__WEBPACK_IMPORTED_MODULE_0__.Parent],
encapsulation: 2
});`
function ɵɵelementStart(index, name, attrsIndex, localRefsIndex) {
/* ... */
const renderer = lView[RENDERER];
const native = (lView[adjustedIndex] = createElementNode(renderer, name, getNamespace$1()));
/* ... */
return ɵɵelementStart;
}
/* ... */
function createElementNode(renderer, name, namespace) {
ngDevMode && ngDevMode.rendererCreateElement++;
return renderer.createElement(name, namespace);
}
Platform Browser
class AppComponent {
constructor() {
this.title = 'ng-renderer';
}
}
AppComponent.ɵfac = function AppComponent_Factory(t) {
return new (t || AppComponent)();
};
AppComponent.ɵcmp = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineComponent"]({
type: AppComponent,
selectors: [["app-root"]],
standalone: true,
features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵStandaloneFeature"]],
decls: 3,
vars: 0,
template: function AppComponent_Template(rf, ctx) {
if (rf & 1) {
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](0, "div");
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵtext"](1, "This is inside the div");
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]();
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelement"](2, "app-parent");
}
},
dependencies: [_parent_component__WEBPACK_IMPORTED_MODULE_0__.Parent],
encapsulation: 2
});`
function ɵɵelementStart(index, name, attrsIndex, localRefsIndex) {
/* ... */
const renderer = lView[RENDERER];
const native = (lView[adjustedIndex] = createElementNode(renderer, name, getNamespace$1()));
/* ... */
return ɵɵelementStart;
}
/* ... */
function createElementNode(renderer, name, namespace) {
ngDevMode && ngDevMode.rendererCreateElement++;
return renderer.createElement(name, namespace);
}
Platform Browser
class AppComponent {
constructor() {
this.title = 'ng-renderer';
}
}
AppComponent.ɵfac = function AppComponent_Factory(t) {
return new (t || AppComponent)();
};
AppComponent.ɵcmp = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineComponent"]({
type: AppComponent,
selectors: [["app-root"]],
standalone: true,
features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵStandaloneFeature"]],
decls: 3,
vars: 0,
template: function AppComponent_Template(rf, ctx) {
if (rf & 1) {
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](0, "div");
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵtext"](1, "This is inside the div");
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]();
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelement"](2, "app-parent");
}
},
dependencies: [_parent_component__WEBPACK_IMPORTED_MODULE_0__.Parent],
encapsulation: 2
});`
function ɵɵelementStart(index, name, attrsIndex, localRefsIndex) {
/* ... */
const renderer = lView[RENDERER];
const native = (lView[adjustedIndex] = createElementNode(renderer, name, getNamespace$1()));
/* ... */
return ɵɵelementStart;
}
/* ... */
function createElementNode(renderer, name, namespace) {
ngDevMode && ngDevMode.rendererCreateElement++;
return renderer.createElement(name, namespace);
}
Platform Browser
class AppComponent {
constructor() {
this.title = 'ng-renderer';
}
}
AppComponent.ɵfac = function AppComponent_Factory(t) {
return new (t || AppComponent)();
};
AppComponent.ɵcmp = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineComponent"]({
type: AppComponent,
selectors: [["app-root"]],
standalone: true,
features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵStandaloneFeature"]],
decls: 3,
vars: 0,
template: function AppComponent_Template(rf, ctx) {
if (rf & 1) {
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](0, "div");
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵtext"](1, "This is inside the div");
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]();
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelement"](2, "app-parent");
}
},
dependencies: [_parent_component__WEBPACK_IMPORTED_MODULE_0__.Parent],
encapsulation: 2
});`
function ɵɵelementStart(index, name, attrsIndex, localRefsIndex) {
/* ... */
const renderer = lView[RENDERER];
const native = (lView[adjustedIndex] = createElementNode(renderer, name, getNamespace$1()));
/* ... */
return ɵɵelementStart;
}
/* ... */
function createElementNode(renderer, name, namespace) {
ngDevMode && ngDevMode.rendererCreateElement++;
return renderer.createElement(name, namespace);
}
Platform Browser
class AppComponent {
constructor() {
this.title = 'ng-renderer';
}
}
AppComponent.ɵfac = function AppComponent_Factory(t) {
return new (t || AppComponent)();
};
AppComponent.ɵcmp = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineComponent"]({
type: AppComponent,
selectors: [["app-root"]],
standalone: true,
features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵStandaloneFeature"]],
decls: 3,
vars: 0,
template: function AppComponent_Template(rf, ctx) {
if (rf & 1) {
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](0, "div");
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵtext"](1, "This is inside the div");
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]();
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelement"](2, "app-parent");
}
},
dependencies: [_parent_component__WEBPACK_IMPORTED_MODULE_0__.Parent],
encapsulation: 2
});`
function ɵɵelementStart(index, name, attrsIndex, localRefsIndex) {
/* ... */
const renderer = lView[RENDERER];
const native = (lView[adjustedIndex] = createElementNode(renderer, name, getNamespace$1()));
/* ... */
return ɵɵelementStart;
}
/* ... */
function createElementNode(renderer, name, namespace) {
ngDevMode && ngDevMode.rendererCreateElement++;
return renderer.createElement(name, namespace);
}
Platform Browser
class AppComponent {
constructor() {
this.title = 'ng-renderer';
}
}
AppComponent.ɵfac = function AppComponent_Factory(t) {
return new (t || AppComponent)();
};
AppComponent.ɵcmp = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineComponent"]({
type: AppComponent,
selectors: [["app-root"]],
standalone: true,
features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵStandaloneFeature"]],
decls: 3,
vars: 0,
template: function AppComponent_Template(rf, ctx) {
if (rf & 1) {
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](0, "div");
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵtext"](1, "This is inside the div");
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]();
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelement"](2, "app-parent");
}
},
dependencies: [_parent_component__WEBPACK_IMPORTED_MODULE_0__.Parent],
encapsulation: 2
});`
function ɵɵelementStart(index, name, attrsIndex, localRefsIndex) {
/* ... */
const renderer = lView[RENDERER];
const native = (lView[adjustedIndex] = createElementNode(renderer, name, getNamespace$1()));
/* ... */
return ɵɵelementStart;
}
/* ... */
function createElementNode(renderer, name, namespace) {
ngDevMode && ngDevMode.rendererCreateElement++;
// feels similar? document.createElement('div') anyone?
return renderer.createElement(name, namespace);
}
Platform Browser
class AppComponent {
constructor() {
this.title = 'ng-renderer';
}
}
AppComponent.ɵfac = function AppComponent_Factory(t) {
return new (t || AppComponent)();
};
AppComponent.ɵcmp = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineComponent"]({
type: AppComponent,
selectors: [["app-root"]],
standalone: true,
features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵStandaloneFeature"]],
decls: 3,
vars: 0,
template: function AppComponent_Template(rf, ctx) {
if (rf & 1) {
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](0, "div");
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵtext"](1, "This is inside the div");
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]();
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelement"](2, "app-parent");
}
},
dependencies: [_parent_component__WEBPACK_IMPORTED_MODULE_0__.Parent],
encapsulation: 2
});`
function ɵɵelementStart(index, name, attrsIndex, localRefsIndex) {
/* ... */
const renderer = lView[RENDERER];
const native = (lView[adjustedIndex] = createElementNode(renderer, name, getNamespace$1()));
/* ... */
return ɵɵelementStart;
}
/* ... */
function createElementNode(renderer, name, namespace) {
ngDevMode && ngDevMode.rendererCreateElement++;
return renderer.createElement(name, namespace);
}
Platform Browser
class AppComponent {
constructor() {
this.title = 'ng-renderer';
}
}
AppComponent.ɵfac = function AppComponent_Factory(t) {
return new (t || AppComponent)();
};
AppComponent.ɵcmp = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineComponent"]({
type: AppComponent,
selectors: [["app-root"]],
standalone: true,
features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵStandaloneFeature"]],
decls: 3,
vars: 0,
template: function AppComponent_Template(rf, ctx) {
if (rf & 1) {
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](0, "div");
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵtext"](1, "This is inside the div");
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]();
_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelement"](2, "app-parent");
}
},
dependencies: [_parent_component__WEBPACK_IMPORTED_MODULE_0__.Parent],
encapsulation: 2
});`
Platform Browser
Platform Browser
Property Binding: [property]="expr"
Platform Browser
Property Binding: [property]="expr"
Attribute Binding: attrName="static-value"
Platform Browser
Property Binding: [property]="expr"
Attribute Binding: attrName="static-value"
Event Binding: (eventName)="handler()"
Platform Browser
<div [id]="title" title="my-title" (click)="onClick()">This is inside the div</div>
Platform Browser
AppComponent.ɵcmp = /*@__PURE__*/ _angular_core__WEBPACK_IMPORTED_MODULE_1__['ɵɵdefineComponent']({
/* ... */
consts: [['title', 'my-title', 3, 'id']],
template: function AppComponent_Template(rf, ctx) {
if (rf & 1) {
/* ... */
_angular_core__WEBPACK_IMPORTED_MODULE_1__['ɵɵelementStart'](0, 'div', 0);
_angular_core__WEBPACK_IMPORTED_MODULE_1__['ɵɵlistener'](
'click',
function AppComponent_Template_div_click_0_listener() {
return ctx.onClick();
}
);
/* ... */
}
if (rf & 2) {
_angular_core__WEBPACK_IMPORTED_MODULE_1__['ɵɵproperty']('id', ctx.title);
}
},
/* ... */
});
Platform Browser
AppComponent.ɵcmp = /*@__PURE__*/ _angular_core__WEBPACK_IMPORTED_MODULE_1__['ɵɵdefineComponent']({
/* ... */
consts: [['title', 'my-title', 3, 'id']],
template: function AppComponent_Template(rf, ctx) {
if (rf & 1) {
/* ... */
_angular_core__WEBPACK_IMPORTED_MODULE_1__['ɵɵelementStart'](0, 'div', 0);
_angular_core__WEBPACK_IMPORTED_MODULE_1__['ɵɵlistener'](
'click',
function AppComponent_Template_div_click_0_listener() {
return ctx.onClick();
}
);
/* ... */
}
if (rf & 2) {
_angular_core__WEBPACK_IMPORTED_MODULE_1__['ɵɵproperty']('id', ctx.title);
}
},
/* ... */
});
<div [id]="title" title="my-title" (click)="onClick()">This is inside the div</div>
Platform Browser
AppComponent.ɵcmp = /*@__PURE__*/ _angular_core__WEBPACK_IMPORTED_MODULE_1__['ɵɵdefineComponent']({
/* ... */
consts: [['title', 'my-title', 3, 'id']],
template: function AppComponent_Template(rf, ctx) {
if (rf & 1) {
/* ... */
_angular_core__WEBPACK_IMPORTED_MODULE_1__['ɵɵelementStart'](0, 'div', 0);
_angular_core__WEBPACK_IMPORTED_MODULE_1__['ɵɵlistener'](
'click',
function AppComponent_Template_div_click_0_listener() {
return ctx.onClick();
}
);
/* ... */
}
if (rf & 2) {
_angular_core__WEBPACK_IMPORTED_MODULE_1__['ɵɵproperty']('id', ctx.title);
}
},
/* ... */
});
<div [id]="title" title="my-title" (click)="onClick()">This is inside the div</div>
Platform Browser
AppComponent.ɵcmp = /*@__PURE__*/ _angular_core__WEBPACK_IMPORTED_MODULE_1__['ɵɵdefineComponent']({
/* ... */
consts: [['title', 'my-title', 3, 'id']],
template: function AppComponent_Template(rf, ctx) {
if (rf & 1) {
/* ... */
_angular_core__WEBPACK_IMPORTED_MODULE_1__['ɵɵelementStart'](0, 'div', 0);
_angular_core__WEBPACK_IMPORTED_MODULE_1__['ɵɵlistener'](
'click',
function AppComponent_Template_div_click_0_listener() {
return ctx.onClick();
}
);
/* ... */
}
if (rf & 2) {
_angular_core__WEBPACK_IMPORTED_MODULE_1__['ɵɵproperty']('id', ctx.title);
}
},
/* ... */
});
<div [id]="title" title="my-title" (click)="onClick()">This is inside the div</div>
Platform Browser
AppComponent.ɵcmp = /*@__PURE__*/ _angular_core__WEBPACK_IMPORTED_MODULE_1__['ɵɵdefineComponent']({
/* ... */
consts: [['title', 'my-title', 3, 'id']],
template: function AppComponent_Template(rf, ctx) {
if (rf & 1) {
/* ... */
_angular_core__WEBPACK_IMPORTED_MODULE_1__['ɵɵelementStart'](0, 'div', 0);
_angular_core__WEBPACK_IMPORTED_MODULE_1__['ɵɵlistener'](
'click',
function AppComponent_Template_div_click_0_listener() {
return ctx.onClick();
}
);
/* ... */
}
if (rf & 2) {
_angular_core__WEBPACK_IMPORTED_MODULE_1__['ɵɵproperty']('id', ctx.title);
}
},
/* ... */
});
<div [id]="title" title="my-title" (click)="onClick()">This is inside the div</div>
Platform Browser
AppComponent.ɵcmp = /*@__PURE__*/ _angular_core__WEBPACK_IMPORTED_MODULE_1__['ɵɵdefineComponent']({
/* ... */
consts: [['title', 'my-title', 3, 'id']],
template: function AppComponent_Template(rf, ctx) {
if (rf & 1) {
/* ... */
_angular_core__WEBPACK_IMPORTED_MODULE_1__['ɵɵelementStart'](0, 'div', 0);
_angular_core__WEBPACK_IMPORTED_MODULE_1__['ɵɵlistener'](
'click',
function AppComponent_Template_div_click_0_listener() {
return ctx.onClick();
}
);
/* ... */
}
if (rf & 2) {
_angular_core__WEBPACK_IMPORTED_MODULE_1__['ɵɵproperty']('id', ctx.title);
}
},
/* ... */
});
<div [id]="title" title="my-title" (click)="onClick()">This is inside the div</div>
export declare abstract class Renderer2 {
abstract get data(): {
[key: string]: any;
};
abstract destroy(): void;
abstract createElement(name: string, namespace?: string | null): any;
abstract createComment(value: string): any;
abstract createText(value: string): any;
destroyNode: ((node: any) => void) | null;
abstract appendChild(parent: any, newChild: any): void;
abstract insertBefore(parent: any, newChild: any, refChild: any, isMove?: boolean): void;
abstract removeChild(parent: any, oldChild: any, isHostElement?: boolean): void;
abstract selectRootElement(selectorOrNode: string | any, preserveContent?: boolean): any;
abstract parentNode(node: any): any;
abstract nextSibling(node: any): any;
abstract setAttribute(el: any, name: string, value: string, namespace?: string | null): void;
abstract removeAttribute(el: any, name: string, namespace?: string | null): void;
abstract addClass(el: any, name: string): void;
abstract removeClass(el: any, name: string): void;
abstract setStyle(el: any, style: string, value: any, flags?: RendererStyleFlags2): void;
abstract removeStyle(el: any, style: string, flags?: RendererStyleFlags2): void;
abstract setProperty(el: any, name: string, value: any): void;
abstract setValue(node: any, value: string): void;
abstract listen(
target: 'window' | 'document' | 'body' | any,
eventName: string,
callback: (event: any) => boolean | void
): () => void;
}
Create a Custom Renderer
Create a Custom Renderer
Create a Custom Renderer
RendererFactory2
Create a Custom Renderer
RendererFactory2
Renderer2
+
Create a Custom Renderer
Demo
Dec 2022
Jan 2023
Thank you
Angular v17
(upto 17.3)
output()
input()
queries
model()
browserUrl
https://github.com/angular/angular/issues/17004
GuardResult & MaybeAsync
TypeScript 5.4
https://devblogs.microsoft.com/typescript/announcing-typescript-5-4/
https://github.com/angular/angular/releases
Angular Three Renderer
By Chau Tran
Angular Three Renderer
- 560