Xử lý expand quill-view-html trong angular
Hiện tại em đang sử dụng quill-view-html
để editor trong angular
Em muốn có cái chức năng expand nội dụng thì xử lý như thế nào ạ
Hiện tại em sử dụng code như sau để hiển thị
<div *ngIf="traLoi" class="bg-gray-200 flex flex-col ">
...
<div class="line-clamp-2 max-h-20" id="traLoi">
<quill-view-html class="app-bg-gray" [content]="traLoi?.NOI_DUNG"></quill-view-html>
</div>
<div *ngIf="checkShowExpandedCTTL()" class="text-center absolute bottom-0 left-0 right-0 bg-gradient-to-b from-transparent to-gray-300 h-18 ">
<span class="content-between absolute bottom-0 left-0 right-0 hover:cursor-pointer ">Ấn vào đây để mở rộng</span>
</div>
</div>
checkShowExpandedCTTL(): boolean {
const element: HTMLElement = document.getElementById( 'traLoi');
const quillEditor: HTMLElement = element.querySelector('quill-view-html');
return element.offsetHeight < quillEditor.offsetHeight;
}
traLoi
nó sẽ thay đổi khi ấn vào các button
Nhưng nó xuất hiện lỗi
thì xử lý làm sao ạ
1 CÂU TRẢ LỜI
Lỗi expression changed after view has been checked error xảy ra ở code của e ở đoạn *ngIf
, lỗi này xảy ra khi biểu thức bên trong ngif của e bị thay đổi khi Angular vừa thực hiện xong việc "check".
Khi dev ở local (development mode), Angular làm 1 việc giống với React đó là thực hiện "thêm" 1 lần "check" sau mỗi lần chạy Change Detection, nhằm đảm bảo là cái state e bind ko thay đổi, cụ thể là *ngIf="traLoi"
.
Khả năng cao là e đang thay đổi state traLoi
ở trong ngOnChanges
, ngAfterViewInit
, hoặc là 1 số thao tác async chạy sau Change Detection. Cái này phải có code đoạn e set this.traLoi
mới nói rõ được.
1 trong những cách fix phổ biến cho e đó là "wrap" đoạn e set this.traLoi
vào setTimeout với 0
delay là được.
Ví dụ
setTimeout(() => {
this.traLoi = true
}, 0)
hoặc e có thể dùng delay(0)
nếu e đang dùng RxJS. Hoặc tốt hơn nữa nếu như e có thể move đoạn code kia từ ngAfterViewInit
sang ngOnInit
thì ko cần setTimeout hay delay gì cả (nếu e đang dùng ngAfterViewInit
)
this.traLoi
nó được thay đổi khi ấn vào các item khác nhau ạ. Hiện tại nó có 2 loại action thay đổi đến nó
ontTraLoiSelected(item) {
this.traLoi= item;
...
}
resetTraLoiSelected() {
this.traLoi= null;
}
Lỗi chỉ xuất hiện khi diều kiện *ngIf="checkShowExpandedCTTL()"
thay đổi giá trị ạ
Em thử setTimeout nhưng vẫn không được ạ
@hoang55dd oh sorry e, hôm qua a ko nhìn thấy còn 1 cái ngIf
bên dưới.
Sau khi xem code mới của e thì khả năng lỗi lại bị ở đây *ngIf="checkShowExpandedCTTL()"
-> giá trị trả về của checkShowExpandedCTTL()
thay đổi sau khi Angular vừa "check" xong template của e, như lỗi in ra thì tại thời điểm check là false nhưng về sau bị đổi thành true
tức là đoạn này return element.offsetHeight < quillEditor.offsetHeight;
bị thay đổi
bởi vì e đang dùng cả cái method ở ngif nên method đó sẽ bị gọi rất nhiều lần, vì e cần nhớ là ở Angular, mỗi khi có thay đổi ở bất kì đâu trong app của e , thì Change Detection sẽ chạy lại cho toàn bộ application tree (mặc định, trừ khi e dùng OnPush), ý là cái method sẽ bị gọi đi gọi lại rất nhiều. e có thể đặt console.log ở trong đó để kiểm chứng.
Cách a khuyên e là, tạo 1 property mới cho component của e, ví dụ: showExpandedCTTL = false
, ở template đoạn ngIf=checkShowExpandedCTTL()
sửa thành ngIf="showExpandedCTTL"
method của e sửa thành:
checkShowExpandedCTTL(): boolean {
const element: HTMLElement = document.getElementById( 'traLoi');
const quillEditor: HTMLElement = element.querySelector('quill-view-html');
this.showExpandedCTTL = element.offsetHeight < quillEditor.offsetHeight;
}
rồi ở những chỗ nào e set this. traLoi
thì sau đó e gọi thêm this.checkShowExpandedCTTL()
, ví dụ:
ontTraLoiSelected(item) {
this.traLoi= item;
this.checkShowExpandedCTTL()
...
}
Như này sẽ giảm đáng kể việc method checkShowExpandedCTTL bị gọi và sẽ fix đc lỗi
nếu sau khi làm như trên vẫn bị lỗi thì e lại wrap những chỗ gọi
this.checkShowExpandedCTTL()
trong setTimeout, lần này sẽ được thôi
khi code, ngôn ngữ nào cũng vậy, hạn chế dùng tiếng việt nhé e, tập dùng tiếng Anh cho quen: ontTraLoiSelected, traLoi ---> onAnswerSelected, answer
@maitrungduc1410 em fix được rồi ạ. Em cảm ơn anh câu trả lời và lời khuyên của a ♥️
@hoang55dd okie e nhé