[英]Angular 2 how to make child component wait for async data to be ready
I'm passing async data from a parent component to a child component.我正在将异步数据从父组件传递给子组件。 And the child component needs to know the length of the data in order to do something.
并且子组件需要知道数据的长度才能执行某些操作。
How the problem is that the child component can't use the 'Oninit' hook to do work because the data isn't available at this time.问题是子组件无法使用“Oninit”钩子来工作,因为此时数据不可用。 So how do I do this?
那么我该怎么做呢?
The parent component code looks like:父组件代码如下所示:
@Component({
moduleId: module.id,
selector: 'parent',
template: `<div>
<child [items]="items | async">
</div>`
})
export class Parent implements OnInit {
items: Items[];
constructor(
private itemService: ItemService,
private router: Router
) { }
ngOnInit() {
this.itemService.getItemss()
.subscribe(
items => this.items = items,
error => this.errorMessage = <any>error
);
}
}
And the child component looks like:子组件看起来像:
@Component({
moduleId: module.id,
selector: 'child',
template: `<div>
<div *ngFor="let itemChunk of itemChunks"></div>
content here
</div>`
})
export class child implements OnInit{
@Input() items: Items[];
itemChunks: Items[][];
ngOnInit() {
this.itemChunks = this.chunk(this.Items);
}
chunk(items: Items[]) {
let result = [];
for (var i = 0, len = items.length; i < len; i += 6) { // this line causes the problem since 'items' is undefined
result.push(items.slice(i, i + 6));
}
return result;
}
}
What is the best practice to handle this?处理这个问题的最佳做法是什么?
There are three ways to do this:有三种方法可以做到这一点:
*ngIf
in parent.*ngIf
中放置一个*ngIf
。 Only render child when parent's items
is ready.items
准备就绪时渲染子items
。<div *ngIf="items">
<child [items]="items | async">
</div>
getter
setter
in child.getter
setter
。 Then act whenever the value is set, you can use RxJS BehaviorSubject
also.BehaviorSubject
。private _items = new BehaviorSubject<Items[]>([]);
@Input() set items(value: Items[]) {
this._items.next(value);
}
get items() {
return this._items.getValue();
}
ngOnInit() {
this._items.subscribe(x => {
this.chunk(x);
})
}
ngOnChanges
of the child.ngOnChanges
期间执行此ngOnChanges
。 Refer to here for example.Simpler solution:更简单的解决方案:
ngOnChanges(changes: SimpleChanges) {
if (changes['items'].currentValue) {
this.items = items
}
}
You can use a setter :您可以使用 setter :
export class child implements OnInit{
itemChunks: Items[][];
private _items ;
//bellow will get called when ever the items are passed in by the parent component
@Input( 'items' ) set items ( items: Items[] ) {
this._items = items;
this.itemChunks = this.chunk(this._items);
}
chunk(items: Items[]) {
let result = [];
for (var i = 0, len = items.length; i < len; i += 6) { // this line causes the problem since 'items' is undefined
result.push(items.slice(i, i + 6));
}
return result;
}
}
Any by the way, I feel like your parent component is not right as well, it should be :顺便说一句,我觉得你的父组件也不对,应该是:
@Component({
moduleId: module.id,
selector: 'parent',
template: `<div>
<child [items]="items | async">
</div>`
})
export class Parent implements OnInit {
items: Items[];
constructor(
private itemService: ItemService,
private router: Router
) {
this.items = this.itemService.getItemss(); // if getItemss is returning an observable, which I think it does
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.