Компонент таблицы угловых материалов, не отображающий данные

#html #angular #angular-material

#HTML #angular #angular-material

Вопрос:

Я изо всех сил пытаюсь загрузить данные в свою таблицу angular material. Заголовки столбцов отображаются так, как и ожидалось, за исключением того, что теперь есть строки данных. Самое странное, что в источнике данных есть данные, которые используются таблицей. Смотрите код (или изображения) ниже:

Тип объекта для заполнения источника данных

 export default interface UserStripeTableResource {
    id: number;
    fullName: string;
    saldo: number;
    totalstripes: number;
} 
 

Это интерфейс, используемый для заполнения списка для таблицы, никаких странных вещей, на мой взгляд.

Компонент (файл .ts)

 @Component({
  selector: 'app-admin-editsaldo',
  templateUrl: './admin-editsaldo.component.html',
  styleUrls: ['./admin-editsaldo.component.css']
})
export class AdminEditsaldoComponent implements OnInit {

  @Input() allusersstripes: UserStripeTableResource[];
  @Output() RefreshListOfUsers = new EventEmitter<any>();


  dataSource: MatTableDataSource<UserStripeTableResource> = new MatTableDataSource();
  dataDisplayedColumns: string[] = ['id', 'fullName', 'saldo', 'totalstripes'];

  selectedamount: number = null;

  constructor(
  ) { }

  ngOnChanges(changes: SimpleChange): void {
  }

  ngOnInit() {
    this.dataSource = new MatTableDataSource(this.allusersstripes);
    console.log(this.dataSource.data);
  }
 

Файл, который обрабатывает логику заполнения таблицы. Как вы можете видеть, данные предоставляются родительским поставщиком (см. @input ). Данные немедленно присваиваются источнику данных в ngOnInit. Кроме того, столбцы указаны правильно, так как они показаны на HTML-странице.

HTML-страница

 <div *ngIf="dataSource">

    <table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">

        <!--- Note that these columns can be defined in any order.
          The actual rendered columns are set as a property on the row definition" -->

        <!-- Position Column -->
        <ng-container matColumnDef="id">
            <th mat-header-cell *matHeaderCellDef mat-sort-header> ID </th>
            <td mat-cell *matCellDef="let element"> {{element.id}} </td>
        </ng-container>

        <!-- Name Column -->
        <ng-container matColumnDef="fullName">
            <th mat-header-cell *matHeaderCellDef mat-sort-header> Naam </th>
            <td mat-cell *matCellDef="let element"> {{element.fullName}} </td>
        </ng-container>

        <!-- Weight Column -->
        <ng-container matColumnDef="saldo">
            <th mat-header-cell *matHeaderCellDef mat-sort-header> Saldo </th>
            <td mat-cell *matCellDef="let element"> {{element.saldo}} </td>
        </ng-container>

        <!-- Symbol Column -->
        <ng-container matColumnDef="totalstripes">
            <th mat-header-cell *matHeaderCellDef mat-sort-header> Totaal strepen </th>
            <td mat-cell *matCellDef="let element"> {{element.totalstripes}} </td>
        </ng-container>

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

</div>
 

HTML-страница, на которой должна отображаться таблица. Столбцы соответствуют именам, указанным в файле .ts, и совпадают со свойствами объекта.

Изображение, показывающее html-страницу с журналом источника данных

Вещи, которые я уже пробовал:

  1. Двойная проверка правильности импорта каждого необходимого модуля.
  2. Используйте ngIf перед отображением таблицы, чтобы убедиться, что источник данных заполнен до отображения таблицы.
  3. Распечатайте источник данных в формате JSON прямо на странице html, чтобы дважды проверить, есть ли он там, прежде чем таблица будет отображена.
  4. Попробуйте использовать приведенный пример с самого сайта angular material, который работает (но он использует статические данные, поэтому, я думаю, они не очень сопоставимы)
  5. Попробуйте включить ngIf в родительском компоненте дочернего компонента, чтобы убедиться, что асинхронные данные присутствуют до фактического отображения компонента.

У меня действительно нет идей, я уже пару дней борюсь с этим. Я действительно надеюсь, что кто-нибудь сможет мне помочь :).

Источник html (без пользовательского источника css)

