【问题标题】:Fill material table with data from API using angular DataSource使用角度数据源使用 API 中的数据填充材料表
【发布时间】:2020-07-18 15:32:30
【问题描述】:

我有一个从后端发送数据的 api,所以当我尝试以我的角度获取这些数据时,数据不会在第一次加载,并且我的表保持为空,但是如果例如打印来自的数据在我的数据源中设置它之前,我的表已正确填充。

我的代码是:

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]));
    }));
  }
  ...

}

用户服务

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 angular-material


    【解决方案1】:

    在将用户集合发回之前,您应该等待服务器响应。

    用户服务

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

    还有,最后一点。使用来自table 标签的dataSource 输入将您的MatTableDataSource 绑定到表。

    <table [dataSource]="dataSource">
      <!-- ... -->
    </table>
    

    【讨论】:

    • 感谢您的回答,这对我很有效,所以从您的解决方案中我不需要UserListDataSource?
    • 好吧,如果你没有实现任何真正棘手的东西,就没有必要从 DataSource 扩展。 MatTableDataSource 确实为你做这件事。
    • 很抱歉,请问DataSource 有什么诀窍吗?
    • 这个问题我没看懂,不好意思,呵呵。你能解释一下吗?
    【解决方案2】:

    我不太确定问题到底出在哪里,但我最近用角材料写了几个表格。这是我用来连接表格的简单方法。

    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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-24
      • 2020-03-14
      • 1970-01-01
      • 2021-02-08
      • 2020-07-10
      • 2020-03-18
      • 1970-01-01
      相关资源
      最近更新 更多