【问题标题】:Is there any way I can pass dynamic data to a component in Angular?有什么方法可以将动态数据传递给 Angular 中的组件?
【发布时间】:2017-12-08 23:09:27
【问题描述】:

我正在尝试将动态数据传递给子组件。但我总是在子组件中得到未定义的数据。下面是我正在做的事情。

父组件.ts

results: any[];
ngOnInit() {
this.http.get('url').subscribe(data => this.results = data);
}

父组件.html

<app-childComponent [dataNeeded]=results></app-childComponent>

ChildComponent.ts

@Input('dataNeeded') dataNeeded: any[];
ngOnInit() {
 console.log(dataNeeded); //Always undefiend
}

正如预期的那样,它不会等待异步调用并返回未定义的我。如何将动态数据传递给组件?

【问题讨论】:

    标签: angular typescript


    【解决方案1】:

    你可以试试OnChanges生命周期钩子方法。

    在您的情况下,您需要像这样将它添加到您的子组件中:

    ngOnChanges(changes) {
      if (changes['dataNeeded'] && this.dataNeeded) {
        console.log(this.dataNeeded);
      }
    }
    

    PS 另外我刚刚注意到您的ChildComponent.ts 中的语法错误,它缺少this

    ngOnInit() {
     console.log(this.dataNeeded);
    }
    

    【讨论】:

    • 它对我有用。我需要在选择主记录时显示详细记录。
    【解决方案2】:

    问题是 UI 线程会在从 observable 订阅完成之前渲染子组件。

    你需要这样做:

    import { ChangeDetectorRef } from '@angular/core';
    
    constructor(private ref: ChangeDetectorRef) {}
    ngOnInit() {
       this.http.get('url').subscribe(data => { 
         this.results = data;
         this.ref.markForCheck();
       });
    }
    

    在 HTML 中,您必须先测试该值。

    <ng-container *ngIf="results != null">
        <app-childComponent [dataNeeded]=results></app-childComponent>
    </ng-container>
    

    稍微描述一下,.markForCheck() 会在订阅后刷新结果,并通知所有正在使用这个“值”的组件来更新它的值,包括 ng-container。容器现在将允许渲染子组件,这将保证当子组件将经历其生命周期时结果不为空。

    【讨论】:

      【解决方案3】:

      如果您确定您的服务成功获得data,那么这将起作用:

      在父组件的 html 中添加引号:

      <app-childComponent [dataNeeded]="results"></app-childComponent>
      

      在您的子组件中,您将使用 OnCh 检查您的Input的更改:

      ngOnChanges(changes: SimpleChanges) {   
         for (let propName in changes) {
            // when your @Input value is changed  
            if(propName === "dataNeeded"){
                console.log(dataNeeded);
            }
         }
      }
      

      希望这会有所帮助:)

      【讨论】:

        【解决方案4】:

        为什么不将 Observable 与异步管道一起使用。 如果要控制台记录该值,请使用 setter。 异步管道也会处理取消订阅。

        results: Observable<any[]>;
        ngOnInit() {
          this.results = this.http.get('url');
        }
        

        在 HTML 中

        <app-childComponent [dataNeeded]="results | async"></app-childComponent>
        

        在你的子组件中

        @Input('dataNeeded') 
        set dataNeeded(val: any[]) {
          console.log(val);
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-06-15
          • 2017-01-07
          • 2015-12-01
          • 1970-01-01
          • 2020-05-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多