问题描述
我有一个主要组件,除其他外,它使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 ngAfterViewInit
have 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挂钩在加载内容时无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!