Список используемых пакетов

 brandfonds-website@0.0.0 E:Prive ProjectenCodingBrandfondsBrandfonds-Frontend
├── @angular-devkit/build-angular@0.1100.7
├── @angular/animations@11.1.0
├── @angular/cdk@11.1.0
├── @angular/cli@11.1.1
├── @angular/common@11.1.0
├── @angular/compiler-cli@11.1.0
├── @angular/compiler@11.1.0
├── @angular/core@11.1.0
├── @angular/flex-layout@11.0.0-beta.33
├── @angular/forms@11.1.0
├── @angular/language-service@11.1.0
├── @angular/localize@11.1.0
├── @angular/material@11.1.0
├── @angular/platform-browser-dynamic@11.1.0
├── @angular/platform-browser@11.1.0
├── @angular/router@11.1.0
├── @fortawesome/fontawesome-free@5.15.2
├── @full-fledged/alerts@11.0.0
├── @types/chart.js@2.9.30
├── @types/jasmine@3.3.16
├── @types/jasminewd2@2.0.8
├── @types/node@8.9.5
├── animate.css@4.1.1
├── chart.js@2.9.4
├── codelyzer@5.2.2
├── font-awesome@4.7.0
├── hammerjs@2.0.8
├── jasmine-core@3.4.0
├── jasmine-spec-reporter@4.2.1
├── karma-chrome-launcher@2.2.0
├── karma-coverage-istanbul-reporter@2.0.6
├── karma-jasmine-html-reporter@1.5.4
├── karma-jasmine@2.0.1
├── karma@5.1.1
├── ng-swagger-gen@2.3.0
├── protractor@7.0.0
├── rxjs@6.6.3
├── ts-node@7.0.1
├── tslib@2.1.0
├── tslint@6.1.3
├── typescript@4.0.5
└── zone.js@0.11.3
 

Ответ №1:

Я воспроизвел ваш пример в stackblitz с последней версией angular 11, и, похоже, это работает.

Редактировать:

ngOnInit получает вызов один раз с нулевыми / неопределенными данными, поскольку http-запрос все еще выполняется. Входные данные обновляются, но поскольку интерфейс onChanges не реализован, компонент AdminEditsaldoComponent ничего не делает с новыми данными.

Решение состоит в том, чтобы либо реализовать интерфейс onChanges, либо скрыть компонент AdminEditsaldoComponent в родительском компоненте, пока вы не загрузили данные (<app-admin-editsaldo *ngIf=»data» [allusersstripes]=»data»>…)

Комментарии:

1. Ну, тогда я действительно этого не понимаю. У меня почти тот же код, за исключением того, что я получаю свои данные в «родительском компоненте» из sync http get, но это не должно иметь значения. Может быть, это как-то связано с одним из моих пакетов (возможно, конфликтует или что-то в этом роде?).

2. Может быть, это просто CSS, вы проверили, существуют ли теги html-элементов <tr>? На связанном изображении есть полоса прокрутки, поэтому похоже, что там есть содержимое.

3. Нет, это тоже не то. Я не использовал пользовательский css, поскольку, насколько я могу судить, я добавил источник html из chrome в исходное сообщение (может быть, вы видите что-то, чего я не вижу)?

4. Хорошо, я понял это, понятия не имею, почему я не видел этого вчера. Я просто смоделировал асинхронный get с таймаутом. Ваша проблема в том, что вы передаете значение null компоненту из родительского компонента при инициализации, затем загружаете данные асинхронно и передаете их снова, но ngOnInit вызывается только один раз в AdminEditsaldoComponent после создания компонента. Чего вам не хватает, так это реализации интерфейса onChanges (ngOnChanges) или вы *ngIf тег <app-admin-editsaldo> в родительском компоненте, пока не получите данные. Я обновил свой пример, чтобы отразить изменения.

5. Я забыл сказать, что я уже пробовал оба решения (вот почему вы все еще видите ngchanges на скриншоте). Я также поместил *ngIf в родительский компонент html для дочернего компонента, но результат все тот же. Что-то подсказывает мне, что это должно быть проблемой с самим html или, возможно, с моими пакетами. Я использую fxFlex в качестве контейнерной сетки, может быть, это как-то конфликтует? Я обновлю список того, что я пробовал, кстати, извините, что забыл добавить этот.