Tengo un conjunto de componentes de una sola celda dentro de un bucle ng-for .
Tengo todo en su lugar, pero parece que no puedo averiguar el correcto
Actualmente tengo
setTimeout(() => { scrollToBottom(); });Pero esto no funciona todo el tiempo ya que las imágenes empujan la ventana gráfica hacia abajo de forma asincrónica.
¿Cuál es la forma adecuada de desplazarse hasta la parte inferior de una ventana de chat en Angular 2?
Tuve el mismo problema, estoy usando una combinación de AfterViewChecked y @ViewChild (Angular2 beta.3).
El componente:
import {..., AfterViewChecked, ElementRef, ViewChild, OnInit} from 'angular2/core' @Component({ ... }) export class ChannelComponent implements OnInit, AfterViewChecked { @ViewChild('scrollMe') private myScrollContainer: ElementRef; ngOnInit() { this.scrollToBottom(); } ngAfterViewChecked() { this.scrollToBottom(); } scrollToBottom(): void { try { this.myScrollContainer.nativeElement.scrollTop = this.myScrollContainer.nativeElement.scrollHeight; } catch(err) { } } }La plantilla:
<div #scrollMe style="overflow: scroll; height: xyz;"> <div class="..." *ngFor="..." ...> </div> </div> Por supuesto, esto es bastante básico. AfterViewChecked activa cada vez que se comprueba la vista:
Implemente esta interfaz para recibir notificaciones después de cada verificación de la vista de su componente.
Si tiene un campo de entrada para enviar mensajes, por ejemplo, este evento se activa después de cada pulsación (solo para dar un ejemplo). Pero si guarda si el usuario se desplazó manualmente y luego omite scrollToBottom() , debería estar bien.
La solución más simple y mejor para esto es:
Agregue esta cosa simple #scrollMe [scrollTop]="scrollMe.scrollHeight" en el lado de la plantilla
<div style="overflow: scroll; height: xyz;" #scrollMe [scrollTop]="scrollMe.scrollHeight"> <div class="..." *ngFor="..." ...> </div> </div>Aquí está el enlace para la DEMO DE TRABAJO (con la aplicación de chat ficticia) Y EL CÓDIGO COMPLETO
Funcionará con Angular2 y también hasta 5, como la demostración anterior se realiza en Angular5.
Nota :
Por error:
ExpressionChangedAfterItHasBeenCheckedErrorVerifique su css, es un problema del lado css, no del lado angular. Uno de los usuarios @KHAN lo resolvió eliminando el
overflow:auto; height: 100%;dediv. (verifique las conversaciones para más detalles)
La respuesta aceptada se dispara mientras se desplaza por los mensajes, esto evita eso.
Quieres una plantilla como esta.
<div #content> <div #messages *ngFor="let message of messages"> {{message}} </div> </div>Luego, desea utilizar una anotación ViewChildren para suscribirse a los nuevos elementos de mensaje que se agregan a la página.
@ViewChildren('messages') messages: QueryList<any>; @ViewChild('content') content: ElementRef; ngAfterViewInit() { this.scrollToBottom(); this.messages.changes.subscribe(this.scrollToBottom); } scrollToBottom = () => { try { this.content.nativeElement.scrollTop = this.content.nativeElement.scrollHeight; } catch (err) {} }