Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 2:智能组件向表示组件传递数据_Angular - Fatal编程技术网

Angular 2:智能组件向表示组件传递数据

Angular 2:智能组件向表示组件传递数据,angular,Angular,我已经设置了一个智能组件,ngOnInit使用服务调用restapi来获取数据对象 该数据通过@Input()属性传递到表示(子)组件 在演示组件中,我需要将数据重新打包到一个不同的模型中,以便它适合我用于演示的第三方组件 我不知道如何处理这样一个事实:在PresentationIn组件的ngOnInit中,传入的@Input属性仍然是未定义的。由于实际数据是Rest API调用,因此父(智能)组件将仅在订阅的观察者中获取它,即异步获取 如何将其连接在一起,使我不会试图操纵一个未定义的对象,而是

我已经设置了一个智能组件,
ngOnInit
使用服务调用restapi来获取数据对象

该数据通过
@Input()
属性传递到表示(子)组件

在演示组件中,我需要将数据重新打包到一个不同的模型中,以便它适合我用于演示的第三方组件

我不知道如何处理这样一个事实:在PresentationIn组件的
ngOnInit
中,传入的
@Input
属性仍然是
未定义的
。由于实际数据是Rest API调用,因此父(智能)组件将仅在
订阅
的观察者中获取它,即异步获取

如何将其连接在一起,使我不会试图操纵一个未定义的对象,而是等到它实际存在于表示组件中


我想,我总是可以通过
@ViewChild
将演示组件链接到智能父组件,然后在演示组件上引入一个公共方法,如
showData(data)
,但我想知道这里的最佳做法是什么。

实际上在线上已经有很多答案了。看看

我回顾了你的案例,虽然不知道你到底在做什么很难理解。我通过在智能组件中初始化变量解决了这个问题:

private apiData: Array = [];
在我的模板中使用*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
}
@Input('apiData')apiData:;
ngOnInit():void{
这个是repack();
}
重新打包():void{
//这是防止错误的部分
如果(!this.apiData)返回;
//在这里重新打包逻辑
}

但是@ThinkingMedia answer在您的情况下可能更正确。

在子组件中,您必须侦听输入的更改。一旦
数据
输入发生更改并有数据。然后可以将其重新打包到另一个属性中

在本例中,输入的
数据
被分配给
重新打包
。请注意模板中的
*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
       }
   }
}
@组件({
选择器:'子',
坦帕尔特:''
})
导出类ChildComponent实现OnChanges{
@输入()
公共数据:对象;
公共重新打包:对象;
公共更改(更改:SimpleChanges):无效{
if(变更中的“数据”){
重新打包(更改['data'].currentValue);
}
}
私有重新打包(数据:对象){
如果(数据){

this.repacked=data;//,使用ngOnChanges代替。你能提供你的代码吗?似乎你的设置与我的不同。@DeborahK这会比使用@ViewChild好吗?出于某种原因,我认为该方法在浏览器中的任何事件上都会触发…它不会。但是,我仍然必须在其中放入
if
语句以确保这是正确的属性。很好奇这里的最佳实践是什么。这个场景是ngOnChanges生命周期挂钩的全部目的。从上面链接中提供的文档中可以看出:“Angular在检测到组件(或指令)的输入属性发生更改时调用其ngOnChanges()方法。”因此,它在生活中的目的是等待数据被设置,然后做出相应的反应。是的,如果可以初始化该值,您仍然需要一个if语句。这不会起作用。在调用repack()时,您的
apiData
)是
未定义的
,并且由于检查而不会执行任何操作。此后它不会神奇地再次调用
重新打包