Angular 4 - 填充子组件数据的最佳方法

时间:2018-02-19 23:55:22

标签: angular

我在父组件中使用@ViewChild,而父组件依赖于子组件属性。现在,子组件从REST调用中获取数据,该调用在ngoninit中完成。在父组件中我使用了ngAfterViewInit以便我可以获取子组件的数据,但似乎在第一次初始化发生时调用ngAfterViewInit并且不查看对视图的任何后续更改(在第一次ngAfterContentChecked之后调用一次( ))。类似下面的内容

子组件

    @Component({
      selector: "academicyear-detail",
    }) 
    export class AcademicYearDetail  {
     currentYear: string;
     ngOnInit() {
        //do a rest call
        //assign when data arrives
        currentYear = data.currentAcademicYear;
    }

父组件

       @Component({
         selector: "testProject",
         templateUrl: "app/partials/Main.html",
         directives: [AcademicYearDetail] 
       })
      export class AppComponent { 
         @ViewChild(AcademicYearDetail) acadYearDetail:AcademicYearDetail;
         ngAfterViewInit() {
         this.getChildProperty();
      }
      getChildProperty() {
        console.log(this.acadYearDetail.currentYear);
      }
   }

现在的问题是

  1. 有没有办法检查并等待子组件完全呈现?
  2. 在父组件child中处理此类方案是否更好? 父数据加载和后续逻辑?但通过这种方式我们完全结束了 在所有父组件中复制子组件数据负载
  3. 有没有更好的方法呢

3 个答案:

答案 0 :(得分:1)

您应该在子组件上使用输出发射器。

   @Component({
      selector: "academicyear-detail",
    }) 
    export class AcademicYearDetail  {

     @Ouput()
     currentYear = new EventEmitter<string>();

     currentYear: string;
     ngOnInit() {
        //do a rest call
        //assign when data arrives
        this.currentYear.emit(currentAcademicYear);
    }

然后在父组件的模板中设置变量。

<academicyear-detail (currentYear)="acadYearDetail.currentYear = $event"></academicyear-detail>

答案 1 :(得分:1)

您应该将api调用之类的逻辑移动到服务中,并使用rxjs/Subjectrxjs/BehaviorSubject将结果数据存储在其中。

或者,如果您想进一步将您的数据存储在 @ngrx/store 等redux商店以及 @ngrx/effects ,其效果非常好由于不可变数据和使用 ChangeDetectionStrategy.OnPush 而受益。此外,您的应用状态绝对可以在任何时间点降低副作用并提高可测试性。

这将使您的逻辑远离组件,并且该服务可用于任何需要共享数据的组件。

有关共享应用程序数据的服务的更多信息,请参阅angular docs的教程部分。

答案 2 :(得分:0)

如果让父组件获取数据的超集,则可以更轻松地执行此操作。 Master-Detail模式实质上意味着您的子组件只接收所需的数据,父组件可以缓存您的完整数据集,直到您需要它为止。

要执行此操作,您可以在父母中进行休息。

@Component({
         selector: "testProject",
         templateUrl: "app/partials/Main.html",
         directives: [AcademicYearDetail] 
       })
export class AppComponent { 
  constructor(private http: HttpClient) { }
  ngOnInit() {
     //do a get for everything
  }      
}

在您的子组件中,您只需要绑定。

 @Component({
      selector: "academicyear-detail",
    }) 
    export class AcademicYearDetail  {
     currentYear: string;
     @Input() data;
     ngOnChanges() {
      //bind data to be used where ever in child.
    }