Matt Westlake
Matt Westlake

Reputation: 3651

How do you trigger change detection in a different component?

When I add/remove matches from the tournament, the table doesn't update. I understand this is because teams isn't updated, but the array underneath them with the matches is. I know you use ChangeDetectorRef to update the component, but how do you tell a different component to detectChanges()?

I have a map of teams, with games, attached to them in a service.

export class TournamentMatchesService {
  teams: Array<Team> = [];
}

export class Team {
    matches: Array<Match> = [];
}

I have one component that adds & remove matches

export class AddMatchComponent implements OnInit {

  matches: Array<Match>;

  constructor(private tournamentMatchesService: TournamentMatchesService, private cdr: ChangeDetectorRef) { }

  ngOnInit() {

  }

  addGameToTournament(match: Match) {
    this.tournamentMatchesService.addMatch(match);
    match.included = true;
    this.cdr.detectChanges();
  }

  removeGameFromTournament(match: Match) {
    this.tournamentMatchesService.removeMatch(match);
    match.included = false;
    this.cdr.detectChanges();
  }
}

and one that displays them

export class TournamentResultsComponent implements OnInit {

  constructor(private tournamentMatchesService: TournamentMatchesService, 
    private cdr: ChangeDetectorRef) { }

  ngOnInit() { }

  sortData(sort: Sort) {
    this.tournamentMatchesService.sort(sort);
    this.cdr.detectChanges();
  }
}

//html file

  <table class="mat-elevation-z8" style="width:80%" (matSortChange)="sortData($event)" matSort>
    <tr>
      ...tableHeader
    </tr>
    <tr *ngFor="let team of this.tournamentMatchesService.teams">
      ...tableBody
    </tr>
  </table>

Upvotes: 0

Views: 1041

Answers (1)

Sergio Alen
Sergio Alen

Reputation: 724

As Jason White suggested, it will be best to use BehaviorSubject, and subscribe for changes in your components, something like this:

import { BehaviorSubject } from 'rxjs/BehaviorSubject';

export class TournamentMatchesService {
  teams$ = new BehaviorSubject<Team[]>([]);

  getTeams(): Observable<Team[]> {
    return this.teams$;
  }
}

Then in you component:

export class TournamentResultsComponent implements OnInit {

  constructor(private tournamentMatchesService: TournamentMatchesService, 
    private cdr: ChangeDetectorRef) {
      this.tournamentMatchesService.getTeams().subscribe(val => {
        this.cdr.detectChanges();
      })
    }

  ngOnInit() { }

  sortData(sort: Sort) {
    this.tournamentMatchesService.sort(sort);
    this.cdr.detectChanges();
  }
}

Upvotes: 2

Related Questions