Saya memiliki masalah yang sama, saya menggunakan kombinasi AfterViewChecked
dan @ViewChild
(Angular2 beta.3).
Komponen:
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) { }
}
}
Template:
<div #scrollMe style="overflow: scroll; height: xyz;">
<div class="..."
*ngFor="..."
...>
</div>
</div>
Tentu saja ini sangat mendasar. The AfterViewChecked
memicu setiap kali pandangan diperiksa:
Terapkan antarmuka ini untuk mendapatkan pemberitahuan setelah setiap pemeriksaan tampilan komponen Anda.
Jika Anda memiliki input-field untuk mengirim pesan misalnya, event ini dijalankan setelah setiap keyup (hanya untuk memberikan contoh). Tetapi jika Anda menyimpan apakah pengguna menggulir secara manual dan kemudian melewati scrollToBottom()
Anda harus baik-baik saja.
biarkan aku memperbaikinya
sumber
Solusi paling sederhana dan terbaik untuk ini adalah:
Tambahkan hal
#scrollMe [scrollTop]="scrollMe.scrollHeight"
sederhana ini di sisi TemplateBerikut ini tautan untuk WORKING DEMO (Dengan aplikasi obrolan boneka) DAN KODE LENGKAP
sumber
Expression has changed after it was checked. Previous value: 'scrollTop: 1758'. Current value: 'scrollTop: 1734'
. Apakah Anda menyelesaikannya?Saya menambahkan tanda centang untuk melihat apakah pengguna mencoba menggulir ke atas.
Saya hanya akan meninggalkan ini di sini jika ada yang menginginkannya :)
dan kode:
sumber
Jawaban yang diterima menyala saat menggulir pesan, ini menghindarinya.
Anda menginginkan template seperti ini.
Kemudian Anda ingin menggunakan anotasi ViewChildren untuk berlangganan elemen pesan baru yang ditambahkan ke halaman.
sumber
Pertimbangkan untuk menggunakan
Lihat https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
sumber
Jika Anda ingin memastikan, bahwa Anda menggulir ke akhir setelah * ngFor selesai, Anda dapat menggunakan ini.
Penting di sini, "lalu" mendefinisikan variabel jika Anda saat ini di item terakhir, sehingga Anda dapat memicu "scrollToBottom" Metode
sumber
sumber
Berbagi solusi saya, karena saya tidak sepenuhnya puas dengan yang lain. Masalah saya
AfterViewChecked
adalah terkadang saya menggulir ke atas, dan untuk beberapa alasan, pengait kehidupan ini dipanggil dan menggulung saya ke bawah meskipun tidak ada pesan baru. Saya mencoba menggunakanOnChanges
tetapi ini adalah masalah, yang mengarahkan saya ke solusi ini . Sayangnya, hanya dengan menggunakanDoCheck
, itu bergulir ke bawah sebelum pesan dirender, yang juga tidak berguna, jadi saya menggabungkannya sehingga DoCheck pada dasarnya menunjukkanAfterViewChecked
apakah itu harus memanggilscrollToBottom
.Senang menerima umpan balik.
chat.component.html
chat.component.sass
sumber
const isScrolledDown = Math.abs(this.scrollable.nativeElement.scrollHeight - this.scrollable.nativeElement.scrollTop - this.scrollable.nativeElement.clientHeight) <= 3.0;
(di mana 3,0 adalah toleransi dalam piksel). Hal ini dapat digunakan dalamngDoCheck
kondisional tidak diaturshouldScrollDown
untuktrue
jika pengguna secara manual menggulir up.ngAfterViewChecked
dengan boolean lain. Saya menggantishouldScrollDown
nama menjadinumberOfMessagesChanged
untuk memberikan kejelasan tentang apa sebenarnya yang dimaksud boolean ini.if (this.numberOfMessagesChanged && !isScrolledDown)
, tetapi saya pikir Anda tidak mengerti maksud dari saran saya. Maksud saya sebenarnya adalah untuk tidak menggulir ke bawah secara otomatis bahkan ketika pesan baru ditambahkan, jika pengguna menggulir ke atas secara manual . Tanpa ini, jika Anda menggulir ke atas untuk melihat riwayat, obrolan akan menggulir ke bawah segera setelah pesan baru tiba. Ini bisa menjadi perilaku yang sangat mengganggu. :) Jadi, saran saya adalah untuk memeriksa apakah obrolan di-scroll ke atas sebelum pesan baru ditambahkan ke DOM dan jangan autoscroll, jika ya.ngAfterViewChecked
sudah terlambat karena DOM sudah berubah.Jawaban Vivek telah berhasil untuk saya, tetapi menghasilkan ekspresi yang berubah setelah diperiksa kesalahannya. Tidak ada komentar yang berhasil untuk saya, tetapi yang saya lakukan adalah mengubah strategi deteksi perubahan.
sumber
Dalam sudut menggunakan desain material sidenav saya harus menggunakan yang berikut:
sumber
sumber
Setelah membaca solusi lain, solusi terbaik yang dapat saya pikirkan, jadi Anda hanya menjalankan yang Anda butuhkan adalah sebagai berikut: Anda menggunakan ngOnChanges untuk mendeteksi perubahan yang tepat
Dan Anda menggunakan ngAfterViewChecked untuk benar-benar menerapkan perubahan sebelum dirender, tetapi setelah ketinggian penuh dihitung
Jika Anda bertanya-tanya bagaimana cara mengimplementasikan scrollToBottom
sumber