我的ngAfterViewInit函数无法正常工作。我感觉我在这里想念什么。
ngOnInit() {
this.dataService.getUsers().subscribe((users) => {this.users = users) ;
}
ngAfterViewInit() {
if (document.getElementById('target')) {
document.getElementById('target').scrollIntoView({
behavior: 'auto',
block: 'center',
inline: 'center',
});
}
基本上,在视图加载完成后,我使用ngAfterViewInint()
函数滚动到当前项目。在ngOnInit()
内,如果我不调用subscribe()
并在其中放置一个变量。它工作正常。但是,并非我要问的那样。
我可以通过在setTimeOut()
内使用ngAfterViewInit()
来解决。但是我不喜欢。我不喜欢它依赖超时的事实。而且我认为会有更好的解决方案。
有理想吗?谢谢大家。
答案 0 :(得分:2)
看起来您的代码取决于调用dataService.getUsers()
之前返回的ngAfterViewInit()
调用吗?
如果是这样,那就行不通了,因为无法保证时间。 而是这样做:
ngAfterViewInit() {
this.dataService.getUsers().subscribe((users) => {
this.users = users;
this.scrollTargetIntoView();
)};
}
scrollTargetIntoView() {
if (document.getElementById('target')) {
document.getElementById('target').scrollIntoView({
behavior: 'auto',
block: 'center',
inline: 'center',
});
}
即使这可能还为时过早-您可能希望为此添加setTimeout(),以便为DOM提供呈现的机会,例如:
ngAfterViewInit() {
this.dataService.getUsers().subscribe((users) => {
this.users = users;
setTimeout(() => this.scrollTargetIntoView());
)};
}
scrollTargetIntoView() {
if (document.getElementById('target')) {
document.getElementById('target').scrollIntoView({
behavior: 'auto',
block: 'center',
inline: 'center',
});
}
答案 1 :(得分:1)
如果您的Angular应用程序具有路由功能,那么您可以查看的另一个选项是Route Resolvers,它可以在导航到特定路由之前预取组件的数据。这样,您的UI将具有在...
生命周期挂钩中呈现所需的所有必要数据。
您可以使用以下代码创建解析器服务:
ngOnInit()
然后在路由定义中,您可以使用以下方法激活解析器:
@Injectable()
export class UserResolverService implements Resolve<Observable<User[]>> {
constructor(private dataService: DataService) {}
resolve() {
return this.dataService.getUsers()
}
}
最后,在组件const routes: Routes = [
{
path: 'my_path',
component: MyComponent,
resolve: {
users: UserResolverService
}
}
];
生命周期挂钩中,可以使用以下代码使用数据:
ngOnInit()
答案 2 :(得分:0)
一个更好的解决方案是使用ViewChildren
装饰器,因为您可以订阅视图的更改,这意味着您不需要使用setTimeOut
@ViewChildren("target") target: QueryList<ElementRef>;
ngOnInit() {
this.dataService.getUsers().subscribe((users) => {this.users = users) ;
}
ngAfterViewInit() {
this.target.changes.subscribe(({ first: elm }) => {
elm.nativeElement.scrollIntoView({
behavior: "auto",
block: "center",
inline: "center"
});
});
}