Почему эта Angular таблица материалов не отображается? - PullRequest
2 голосов
/ 29 мая 2020

Я работаю над приложением «Контакты» с материалами Angular 9 и Angular. Компонент списка должен отображать для каждого контакта некоторую информацию и изображение в строке таблицы.

В моем app.module.ts я импортировал, среди прочего, MatTableModule.

app\services\contacts-list.service.ts У меня:

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { map } from 'rxjs/operators';

import { Contact } from '../models/Contact';

const httpOptions = {
  headers: new HttpHeaders({
    'Content-Type': 'application/json'
  })
}

@Injectable({
  providedIn: 'root'
})

export class ContactsListService {

  contactsUrl = 'https://randomuser.me/api/?&results=20&inc=name,location,email,cell,picture';

  constructor(private http:HttpClient) { }

  getContcts():Observable<Contact[]> {
    return this.http.get<Contact[]>(`${this.contactsUrl}`)
      .pipe(map(response => response['results']));
  }

  getOneContact():Observable<Contact[]> {
    return this.http.get<Contact[]>(`${this.contactsUrl}`)
      .pipe(map(response => response['results']));
  }

}

В app\components\list\list.component.ts У меня:

import { Component, OnInit } from '@angular/core';
import { MatTableDataSource } from '@angular/material/table';
import { from } from 'rxjs';
import { ContactsListService } from '../../services/contacts-list.service';
import { Contact } from '../../models/Contact';

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

export class ListComponent implements OnInit {

  pageTitle = 'My Contacts';

  contactsList:Contact[];

  constructor(private ContactsListService:ContactsListService) { }

  contactsTableData: MatTableDataSource<any>;
  displayedColumns: string[] = ['fullName', 'photo', 'email', 'city', 'country'];

  ngOnInit(): void  {
    // Contact list
    this.ContactsListService.getContcts().subscribe(
      contactsList => { 
        this.contactsList = contactsList; console.log(contactsList);
        this.contactsTableData = new MatTableDataSource(contactsList);
      },
      error => { }
    );
  }
}

В шаблоне вышеуказанного компонента:

<div class="container">
    <h2 class="mat-display-1 page-title">{{pageTitle}}</h2>
    <div class="mat-elevation-z8">
        <mat-table [data-source]="contactsTableData">

            <ng-container matColumnDef="fullName">
                <mat-header-cell *matHeaderCellDef> Full Name </mat-header-cell>
                <mat-cell *matCellDef="let element"> {{element.name.first}} {{element.name.last}} </mat-cell>
            </ng-container>

            <ng-container matColumnDef="photo">
                <mat-header-cell *matHeaderCellDef> Photo </mat-header-cell>
                <mat-cell *matCellDef="let element"> {{element.picture.large}} </mat-cell>
            </ng-container>

            <ng-container matColumnDef="email">
                <mat-header-cell *matHeaderCellDef> Email address </mat-header-cell>
                <mat-cell *matCellDef="let element"> {{element.email}} </mat-cell>
            </ng-container>

            <ng-container matColumnDef="city">
                <mat-header-cell *matHeaderCellDef> City </mat-header-cell>
                <mat-cell *matCellDef="let element"> {{element.location.city}} </mat-cell>
            </ng-container>

            <ng-container matColumnDef="phone">
                <mat-header-cell *matHeaderCellDef> Phone </mat-header-cell>
                <mat-cell *matCellDef="let element"> {{element.cell}} </mat-cell>
            </ng-container>

            <ng-container matColumnDef="country">
                <mat-header-cell *matHeaderCellDef> Country </mat-header-cell>
                <mat-cell *matCellDef="let element"> {{element.location.country}} </mat-cell>
            </ng-container>

            <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
            <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
        </mat-table>
    </div>
</div>

Проблема

Проблема, с которой я столкнулся, заключается в том, что отображается только заголовок таблицы (имена столбцов) без данных, Эван подумал, что строка console.log(contactsList) из компонента правильно показывает список контактов:

