简体   繁体   English

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

[英]Angular 4 - Best way to populate child components data

I am using @ViewChild in parent component and the parent component depends on child component properties.我在父组件中使用 @ViewChild 并且父组件取决于子组件属性。 Now the child component gets data from a REST call which is done in ngoninit.现在子组件从ngoninit 中完成的REST 调用中获取数据。 In parent component i have used ngAfterViewInit so that i can get hold of the data of child component, but it seems that ngAfterViewInit gets called when first initialization takes place and any subsequent changes to view are not looked into(Called once after the first ngAfterContentChecked()).在父组件中,我使用了 ngAfterViewInit 以便我可以获取子组件的数据,但是似乎在第一次初始化发生时调用了 ngAfterViewInit,并且不会查看对视图的任何后续更改(在第一个 ngAfterContentChecked( ))。 something like below像下面这样的东西

child Component子组件

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

Parent Component父组件

      @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);
        }
      }

Now the question is现在的问题是

  1. Is there a way to check and wait for child component to be fully rendered?有没有办法检查并等待子组件完全呈现?
  2. Is it better to take care of such scenarios in the parent component, child data load and subsequent logic in parent?在父组件中处理此类场景,子数据加载和父级中的后续逻辑是否更好? But in this way we end up totally duplicating child component data load in all parent components但是这样我们最终会在所有父组件中完全复制子组件数据加载
  3. Is there any better way to do this有没有更好的方法来做到这一点

You should make use of an Output emitter on the child component.您应该在子组件上使用输出发射器。

   @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);
    }

Then in the template for the parent component set the variable.然后在父组件的模板中设置变量。

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

You should move logic like api calls into a service and store your resulting data inside it using a rxjs/Subject or rxjs/BehaviorSubject .您应该将 api 调用之类的逻辑移动到服务中,并使用rxjs/Subjectrxjs/BehaviorSubject将结果数据存储在其中。

Or if you want to go even further store your data in a redux store like @ngrx/store together with @ngrx/effects which has a great performance benefit due to immutable data and the use of ChangeDetectionStrategy.OnPush .或者,如果你想走得更远您的数据存储在Redux的商店像@ NGRX /存储加上@ NGRX /效应由于不可改变的数据和使用具有很大的性能优势ChangeDetectionStrategy.OnPush Also your application state is definitly at any point of time which reduces side effects and improves testability.此外,您的应用程序状态绝对是在任何时间点,这可以减少副作用并提高可测试性。

This will keep your logic away from components and the service can be used in any component which need the shared data.这将使您的逻辑远离组件,并且该服务可以在需要共享数据的任何组件中使用。

More about services to share application data can be found in the tutorial section of the angular docs .有关共享应用程序数据的服务的更多信息,请参见angular 文档的教程部分。

You could probably do it more easily if you let the parent component get the superset of your data.如果让父组件获取数据的超集,您可能会更轻松地做到这一点。 Master-Detail pattern essentially means that your children component just receives the data it needs and the parent component can cache your full data set till you need it. Master-Detail模式本质上意味着您的子组件只接收它需要的数据,而父组件可以缓存您的完整数据集,直到您需要它为止。

To do this you can make the rest call in your parent.为此,您可以在您的父母中拨打其余电话。

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

In your child component you just need to bind.在您的子组件中,您只需要绑定即可。

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

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

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