// Motivation: https://github.com/angular/angular/issues/18877
import { Directive, ElementRef, AfterViewInit } from '@angular/core';
@Directive({
standalone: true,
selector: '[remove-host]'
})
export class RemoveHostDirective implements AfterViewInit {
constructor(private el: ElementRef) { }
ngAfterViewInit() {
const host = this.el.nativeElement;
const parent = host.parentNode;
if (parent) {
const fragment = document.createDocumentFragment();
while (host.firstChild) {
fragment.appendChild(host.firstChild);
}
parent.insertBefore(fragment, host);
parent.removeChild(host);
}
}
}
This Angular directive designed to remove
the host element of a component from the DOM while keeping its children.
import { Component } from '@angular/core';
@Component({
template: `
<h1>Hello World!</h1>
<p>This is content from the ExampleComponent.</p>
`,
// Include the directive
hostDirectives: [RemoveHostDirective]
})
export class ExampleComponent {}
So, The host div
element which will create by Angular will remove and you have just h1
and p
without any wrapper around in the DOM.
// Motivation: https://vuejs.org/guide/components/attrs.html
import { Directive, ElementRef, Renderer2, OnInit } from '@angular/core';
@Directive({
standalone: true,
selector: '[attrs]',
})
export class AttrsDirective implements OnInit {
constructor(private el: ElementRef, private renderer: Renderer2) { }
ngOnInit() {
const originalHostElement = this.el.nativeElement;
const newHostElements = originalHostElement.querySelectorAll('[attrs]');
if (!newHostElements.length) return;
newHostElements.forEach((newHostElement: any) => {
for (let i = 0; i < originalHostElement.attributes.length; i++) {
const attribute = originalHostElement.attributes[i];
if (!attribute.name.startsWith('_ng')) {
const existingAttrValue = newHostElement.getAttribute(attribute.name);
if (existingAttrValue) {
const newValue = `${existingAttrValue} ${attribute.value}`;
this.renderer.setAttribute(
newHostElement,
attribute.name,
newValue.trim()
);
} else {
this.renderer.setAttribute(
newHostElement,
attribute.name,
attribute.value
);
}
}
}
});
for (let i = originalHostElement.attributes.length - 1; i >= 0; i--) {
const attribute = originalHostElement.attributes[i];
if (!attribute.name.startsWith('_ng')) {
this.renderer.removeAttribute(originalHostElement, attribute.name);
}
}
}
}
This Angular directive, AttrsDirective
, is designed to transfer attributes from a host element to its child elements.
For example:
import { Component } from '@angular/core';
import { AttrsDirective } from './attrs.directive'; // assuming both are in the same directory
@Component({
selector: 'app-bootstrap-badge',
template: `
<button type="button" class="btn btn-primary">
Notifications <span class="badge" attrs>4</span>
</button>
`,
styleUrls: ['node_modules/bootstrap/dist/css/bootstrap.min.css'],
hostDirectives: [AttrsDirective]
})
export class BootstrapCardComponent { }
Now you can use like
import { Component } from '@angular/core';
@Component({
selector: 'app-parent',
template: `
<app-bootstrap-badge class="text-bg-secondary"></app-bootstrap-badge>
`
})
export class ParentComponent { }
So, text-bg-secondary
instead of host element will transfer and apply to span
inside the component.