Проблемы с рендерингом HTML после инициализации view

#angular

#angular

Вопрос:

ниже приведен мой компонент HTML

     <li *ngIf="this.currentData.length == 0">
          Data not found
    </li>
    <li
      #itemElement
      *ngFor="let item of currentData; let i = index"
      (click)="onSelectionChange(valueAccessor(item), itemElement)"
      [ngClass]="{ 'k-state-selected': isItemSelected(item) }"
    >
      <input
        type="checkbox"
        id="chk-{{ valueAccessor(item) }}"
        (focus)="onFocus(itemElement)"
        class="k-checkbox"
        [checked]="isItemSelected(item)"
      />
      <label
        class="k-multiselect-checkbox k-checkbox-label"
        for="chk-{{ valueAccessor(item) }}"
      >
        {{ textAccessor(item) }}
      </label>
    </li>
  

необходимая часть compotent TS

     public ngAfterViewInit() {
        this.vlSubscription = this.valueListService.getValueListData(this.gridType, this.valueListObj).subscribe((data: any) => {
            this.data = data.values;
            this.currentData = this.data;
        });
    }
  

Итак, проблема здесь в том, что пока данные не будут возвращены, HTML показывает, что данные не найдены. Через пару секунд отображается список значений. Здесь, как я могу показать по крайней мере новый текст, такой как ‘loading ..’, пока данные не закончат загрузку? Спасибо.

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

1. (1). Почему переменные назначены в ngAfterViewInit() hook. Это прекрасно (и даже быстрее) делать в ngOnInit() хук. (2). Если вы используете стратегию CD по умолчанию, не рекомендуется привязывать функции к интерполяции и привязкам свойств, таким как {{ valueAccessor(item) }} и isItemSelected(item) . Они будут выполняться для каждого цикла CD. И у вас есть много таких заявлений. Вместо этого вы могли бы зациклить массив в подписке, вызвать необходимые функции и создать новые свойства с их ответами. И используйте эти новые свойства непосредственно в шаблоне.

2. Причина в том, что мне нужно вызвать API и загрузить данные соответствующего столбца при нажатии на значок фильтра. Именно по этой причине я использую afterviewiniti.

Ответ №1:

Вы можете добавить дополнительную переменную для загрузки:

  loading = true;

 public ngAfterViewInit() {
        this.vlSubscription = this.valueListService.getValueListData(this.gridType, this.valueListObj).subscribe((data: any) => {
            this.loading = false;
            this.data = data.values;
            this.currentData = this.data;
        });
    }
  
 
    <li *ngIf="this.loading">
          Loading...
    </li>

    <ng-container *ngIf="!this.loading">
      <li *ngIf="this.currentData.length == 0">
           Data not found
      </li>
      <li
        #itemElement
        *ngFor="let item of currentData; let i = index"
        (click)="onSelectionChange(valueAccessor(item), itemElement)"
        [ngClass]="{ 'k-state-selected': isItemSelected(item) }">
       ...
    </ng-container>