Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
125 views
in Technique[技术] by (71.8m points)

angular - Update table information from custom data source

I can't update my angular material table information when the user add a new tv show from a dialog component!

The idea is that once the user add a new tv show, the table will have this new information.

I have implemented a custom Data Source following an article.

The code of this class is :

export class DataSourceTvShowRemindersService implements DataSource<TvShowReminder> {

  private totalElementsForPagination = new BehaviorSubject<number>(0); 
  public readonly totalElementsForPagination$: Observable<number> = this.totalElementsForPagination.asObservable();
  private tvShowRemindersSubject = new BehaviorSubject<TvShowReminder[]>([]);

  constructor(private tvShowReminderService: TvShowRemindersService) {}

  loadReminders(page: number, size:number) {
    this.tvShowReminderService.getTvShowRemindersPaginated(page,size).pipe(
      tap((reminders) => console.log(reminders))     
    ).subscribe((pageReminder) => {
      if(pageReminder != null) {
        this.tvShowRemindersSubject.next(pageReminder.items);
        this.totalElementsForPagination.next(pageReminder.pageDescriptionDTO.totalElements);
      }
    });
  }

   //This method will be called once by the Data Table at table bootstrap time.
  // The Data Table expects this method to return an Observable, and the values of that observable 
 // contain the data that the Data Table needs to display.

  connect(collectionViewer: CollectionViewer): Observable<TvShowReminder[]> {
    console.log('Connecting data source');
    return this.tvShowRemindersSubject.asObservable();
  }

  // This method is called once by the data table at component destruction time.
  disconnect(collectionViewer: CollectionViewer): void {
    this.tvShowRemindersSubject.complete();
  }

  saveReminder(reminder: TvShowReminderEntity) : void {
    this.tvShowReminderService.saveTvShowReminder(reminder).subscribe(() => {
      this.loadReminders(0,3);
    });
  }
}

The component table code is :

export class TvShowRemindersComponent implements OnInit , AfterViewInit {
  totalElementsForPagination : number;
  reminder = {} as PageResponseReminder;
  dataSource: DataSourceTvShowRemindersService;
  displayedColumns = [
    'name',
    'genre',
    'currentSeason',
    'currentEpisode',
    'completed',
    'personalRating',
  ];

  @ViewChild(MatPaginator) paginator: MatPaginator;

  constructor(private tvShowRemindersService: TvShowRemindersService) {}

  ngOnInit(): void {
    this.dataSource = new DataSourceTvShowRemindersService(this.tvShowRemindersService);
    this.dataSource.loadReminders(0, 3);

    // Get the total number of element to paginated
    this.dataSource.totalElementsForPagination$.subscribe((totalElementsToPaginated) => {
      this.totalElementsForPagination = totalElementsToPaginated;
      console.log(this.totalElementsForPagination);
    });
  }

  ngAfterViewInit() {
    this.paginator.page.pipe(tap(() => this.loadRemindersPage())).subscribe();

    // Get the total number of element to paginated
    this.dataSource.totalElementsForPagination$.subscribe((totalElementsToPaginated) => {
      this.totalElementsForPagination = totalElementsToPaginated;
      console.log(this.totalElementsForPagination);
    });
  }

  loadRemindersPage() {
    this.dataSource.loadReminders(
      this.paginator.pageIndex, // number of page
      this.paginator.pageSize // size of the page (elements)
    );
  }
}

And the dialog component that is calling the saveReminder method from the DataSource class:


export class TvShowReminderDialogComponent implements OnInit {
  
  // Ommit the rest of the code for brevity.

  saveTvShowReminder(reminder: TvShowReminderEntity) {
    this.dataSourceReminders.saveReminder(reminder);
  }
}

Finally the service that store the tv show reminder and load the paginated reminders:

export class TvShowRemindersService {

  /* GET tv shows reminders from the server */
  getTvShowRemindersPaginated(page: number, size:number): Observable<PageResponseReminder> {
    const params = new HttpParams().set('page', page.toString()).set('size', size.toString()); 

    return this.http.get<PageResponseReminder>(baseUrl+ `${tvShowReminderEndpoints.REMINDERDS_PAGINATED}`, {params}).pipe( 
      tap((result) => console.log(result)) 
    );
  }

  saveTvShowReminder(tvShowReminder : TvShowReminderEntity): Observable<TvShowReminderEntity> {
    return this.http.post<TvShowReminderEntity>(baseUrl+ `${tvShowReminderEndpoints.SAVE_REMINDER}`, tvShowReminder);
  }

  constructor(private http: HttpClient) { }
}

So I am calling the saveTvShowReminder method from my dialog component, which calls the data source method saveReminder with the entity we are goint to store. Then i will subscribe to that service call, once the tv show is saved, i call the loadReminders.

I am getting the reminders of the user , with this new tv show reminder, that has been stored in the database. So far all is working good, BUT the problem is that the component table is not being notified of this change and the table is not showing this new information.

I dont understand why is not reloading the table.

I am new to angular and rxjs library , so please, can anyone help me to solve this!

question from:https://stackoverflow.com/questions/65877433/update-table-information-from-custom-data-source

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I don't know where do you open your TvShowReminderDialogComponent, but you can do something like the code bellow:

const dialogRef = this.dialog.open(TvShowReminderDialogComponent, {
      data: //SOME DATA TO THE DIALOG IF NEEDED,
      disableClose: true //THIS PREVENT THE USER TO CLOSE THE DIALOG CLICKING OUT OF BOUNDS
    });
    //THIS CODE HERE WILL SUBSCRIBE TO THIS dialogRef, AND WHEN IT CLOSES
    //WILL RUN THE FOLLOWING CODE
    dialogRef.afterClosed().subscribe(result => {

      //YOU CAN CALL YOUR loadReminders HERE
      // AND REFRESH YOUR DATASOURCE

    });

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...