我正在尝试访问scrollHeight
元素上的clientHeight
和<div>
属性,以决定是否显示“查看更多”链接:
<div #clippedContainer class="clipped">
<some-other-component></some-other-component>
<a class="view-more" href="...">View more</a>
</div>
.clipped {
max-height: 600px;
overflow: hidden;
position: relative;
}
.view-more {
position: absolute;
width: 100%;
top: 550px;
text-align: center;
display: none;
.displayed {
display: block;
}
}
@ViewChild('clippedContainer', read: Element)
set clippedContainer(Element container) {
if (container.scrollHeight > container.clientHeight) {
container.querySelector('.learn-more').classes.add('displayed');
}
}
问题在于调用时scrollHeight为0,因为尚未显示组件。我尝试在scheduleMicrotask
和ngAfterViewInit
中读取它,但是它仍然为0。我发现了一个hack,它等待一秒钟,让浏览器计算布局然后访问所需的属性:
Future.delayed(Duration(seconds: 1)).then(() {
if (container.scrollHeight > container.clientHeight) {
container.querySelector('.learn-more').classes.add('displayed');
}
});
,但是这会在呈现的内容和链接出现之间引入不必要的延迟。有没有更好的方法来检测何时已计算布局并且scrollHeight
和clientHeight
可用?
更新:我发现问题的部分原因是包含<div>
的组件是由弹出框架动态构建的。看来ngAfterViewInit
之类的钩子甚至在组件连接到DOM之前就已执行。
答案 0 :(得分:0)
我发现了一种检测组件何时连接到DOM的方法,但是我并不喜欢这种方法,因为它非常复杂。希望有人能提出更好的解决方案。
class MyComponent {
final NgZone _ngZone;
final Element _hostElement;
MyComponent(this._ngZone, this._hostElement);
@ViewChild('clippedContainer', read: Element)
Element container;
void ngAfterViewInit() {
final sub = _ngZone.onTurnStart.listen((_) {
if (_hostElement.parent == null) return;
sub.cancel();
if (container.scrollHeight > container.clientHeight) {
container.querySelector('.learn-more').classes.add('displayed');
}
});
}
}