twitter.com/@nartc1410
github.com/nartc
@Component({
template: `
<div>This is inside the div</div>
<app-parent />
`,
imports: [ParentComponent],
})
export class AppComponent {
title = 'ng-renderer';
}
Component
Template
Component
Template
Compiler
Component
Template
Compiler
Template
Instructions
Component
Template
Compiler
Template
Instructions
Renderer
Component
Template
Compiler
Template
Instructions
Renderer
Platform
the bridge between your template and the platform
Component
Template
Compiler
Template
Instructions
Renderer
Platform
the bridge between Angular Core and the platform
Angular
Core
Renderer
Platform
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
});`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';
}
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
});`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
});`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);
}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);
}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);
}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);
}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);
}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);
}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);
}Property Binding: [property]="expr"
Property Binding: [property]="expr"
Attribute Binding: attrName="static-value"
Property Binding: [property]="expr"
Attribute Binding: attrName="static-value"
Event Binding: (eventName)="handler()"
<div [id]="title" title="my-title" (click)="onClick()">This is inside the div</div>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);
}
},
/* ... */
});
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>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>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>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>RendererFactory2
RendererFactory2
Renderer2
+
Demo
(upto 17.3)
https://github.com/angular/angular/issues/17004
https://devblogs.microsoft.com/typescript/announcing-typescript-5-4/