Jose Raul Perera
Jose Raul Perera

Reputation: 878

Angular Directives Reference elements

I have a Dashboard Component with this template:

<div class="widget-container" id="dashboard-container">
    <app-my-widget id="comp1" draggable boundary="#dashboard-container">
        <p component>Test 1</p>
    </app-my-widget>
</div> 

As you can see we have a component app-my-widget that have a directive draggable

This is the app-my-widget html:

<div class="widget-container">
    <div class="drag-handle" dragging-handler></div>
    <div class="content">
        <ng-content select="[component]"></ng-content>
    </div>
    <div class="resize-handle" resize-handler></div>
</div>

This is my app-widget-component referencing the Two Directives:

@Component({
  selector: 'app-my-widget',
  standalone: true,
  imports: [],
  hostDirectives: [
    {
      directive: DraggableDirective,
      inputs: ['boundary'],
    },
    {
      directive: DraggingHandlerDirective
    },
  ],
  templateUrl: './my-widget.component.html',
  styleUrl: './my-widget.component.scss'
})

My problem is the following I have a second directive dragging-handler with just this code:

constructor(public elementRef: ElementRef<HTMLElement>) {}

I need from the draggable Directive reference the div element with the Directive dragging-handler so my code should be something like this:

@ContentChild(DraggingHandlerDirective) handle!: DraggingHandlerDirective;
  handleElement!: HTMLElement;

But handle is always undefined. What I'm missing here?

Upvotes: 1

Views: 32

Answers (2)

Jose Raul Perera
Jose Raul Perera

Reputation: 878

This is probably not the best but I'm tired of spending 2 days to make this work so what I did was:

this.element = this.elementRef.nativeElement as HTMLElement;
this.handleElement = (this.element).querySelector('.drag-handle');

And this worked perfectly fine. Thanks all for your suggestions.

Upvotes: 0

Naren Murali
Naren Murali

Reputation: 58449

You can just use ViewChild to access the directive, from the other directive. Because the directive is present in the hostDirectives, the handler, is a child element in the view, not the content.

@Directive({ ... })
export class DraggableDirective {
    @ViewChild(DraggingHandlerDirective) handle!: DraggingHandlerDirective;
    handleElement!: HTMLElement;
    ...
}

Also we do not need to second definition of draggable directive in the dashboard component, since you already added it to the host listeners.

<div class="widget-container" id="dashboard-container">
    <app-my-widget id="comp1" boundary="#dashboard-container">
        <p component>Test 1</p>
    </app-my-widget>
</div>  

Upvotes: 0

Related Questions