[
  {
     "name":{
        "title":"Mr",
        "first":"Mair",
        "last":"da Cunha"
     },
     "location":{
        "street":{
           "number":1198,
           "name":"Rua Belo Horizonte "
        },
        "city":"Cachoeiro de Itapemirim",
        "state":"Tocantins",
        "country":"Brazil",
        "postcode":36034,
        "coordinates":{
           "latitude":"-78.1101",
           "longitude":"-171.0313"
        },
        "timezone":{
           "offset":"+5:00",
           "description":"Ekaterinburg, Islamabad, Karachi, Tashkent"
        }
     },
     "email":"mair.dacunha@example.com",
     "cell":"(66) 5998-0008",
     "picture":{
        "large":"https://randomuser.me/api/portraits/men/88.jpg",
        "medium":"https://randomuser.me/api/portraits/med/men/88.jpg",
        "thumbnail":"https://randomuser.me/api/portraits/thumb/men/88.jpg"
     }
  }
]

Чего не хватает?

Ответы [ 2 ]

2 голосов
/ 29 мая 2020

На шаблоне mat-table следует использовать [dataSource] вместо [data-source]. Это должно решить вашу проблему.

Также быстрый совет: ваш ответ возвращает не массив ContactAM, а объект, имеющий свойство с именем results, которое, в свою очередь, имеет значение массива ContactAM. Итак, на вашем service, где вы вводите HTTP GET call и набираете его как ContactAM[], вы фактически должны вводить его как { results: ContactAM[] }

1 голос
/ 29 мая 2020

Вот как была решена проблема, на случай, если кто-то еще может использовать эту информацию:

В файле app\components\list\list.component.ts у меня есть:

import { Component, OnInit, ViewChild } from '@angular/core';
import { MatTableDataSource } from '@angular/material/table';
import { MatPaginator } from '@angular/material/paginator';
import { from } from 'rxjs';
import { ContactsListService } from '../../services/contacts-list.service';
import { Contact } from '../../models/Contact';

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

export class ListComponent implements OnInit {

  pageTitle = 'My Contacts';

  contactsList:Contact[];

  constructor(private ContactsListService:ContactsListService) { }

  contactsTableData: MatTableDataSource<any>;
  displayedColumns: string[] = ['fullName', 'photo', 'email', 'phone', 'city', 'country'];

  @ViewChild(MatPaginator) paginator: MatPaginator;

  ngOnInit(): void  {
    // Contact list
    this.ContactsListService.getContcts().subscribe(
      contactsList => { 
        this.contactsList = contactsList;
        this.contactsTableData = new MatTableDataSource(contactsList);
        this.contactsTableData.paginator = this.paginator;
      },
      error => { }
    );
  }
}

В шаблоне компонента I есть:

<div class="container">
    <div class="mat-elevation-z8">
        <table mat-table [dataSource]="contactsTableData" class="w-100">
            <ng-container matColumnDef="fullName">
                <th mat-header-cell *matHeaderCellDef>Full Name</th>
                <td mat-cell *matCellDef="let element">{{element.name.first}} {{element.name.last}}</td>
            </ng-container>

            <ng-container matColumnDef="photo">
                <th mat-header-cell *matHeaderCellDef>Photo</th>
                <td mat-cell *matCellDef="let element">
                    <img src="{{element.picture.large}}" alt="{{element.name.first}} {{element.name.last}}" class="thumbnail rounded-circle">
                </td>
            </ng-container>

            <ng-container matColumnDef="email">
                <th mat-header-cell *matHeaderCellDef>Email address</th>
                <td mat-cell *matCellDef="let element">
                    <a href="mailto:{{element.email}}">{{element.email}}</a>
                </td>
            </ng-container>

            <ng-container matColumnDef="phone">
                <th mat-header-cell *matHeaderCellDef>Phone</th>
                <td mat-cell *matCellDef="let element">
                    <a href="tel:{{element.phone}}">{{element.cell}}</a>
                </td>
            </ng-container>

            <ng-container matColumnDef="city">
                <th mat-header-cell *matHeaderCellDef>City</th>
                <td mat-cell *matCellDef="let element">{{element.location.city}}</td>
            </ng-container>

            <ng-container matColumnDef="country">
                <th mat-header-cell *matHeaderCellDef>Country</th>
                <td mat-cell *matCellDef="let element">{{element.location.country}}</td>
            </ng-container>

            <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
            <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
        </table>
        <mat-paginator [pageSizeOptions]="[10, 20, 50]" [pageSize]="10" showFirstLastButtons></mat-paginator>
    </div>
</div>

У меня тоже есть эти стили для изображений:

.rounded-circle {
    border-radius: 50%!important;
}

.thumbnail {
    padding: 2px;
    line-height: 1;
    background-color: #fff;
    border: 1px solid #ddd;
    height: 40px;
    width: auto;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...