简体   繁体   中英

Angular 2: Child component doesn't initializes again once parent component gets data from service

I have two components: Component A and Component B, where Comp B named "filter" is the Child of Comp A.

They are based on the activated route where they fetch the changes in URL and sends the call to the server and get the latest "filterMap " from it.

Component_A.html

<section class="abc"> 
  <filter [filterMap]=[filterMap]></filter>
  <div *ngFor="let item of courses">
    <!-- code -->
  </div> 
</section>

Component_A.ts

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { Subscription } from 'rxjs';

@Component({
    selector: 'component-a',
    templateUrl: '../template/component-a.html'
})

export class ComponentAComponent implements OnInit, OnDestroy {
constructor(private _activatedRoute: ActivatedRoute,
            private _router: Router) { }

ngOnInit() {
        this._querySubscription = this._activatedRoute.queryParams
            .subscribe(params => {
                    this.setQueryParams(params);
                    this._courseService.getData()
                        .subscribe(res => {
                            if (res.data) {
                                this.courses = res.data.courseDTOList;
                                this.filterMap = res.data.filterMap;
                            }

                        });                
            });
    }
}

Component_B.html

<div class="xyz">
  <span> Filter Result </span>
  <section class="filter-section" *ngFor='let filter of filterData>
    <!-- Code -->
  </section>
</div>

Component_B.ts

import { Component, Input, Output, EventEmitter, OnInit, AfterViewInit } from "@angular/core";
import { Router, ActivatedRoute } from '@angular/router';
import { Subscription } from 'rxjs';

@Component({
    selector: 'filter',
    templateUrl: '../template/course-filter.html'
})

export class FilterComponent implements OnInit{

@Input() filterMap: any;

ngOnInit() {
        if (this.filterMap[0])
            this.filterData = this.filterMap[0];
    }
}

Problem :

Once the page is reloaded, both the components get initialized and provide the desired output.

If URL gets changed, the call to the server is sent and filterMap comes from service but Component_B doesn't get initialized again and the filter screen remains with the old data every time.

This is the expected behavior, by default, angular reuse components if the parameters of the route change but the route in itself does not.

For example with a route like route/:id , if the user navigates from route/1 to route/2 , angular will reuse the same component.

This is a default behavior that can be overriden by implementing your own RouteReuseStrategy . You can check this to get more informations about this approach.

In your case, defining your filterMap inside Component B during change detection instead of on init should be sufficient :

@Component({
  selector: 'filter',
  templateUrl: '../template/course-filter.html'
})

export class FilterComponent implements OnChanges {

  @Input() filterMap: any;

  ngOnChanges() {
    if (this.filterMap && this.filterMap[0])
      this.filterData = this.filterMap[0];
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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