Заполните таблицу материалов данными из API, используя angular DataSource - PullRequest
0 голосов
/ 06 апреля 2020

У меня есть API, который отправляет данные из бэкэнда, поэтому, когда я пытаюсь получить эти данные в моем angular, данные не загружаются в первый раз, и моя таблица остается пустой, но если, например, распечатать данные, которые исходить из banckend перед настройкой в ​​моем источнике данных, моя таблица заполнена правильно.

Мой код:

user-datasource.ts

export class UserListDataSource extends DataSource<User> {
  data: User[];
  paginator: MatPaginator;
  sort: MatSort;

  constructor(private usersService: UsersService) {
    super();
  }

  connect(): Observable<User[]> {
    this.data = this.usersService.usersList();
    //this.data.forEach(u => console.log(u.id)); <<---------- When I log this, My data is fill corectly
    const dataMutations = [
      observableOf(this.data),
      this.paginator.page,
      this.sort.sortChange
    ];

    return merge(...dataMutations).pipe(map(() => {
      return this.getPagedData(this.getSortedData([...this.data]));
    }));
  }
  ...

}

userService

export class UsersService {

  users: User[];

  constructor(private http: HttpClient) {}

  usersList() {    
    this.http.get(`${environment.apiUrl}/users`).pipe(
      map((jsonArray: Object[]) =>  jsonArray.map(jsonItem => User.fromJson(jsonItem)))
    ).subscribe((users: User[]) => { this.users = users; });

    return this.users;
  }

}

компонент

export class UserListComponent implements AfterViewInit, OnInit {
  @ViewChild(MatPaginator) paginator: MatPaginator;
  @ViewChild(MatSort) sort: MatSort;
  @ViewChild(MatTable) table: MatTable<User>;

  dataSource: UserListDataSource = new UserListDataSource(this.usersService);

  displayedColumns = ['id', 'email', 'username'];

  constructor(private usersService: UsersService) { }

  ngOnInit() {}

  ngAfterViewInit() {
    this.dataSource.sort = this.sort;
    this.dataSource.paginator = this.paginator;
    this.table.dataSource = this.dataSource;
  }
}

Я не уверен, если Я использую правильный способ заполнить свою таблицу, или я что-то пропускаю.

Из того, что я вижу, я думаю, что бэкэнд занял больше времени, чем веб-интерфейс для загрузки данных, другими словами, веб-интерфейс не ждет необходимое время для получения данных из бэкэнда.

Есть ли способ исправить это, пожалуйста?


Примечание: Я использую angular схемы материалов для создания всех это, в коде по умолчанию, он использует данные stati c, что не является для меня решением, и мне нужно использовать данные Dynami c.

Ответы [ 2 ]

1 голос
/ 07 апреля 2020

Вы должны дождаться ответа сервера, прежде чем отправлять коллекции пользователей обратно.

UsersService

usersList(): Observable<User[]> {    
    return this.http.get(`${environment.apiUrl}/users`).pipe(
      map((jsonArray: Object[]) =>  jsonArray.map(jsonItem => User.fromJson(jsonItem)))
    );
}

UserService просто возвращает обещание коллекции пользователя.
В вашем UserListComponent, создайте MatTableDataSource типа User и дождитесь данных от вашего сервиса. Затем, как только оно будет выполнено, добавьте эти данные к datasource.

export class UserListComponent implements OnInit, AfterViewInit {

  private users: User[] = [];
  dataSource = new MatTableDataSource<User>();
  columns: string[] = ['...'];

  @ViewChild(MatPaginator) paginator: MatPaginator;
  @ViewChild(MatSort) sort: MatSort;

  constructor(private service: UsersService) {}

  ngOnInit(): void {
    this.service.usersList().subscribe(users => {
      this.users = users;
      this.dataSource.data = this.users;
    });
  }

  ngAfterViewInit(): void {
    this.dataSource.sort = this.sort;
    this.dataSource.paginator = this.paginator;
  }
}

И к последнему пункту. Используйте ввод dataSource из тега table, чтобы связать ваш MatTableDataSource с таблицей.

<table [dataSource]="dataSource">
  <!-- ... -->
</table>
0 голосов
/ 07 апреля 2020

Я не совсем уверен, в чем именно проблема, но я недавно написал пару таблиц с материалом angular. Вот простой способ, которым я пользовался для соединения с таблицей.

export class UserDataSource extends DataSource<any> {

constructor (
    private userSettingsService: UserSettingsService) 
{
    super();
}

  public usersDataStream = new BehaviorSubject<IUser[]>([]);

  connect(): Observable<IUser[]> {
    return this.usersDataStream.asObservable();
  }
  disconnect() {
    this.usersDataStream.complete();
  }
}

А затем в классе компонентов:

public dataSource: UserDataSource;

ngOnInit(): void {
this.dataSource = new UserDataSource(this._userSettingsService);
}

и затем шаблон HTML:

<mat-table [dataSource]="dataSource">
...
</mat-table>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...