I currently have the following line in my HTML:
<p> this is my first line </p>
Using a wrapper directive I want to add a second paragraph and wrap it in a div so it will look like this:
<p wrapper> this is my first line </p>
And then the directive will add the wrapper and second line to make the final HTML look like this:
<div>
<p> this is my first line </p>
<p> this is my second </p>
</div>
From what I understand from angular.io I will need to create a structural directive and use a TemplateRef and a ViewContainerRef, but I can't find an example on how to use them to wrap an existing part of the dom and add a second line.
I'm using Angular 5 in this project.
Structural directives are a type of directive which changes the structure of the DOM. We use the <ng-template> tag to define the element we want to insert into the DOM. We can prepend the directive name with * to skip having to define a <ng-template> and have the directive use the element it’s attached to as the template.
You may apply only one structuraldirective to an element. The reason is simplicity. Structural directives can do complex things with the host element and its descendents. When two directives lay claim to the same host element, which one takes precedence?
When structural directives are applied they generally are prefixed by an asterisk, *, such as * ngIf. This convention is shorthand that Angular interprets and converts into a longer form. Angular transforms the asterisk in front of a structural directive into an <ng-template> that surrounds the host element and its descendants.
Creating a directive is similar to creating a component. Import the Directivedecorator (instead of the Componentdecorator). Import the Input, TemplateRef, and ViewContainerRefsymbols; you'll need them for anystructural directive.
I made the directive like so:
import { Directive, ElementRef, Renderer2, OnInit } from '@angular/core';
@Directive({
selector: '[wrapper]'
})
export class WrapperDirective implements OnInit {
constructor(
private elementRef: ElementRef,
private renderer: Renderer2) {
console.log(this);
}
ngOnInit(): void {
//this creates the wrapping div
const div = this.renderer.createElement('div');
//this creates the second line
const line2 = this.renderer.createElement('p');
const text = this.renderer.createText('this is my second');
this.renderer.appendChild(line2, text);
const el = this.elementRef.nativeElement; //this is the element to wrap
const parent = el.parentNode; //this is the parent containing el
this.renderer.insertBefore(parent, div, el); //here we place div before el
this.renderer.appendChild(div, el); //here we place el in div
this.renderer.appendChild(div, line2); //here we append the second line in div, after el
}
}
the templateRef has property called "elementRef" you can throw it access the native dom like this:
this.templateRef.elementRef.nativeElement
So you can get the access to your element like above and use the built in Renderer class providing by angular.
check the below link please
https://angular.io/api/core/Renderer2
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With