我的页面上有一个很大的ngx-bootstrap手风琴。当我打开一些较低的手风琴时,我希望它滚动页面,以便打开的手风琴从窗口顶部开始。我用scrollIntoView实现了滚动部分,但是现在的问题是在正确的时间执行它。我目前正在ngAfterViewChecked中执行此操作,但是多次触发了ViewChecked(mousemove,mouseenter等)。是否只有在DOM完成与angular2 + changeDetection分开的渲染之后才可以触发一段代码?
解决方案
这是开始起作用的解决方案。
constructor(elementRef: ElementRef) {
this.elementRef = elementRef
}
getData(){
this.getService().then(result => {
#do stuff with result
setTimeout(() => this.scrollToBegin());
}).catch((err: any) => {
});
}
scrollToBegin(): any{
this.elementRef.nativeElement.scrollIntoView();
}
答案 0 :(得分:1)
AFAIK,您只有ngAfterViewChecked
和ngAfterViewInit
用于检测dom更新。
根据我的经验,有时您需要在settimeout
内编写用于dom更改的代码,以便为此安排一个宏任务(异步更新),以便您的代码在下一个更改检测周期(即正是您所需要的)。有关更多详细信息,请参见this article
将您的罐子放在块代码末尾的settimeout
内(并将其从ngAfterViewChecked
中删除)。
一些例子:
setTimeout(() => htmlInputElement.focus()); // focus an input
setTimeout(() => htmlElement.scrollIntoView()); // scroll into view
答案 1 :(得分:0)
检查Angular文档中是否有不同的生命周期挂钩。初始化组件视图后,将调用生命周期挂钩。
AfterViewInit()
将按照您的要求执行一次。
在Angular具有后立即调用的回调方法 完成组件视图的初始化。仅被调用 视图被实例化一次。
ngAfterVIewChecked()
在加载组件的视图之后被调用,但是它检测到更改并执行。
答案 2 :(得分:0)
这是一个愚蠢的回应。但是您是否考虑过使用Accordeon随附的自定义事件isOpenChange
:
<accordion-group heading="Group with isOpenChange event listener"
(isOpenChange)="log($event)">
<p>Some content</p>
</accordion-group>
,然后在对应词中:
log(event: boolean) {
console.log(`Accordion has been ${event ? 'opened' : 'closed'}`);
}