ngAfterViewInit无法正常工作或我做错了什么

时间:2019-12-17 22:22:15

标签: javascript angular typescript

我的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()来解决。但是我不喜欢。我不喜欢它依赖超时的事实。而且我认为会有更好的解决方案。 有理想吗?谢谢大家。

3 个答案:

答案 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"
      });

    });
  }

stackblitz demo ?

相关问题