Использование *ngFor внутри собственного ng-шаблона #treeNodeTemplate заставляет дерево обновляться бесконечно, вызывая сбой браузера

  • Добавление *ngFor в шаблон ng #treeNodeTemplate заставляет дерево обновляться бесконечно.

Связанный с angular-tree-component с Angular 7.

<tree-root [nodes]="data" #tree [options]="customTemplateStringOptions">
  <ng-template #treeNodeTemplate let-node="node" let-index="index">
    <div class='model-tree-item'>
      <div>{{ node.data.getItemText() }}</div> <!-- supposed to get text from object -->

      <!-- This loop runs infinitely, getTestData() returns [1, 2, 3], keeps getting called -->
      <ng-template ngFor [ngForOf]="getTestData()" let-item>
        {{item}}
      </ng-template>
    </div>
  </ng-template>
</tree-root>

Попробовал это с простым

<div *ngFor="let item of [1, 2, 3]"> (or getTestData(), same result) 

Это объект опций дерева:

  public customTemplateStringOptions: ITreeOptions = {
    // displayField: 'subTitle',
    // isExpandedField: 'expanded',
    idField: 'uuid',
    getChildren: this.getChildren.bind(this),
    nodeHeight: 23,
    allowDrag: (node) => {
      return false;
    },
    allowDrop: (node) => {
      return false;
    }
  }

Вот getTestData():

getTestData() {
    console.log('test data');
    return [1, 2, 3];
  }

Результаты: вывод на консоль после отображения дерева

test data
test data
test data
test data
test data
test data
...

Эта проблема была открыта по следующей ссылке, но похоже, что она никогда не была решена, так как автор не ответил: Проблема Ссылка

2 ответа

Решение

Я думаю, проблема в том, что вы используете функцию в качестве input для привязки свойства, например [ngForOf]="getTestData()"

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

Попробуйте установить данные как свойство класса - посмотрите, не сужает ли это проблему

Примечание: это также почему pure pipes необходимы

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

Добавить number[] Свойство для компонента:

testData: number[];

Имейте компонент, реализующий OnInit и установите значение в ngOnInit,

ngOnInit() {
   this.testData = [1, 2, 3];
}

Изменить шаблон на

<ng-template [ngForOf]="testData" let-item>
Другие вопросы по тегам