简体   繁体   English

Angular 2 如何让子组件等待异步数据准备就绪

[英]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:有三种方法可以做到这一点:

  1. Put an *ngIf in parent.在父*ngIf中放置一个*ngIf Only render child when parent's items is ready.仅在父items准备就绪时渲染子items
<div *ngIf="items">
   <child [items]="items | async">
</div>
  1. Separate your input getter setter in child.在 child 中分离您的输入getter setter Then act whenever the value is set, you can use RxJS BehaviorSubject also.然后在设置值时采取行动,您也可以使用 RxJS 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);
    })
}
  1. Do it during the ngOnChanges of the child.在孩子的ngOnChanges期间执行此ngOnChanges Refer to here for example.例如,请参阅此处。 https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html#!#onchanges https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html#!#onchanges

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.

相关问题 如何让组件等待来自服务的异步数据 - How do I make a component wait for async data from service Angular5-如何将ASYNC数据从父组件传递到子组件 - Angular5 - How to pass ASYNC data from parent to child component 如何将异步数据作为对象数组传递给子组件-angular 6 - How to pass async data as a Array of Objects to child component - angular 6 如何将角度异步数据绑定到子组件输入属性 - How to bind angular async data to child component input property Angular2 - 将ASYNC数据传递给子组件 - Angular2 - pass ASYNC data to child component Angular 2检查子组件是否准备就绪 - Angular 2 check if child component is ready 我如何让 function 等到另一个异步 function 在 angular 准备好? - Ho do I make function wait until another async function is ready in angular? Angular - 接收@Input 时,如何在执行@Input 逻辑之前等待子组件中的其他异步数据 - Angular - When receiving @Input, how to wait for other async data in the children component before executing the @Input logic Angular,使用ngIf,异步和Observable等麻烦,等到数据准备好显示内容 - Angular, trouble using ngIf, async and Observable to wait until data is ready to display content 如何在Angular 5中使组件侦听并等待来自另一个组件的数据而没有事件? - How to make a component listen and wait for data from another component without an event in Angular 5?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM