Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to enable autoscrolling in perfect-scrollbar with angular 4?

documentation is not being very helpful here. I want to use the perfect scroll-bar in my application so that I bypass issues of compatibility with all browsers. I initialized my code exactly as described here https://github.com/zefoy/ngx-perfect-scrollbar/tree/4.x.x/ . This is what I did in my html

<perfect-scrollbar id="chat" [config]="config"> <li *ngFor="let message of messages"> {{messages}} <li> </perfect-scrollbar>

now for each new message I want the container to autoscroll to the latest message. Reading further the documentation I found that there'are directives to call events. that is described at the end of the document I linked earlier. So my approach has been the following in the same component:

import {PerfectScrollbarComponent } from 'ngx-perfect-scrollbar';
...

constructor(private scrollbar:PerfectScrollbarComponent) { }
...

  ngDoCheck() {
    var chat = document.getElementById('chat');
    this.scrollbar.directiveRef.scrollToBottom(chat.scrollHeight);
  }

This gives me an error because it's expecting PerfectScrollbarComponent to be a provider. After I do that, I get another error No provider for ElementRef!.

I am loosing my sleep over this. Can anyone suggest a suggestion on how to implement autoscrolling with perfectscrollbar in angular 4? Thank you in advance

like image 589
Sivvio Avatar asked Nov 15 '17 12:11

Sivvio


3 Answers

After spending so much time I solved my problem using perfect-scrollbar directive.

My problem was to add the new message in the database then scroll to new message. Tried so many methods but

setTimeout() solved my problem

Sharing the code below

HTML:

<perfect-scrollbar>
   <div class="msg-body" [perfectScrollbar] #psBottom="ngxPerfectScrollbar">
      <ng-container *ngFor="let msg of messages">
         <div class="nk-reply-item">
            {{msg.content}}
         </div>
      </ng-container>
   </div>
</perfect-scrollbar>

TS:

import { Component, OnInit, ViewChild } from '@angular/core';
import { PerfectScrollbarDirective } from 'ngx-perfect-scrollbar';
export class MessageComponent implements OnInit {
   @ViewChild('psBottom') psBottom: PerfectScrollbarDirective;
   messages = []
   constructor() {}

   addMessage(newMsg) {
      // request to backend or simply push the new msg to messages array
      setTimeout(() => {
         this.psBottom.scrollToBottom(0, 500);
      }, 100);
   }
like image 103
Usama nadeem Avatar answered Nov 10 '22 09:11

Usama nadeem


I also spent a lot of time on this and solved this problem as follows:

HTML:

<perfect-scrollbar class="window__list">
  ...
</perfect-scrollbar>

Component:

...
import { PerfectScrollbarComponent } from 'ngx-perfect-scrollbar';

export class ChatWindowComponent implements OnInit {
   ...
   // Linking to component that using perfect-scrollbar
   @ViewChild(PerfectScrollbarComponent) public directiveScroll: PerfectScrollbarComponent;
   ...
   constructor() { }
   ...
   toBottom(): void {
     if (isUndefined(this.directiveScroll)) return;
     this.directiveScroll.directiveRef.scrollToBottom(0, 100)
  }
}
like image 45
Sergey Dzyuba Avatar answered Nov 10 '22 08:11

Sergey Dzyuba


PerfectScrollbarComponent is a component as the name suggests, so instead of injecting it, you need to get a reference to it using @ViewChild

@ViewChild(PerfectScrollbarComponent)
scrollbar?: PerfectScrollbarComponent;

Assuming the latest message appear at the bottom of the list, you can use scrollToBottom method available on the directiveRef

this.scrollbar.directiveRef.scrollToBottom(0, 500);  // 500ms is the speed
like image 3
Sandeep Avatar answered Nov 10 '22 08:11

Sandeep