【发布时间】:2020-04-03 21:02:57
【问题描述】:
我的应用程序有两个父组件 A 和 B,每个组件都在自己的模块中(分别是模块 A 和 B)。组件 A 包括来自其自身模块(模块 C)的子组件 C。组件 B 包括子组件 C(来自模块 C)和来自模块 B 的子组件 B1。各种父/子组件之间的所有交互和行为都运行良好。我遇到的问题是试图让组件 (B1) 将元素 (elemOfInterest) 滚动到视口顶部,以响应组件 C 通过数据共享服务发出的标志 (flagA)。
当我从组件 A 的模板单击子组件 C 的表单提交按钮时,我被路由到组件 B。但是子组件 B1 中的 scrollToView 在没有 setTimeout 的情况下不起作用。一旦组件 B1 的 ngOnInit 生命周期被触发,单击组件 C 的表单提交按钮(这次来自组件 B 的模板)会导致 scrollToView 方法在没有 setTimeout 的情况下工作得非常好。我无法弄清楚为什么 ngOnInit 会干扰组件 B1 中的 scrollToView。这是我的代码:
ComponentC.component.ts:
export class ComponentC implements OnInit {
constructor(private dataSharing: DataSharingService) {}
ngOnInit() {
doSomething(){
this.dataSharing.transferData({'data':{'flagA':true}});
}
}
}
ComponentC.component.html:
<form class="mx-auto" [formGroup]="searchForm" (ngSubmit)="doSomething()">
<div> … </div>
<div> <button type="submit">Submit</button> </div>
</form>
ComponentB1.component.ts
export class ComponentB1 implements OnDestroy, OnInit {
subscriptions: Subscription = new Subscription();
constructor(private dataSharing: DataSharingService) {}
ngOnInit() {
this.subscriptions.add(
this.dataSharing.outgoingData$.subscribe(data => {
this.onSharedData(data);
})
)
}
onSharedData(data) {
if (Object.keys(data).length && Object.keys(data['data']).length) {
switch (true) {
case data['data']['flagA']:
this.func1();
break;
case data['data']['flagB']:
this.func2();
break;
}
}
}
ngOnDestroy() {this.subscriptions.unsubscribe()}
func1(){
//do something simple, like set html element values, etc.
setTimeout(()=>document.getElementById('elemOfInterest').scrollIntoView({behavior: 'smooth', block: 'start', inline: 'nearest'}));
}
}
数据共享服务代码:
import { Injectable } from '@angular/core';
import { Observable, ReplaySubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class DataSharingService {
outgoingData$ = new ReplaySubject(1);
constructor() {}
transferData(incomingData: object){
this.outgoingData$.next(incomingData);
}
}
为了它的价值,我也尝试过使用 jquery
$('html, body').animate({ scrollTop: $('#elemOfInterest).offset().top }, 'slow')
而不是 scrollToView 但在组件 B1 首次启动时仍需要 setTimeout 才能使滚动正常工作。知道如何在不使用 setTimeout 的情况下完成滚动行为吗?
【问题讨论】:
标签: javascript scroll angular7 settimeout