简体   繁体   English

角度2:将数据传递到Presentation组件的智能组件

[英]Angular 2: Smart component passing in data to Presentation component

I have set up where I have a smart component that ngOnInit uses a service to call out to a Rest API to fetch an object of data. 我在这里设置了一个智能组件, ngOnInit使用该组件调用服务来调用Rest API来获取数据对象。

That data is passed into the presentation (child) component through an @Input() property. 该数据通过@Input()属性传递到表示(子)组件中。

In the presentation component, I need to repack the data into a bit of a different model so that it fits into the 3rd party component I am using for presentation. 在演示组件中,我需要将数据重新打包为其他模型,以使其适合我用于演示的第三方组件。

I am not 100% how to deal with that fact that in the ngOnInit of the presentatioin component, the passed in @Input property is still undefined . 我不是100%如何处理在presentatioin组件的ngOnInit中传入的@Input属性仍然undefined @Input Since the actual data is a Rest API call, the parent (smart) component will only get it in the subscribe 's observer, ie, asynchronously. 由于实际数据是对Rest API的调用,因此父(智能)组件将仅在subscribe的观察器中(即,异步地)获取它。

How do I hook this up together such that I am not trying to manipulate an undefined object, but wait until it's actually there in the presentation component? 如何将其连接在一起,以使我不试图操纵undefined对象,而是等到它在演示组件中真正存在为止?

I guess, I can always link the presentation component to the smart parent component through @ViewChild and then introduce a public method on the presentation component like showData(data) , but I am wondering what the best practice is here. 我猜想,我总是可以通过@ViewChild将表示组件链接到智能父组件,然后在表示组件上引入一个公共方法,如showData(data) ,但是我想知道这里的最佳实践是什么。

In the child component you have to listen for changes to the input. 在子组件中,您必须侦听输入的更改。 Once the data input has changed and has data. 一旦data输入已更改并具有数据。 You can then repack it into another property. 然后,您可以将其重新打包到另一个属性中。

In this example the input data gets assigned to repacked . 在此示例中,输入data被分配给repacked Notice the *ngIf in the template to prevent the use of the third party stuff until the data is ready. 注意模板中的*ngIf ,以防止在数据准备好之前使用第三方的东西。

@Component({
    selector: 'child',
    tempalte: '<div *ngIf="repacked"><!-- third-party stuff --></div>'
})
export class ChildComponent implements OnChanges {
   @Input()
   public data: Object;

   public repacked: Object;

   public ngChanges(changes: SimpleChanges): void {
      if('data' in changes) {
           this.repack(changes['data'].currentValue);
      }
   }

   private repack(data: Object) {
       if(data) {
          this.repacked = data; // <-- do repacking work here
       }
   }
}

There is actually quite some answers online for this already. 实际上已经有很多在线答案。 Have a look at https://scotch.io/tutorials/3-ways-to-pass-async-data-to-angular-2-child-components 看看https://scotch.io/tutorials/3-ways-to-pass-async-data-to-angular-2-child-components

I reviewed your case and although it's hard to understand without knowing exactly what you do. 我审查了您的案件,尽管很难确切知道您的所作所为。 I solved this by initializing my variable in the Smart Component: 我通过在智能组件中初始化变量来解决此问题:

private apiData: Array = [];

Using *ngIf in my template, and then repacking the data in the child if I have the data: 在我的模板中使用* ngIf,如果有数据,则在子级中重新打包数据:

@Input('apiData') apiData: <any>;

ngOnInit(): void {
    this.repack();
}

repack(): void {
    // here is the part that prevents errors
    if(! this.apiData) return;

    // repack logic here
}

However @ThinkingMedia answer is likely the more correct one in your case. 但是,在您的情况下,@ ThinkingMedia答案可能是更正确的答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM