Search code examples
angularchatangular-directive

Call directive's method from component - Angular 9


I'm trying to build a chat component in Angular 9 PWA. Now I'm wondering how to implement an "automatic scroll to bottom" functionallity when a new message is being displayed in the chat window.

For this purpose, I've created a custom ScrollToBottom directive and applied it to chat DIV container.

<div class="msg_history" scrollToBottom>
   <li class="message" *ngFor="let message of messages | async">

In this directive I have a method called scrollToBottom.

public scrollToBottom() {
    const el: HTMLDivElement = this._el.nativeElement;
    setTimeout(() => el.scrollTop = Math.max(0, el.scrollHeight - el.offsetHeight));
  }

Now, my question is, whether is it possible (and how?) to call a directive's method from the Chat component after a Conversetion Subject recives a new message.

//In component
this.chatService.conversation.subscribe(() => DIRECTIVE.scrollToBottom());

OR it's better way to omit the Chat component and inject the Chat Service directly in the Directive in order to handle a Conversetion Subject changes there ?

@Directive({
  selector: '[scrollToBottom]'
})
export class ScrollToBottomDirective {
  constructor(private _el: ElementRef, private chat: ChatService) { }

  public ngAfterViewInit() {
    this.chat.conversation.subscribe(() => this.scrollToBottom());
  }

  public scrollToBottom() {
    const el: HTMLDivElement = this._el.nativeElement;
    setTimeout(() => el.scrollTop = Math.max(0, el.scrollHeight - el.offsetHeight));
  }
}

Thank you in forward ;-)


Solution

  • yep, inside the chat component, you can leverage the ViewChild decorator to get a reference to the components\directives inside the current component

    @ViewChild(ScrollToBottomDirective) child: ScrollToBottomDirective;
    
    //In component
    this.chatService.conversation.subscribe(() => this.child.scrollToBottom());