我制作了以下小程序来显示我的问题。当我使用本地数据填充我的div时,我的largestHeight
方法在正确的时间运行得很好,但是当我使用API数据时,largestHeight
方法运行得太快并且在数据之前完成插入。
这两个组件是整个程序。我在主要组件HTML模板中标记了需要更改的一个变量,以查看两种数据类型之间的差异。 (我试着用这两段代码填充6小时,但最后,我无法让它工作,即使我确信它应该是非常直接的):(
主要组件
import { Component, OnInit, ElementRef, QueryList, ViewChildren, ViewChild, Renderer, AfterViewInit } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/Rx';
export interface IHeadlines {
userId: number;
id: string;
title: string;}
export interface GroupPosts {
title: string;
posts: IHeadlines[];}
@Component({
selector: 'test-main3',
template: `
<div id="main_container" #main_container>
<div id="one" #containers>
<test-child3 [data]="localdata"></test-child3> <!-- Change "localdata" to "apidata" to see the difference -->
</div>
<div id="two" #containers>
***** <br>
*****
</div>
</div>
`,
styles: [`
#main_container {
background-color: #cc66ff;
height:100px;
}
#one {
background-color: #669966;
position:absolute;
margin-left: 33.5%;
}
#two {
background-color: #ff99cc;
position:absolute;
margin-left: 5%;
}
`],
})
export class Main3Component implements OnInit {
@ViewChildren('containers', {read: ElementRef})
public divs: QueryList<ElementRef>
@ViewChild('main_container')
public mainContainerRef: ElementRef;
apidata: IHeadlines[];
localdata = [
{ id: 'text1', title: 'up' },
{ id: 'text2', title: 'down' },
{ id: 'text3', title: 'down' },
{ id: 'text4', title: 'up' },
{ id: 'text5', title: 'down' },
{ id: 'text6', title: 'up' },
{ id: 'text7', title: 'up' },
{ id: 'text8', title: 'down' },
{ id: 'text9', title: 'up' },
{ id: 'text10', title: 'down' }
];
constructor(private _http: Http, private _renderer:Renderer) { }
getPosts() {
const url = 'https://jsonplaceholder.typicode.com/albums';
return this._http.get(url)
.map(x => x.json());
}
ngOnInit() {
this.getPosts()
.subscribe(x => this.apidata = x);
}
ngAfterViewInit() {
this.largestHeight();
}
largestHeight() {
console.log("Parent ngAfterViewInit");
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 + 40 + 'px');
this.divs.forEach((names) => {
this._renderer.setElementStyle(names.nativeElement, 'height', largestHeight + 'px');
console.log(largestHeight);
});
}
}
子组件
import { Component, OnInit, Input, SimpleChanges } from '@angular/core';
import { IHeadlines, GroupPosts } from '../main3.component';
@Component({
selector: 'test-child3',
template: `
<div *ngFor="let headlines of data">
{{headlines.id}} {{headlines.title}} <br>
</div>
`,
styles: ['div {color: white;}']
})
export class Child3Component implements OnInit {
@Input() data: IHeadlines[];
groupPosts: GroupPosts[];
constructor() { }
ngOnInit() {
}
ngOnChanges(changes: SimpleChanges) {
if (changes['data']) {
this.groupPosts = this.groupByCategory(this.data);
}
}
groupByCategory(data: IHeadlines[]): GroupPosts[] {
if (!data) return
const categories = new Set(data.map(x => x.title));
const result = Array.from(categories).map(x => ({
title: x,
posts: data.filter(post => post.title === x)
}));
return result;
}
}
感谢任何人试图提供帮助!
答案 0 :(得分:2)
我猜你需要在渲染元素后调用largestHeight
函数。
你可以这样解决:
import 'rxjs/add/operator/first';
...
constructor(private ngZone: NgZone) { }
ngOnInit() {
this.getPosts()
.subscribe(x => {
this.apidata = x;
this.ngZone.onMicrotaskEmpty.first().subscribe(() => {
this.largestHeight();
});
});
}
<强> Plunker Example 强>