Lifecycle挂钩在加载内容时无法正常工作

Lifecycle挂钩在加载内容时无法正常工作

本文介绍了Angular2 Lifecycle挂钩在加载内容时无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个主要组件,除其他外,它使div彼此相邻并具有position:absolute.我编写了一个脚本,该脚本可测量div中的内容并将所有div扩展到最高div的高度,以使它们的高度相同.该脚本使用 ngAfterViewInit 运行.但是在测试中,我总是在子组件中放入随机内容,现在我使用"get" api请求加载内容.但是问题是,在我看来api请求花费的时间太长,到那时父 ngAfterViewInit 已经被触发,看到没有内容,使得div的尺寸变得非常小,并且然后会加载内容,但您只会看到第一行,因为剩下的部分是看到主div没有拉伸到正确的高度而被剪掉的.

I have a main component that renders among other things divs next to one other that has position:absolute. I have written a script that measures the content in the divs and expands all the divs to the height of the highest div so that all of them are the same height. The script runs with ngAfterViewInit. But in testing I always put in random content in the child component, and now I load content with a "get" api request. But the problem is that it seems to me that the api request takes too long, and by then the parent ngAfterViewInithave already fired, sees there is no content, makes the size of the divs extremely small, and then the content loads, but you only see the first line because the rest are cut of seeing that the main div is not stretched to the right height.

我的应用基本如下:

父组件

ngAfterViewInit() {
   Works out how high the divs must be and sets the height in the css.
}

子组件

ngOnInit() {
   Gets the data using a get api request form the server.
}

我曾尝试将 ngAfterViewInit 更改为没有任何作用的 onChanges 钩子,还有其他一些事情,但是我觉得我必须做一些小改动仅在所有内容加载完毕后,使 ngAfterViewInit 检查子组件的高度.

I have tried changing the ngAfterViewInit to a onChanges hook which did nothing, and a few other things, but I feel that there must be some small change that I can do to make the ngAfterViewInit check the height of the child components only after all the content have loaded.

更新

我记录了每个组件以查看发生的情况:

I logged every component to see what is happening:

Parent ngOnInit
child ngOnInit
child ngOnInit
child ngOnInit
child ngOnInit
child ngOnInit
child ngOnInit
child ngOnInit
Parent ngAfterViewInit
lang.js:137 Angular is running in the development mode. Call enableProdMode() to enable the production mode.
Set
Set
Set
Set
Set
Set
Set

UPDATE2

这是我的函数,计算每个div的高度,并将该值应用于主div.

Here is my function working out the height of each div, and applying the value to the main div.

父项

largestHeight() {
    let largestHeight = this.divs.reduce((topHeight, divValue) => {
        let currentDiv = divValue.nativeElement.getBoundingClientRect();
        return (currentDiv.height > topHeight ? currentDiv.height : topHeight);
     }, 0);
    this._renderer.setElementStyle(this.mainContainerRef.nativeElement, 'height', largestHeight + 80 + 'px');
    this.divs.forEach((names) => {
    this._renderer.setElementStyle(names.nativeElement, 'height', largestHeight + 'px');
    console.log(largestHeight);
    });
   }

在这里,我在Subscribe方法的回调中使用该函数

Here I use the function in the callback of the subscribe method

ngAfterViewInit() {
      this._httpService.getPostsByBlogger()
            .subscribe(x => this.posts = x,
                error => console.log("Error: ", error),
                () => this.largestHeight());
   }

子组件

ngOnChanges(changes: SimpleChanges) {
    console.log("child ngOnChanges");
          if (changes['data']) {
              this.groupPosts = this.groupByCategory(this.data);
          }

      }

    groupByCategory(data: DB[]): GroupPosts[] {
        if (!data) return

        const categories = new Set(data.map(x => x.Leaning));
        console.dir(categories);
                const result = Array.from(categories).map(x => ({
            Leaning: x,
            posts: data.filter(post => post.Leaning === x)
        }));

        return result;

简化的HTML结构

<div id="parent"> //this div has css position:absolute, so it does not contract or expand as data is inserted
  <div id="child"> //this div is normal, and gets the data (that is also sorted).
  </div> // The parent div gets it's size form the child div, but now the parent div gets the size before the child div is rendered.
</div>

推荐答案

在以下链接的后续问题中给出了答案:

The answer was given in a follow-up question at this link: Angular2 lifecycle hook working on local data, but not api data

但是简而言之,需要将 ngAfterViewInit 钩子更改为在渲染所有元素之后调用"largestHeight".

But in short the ngAfterViewInit hook needed to be changed to calling the `largestHeight' after all elements were rendered.

import 'rxjs/add/operator/first';
...
constructor(private ngZone: NgZone) { }

ngOnInit() {
   this.getPosts()
     .subscribe(x => {
        this.apidata = x;
        this.ngZone.onMicrotaskEmpty.first().subscribe(() => {
          this.largestHeight();
        });
      });
}

这篇关于Angular2 Lifecycle挂钩在加载内容时无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!