JPS
JPS

Reputation: 2760

How to change border using a structural directive?

I am trying to create an angular directive that does two things.

 1. change border of the host element
 2. append a button at the end of the host element

As of now i am on the first step where i have to set the border of host element.

HTML

  <div *myDirective
        <h1> some value </h1>
  </div>      

Directive

export class MyDirective{

  constructor(private templateRef: TemplateRef<any>,
    private viewContainer: ViewContainerRef) {
      this.templateRef.elementRef.nativeElement.style['border'] = '1px solid red';
      this.viewContainer.createEmbeddedView(this.templateRef);
    }      
}

Now when i add this directive to a div element,I get the following error,

Cannot set property 'border' of undefined

How could i change the style and append another element to the host using structural directive?

[Edit] As most of the answers are suggesting me to create an attribute directive, i just want to post the statement from angular document regarding structural directives.

They shape or reshape the DOM's structure, typically by adding, removing, or manipulating elements.

In that case creating attribute directive to append a button to the host element is not proper. Isn't it?

Upvotes: 3

Views: 3586

Answers (3)

kboul
kboul

Reputation: 14570

For the border you need to do the following:

Create the directive:

import { Directive, ElementRef, Renderer } from '@angular/core';

// Directive decorator
@Directive({ selector: '[myDirective]' })
// Directive class
export class MyDirective {
    constructor(el: ElementRef, renderer: Renderer) {
    // Use renderer to render the element with styles
    renderer.setElementStyle(el.nativeElement, 'border', '1px solid red');
    }
}

Following you need to declare and export this directive via SharedModule so that the app module can load and import it globally.

Shared.module

import { NgModule } from '@angular/core';

import { MyDirective } from './my-directive.directive';

@NgModule({
    declarations: [
        MyDirective
    ],
    exports: [
        MyDirective
    ]
})
export class SharedModule{}

Then import the shared module in the app.module

then use it as follows:

<div myDirective>
    <h1> some value </h1>
</div> 

Demo

Upvotes: 0

westor
westor

Reputation: 1534

Indeed I would use a structural directive for this.

But the templateRef.elementRef.nativeElement is just a html comment, and there is no style property.

To append the button you can follow this very good example of a structural directive: Adding a Component to a TemplateRef using a structural Directive

Upvotes: 0

Akj
Akj

Reputation: 7231

Try like this:

DEMO

mydirective.ts:

import { Directive, TemplateRef, ElementRef, ViewContainerRef } from '@angular/core';

@Directive({
  selector: '[appMydirective]'
})
export class MydirectiveDirective {

  constructor(private el: ElementRef) {
    console.log(this.el.nativeElement)
    el.nativeElement.style.border = '2px solid red';
    let bt = document.createElement("button");
    var btContent = document.createTextNode("my Button");
    bt.appendChild(btContent);
    bt.style.cssFloat = 'right'
    this.el.nativeElement.append(bt)
  }
}

HTML:

<div appMydirective>
        <h1> some value </h1>
  </div> 

Upvotes: 1

Related Questions