1
  • Adding *ngFor to ng-template #treeNodeTemplate causes the tree to refresh infinitely.

Related to angular-tree-component with 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>

Tried this with simple

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

This is the tree options object:

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

Here is getTestData():

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

Results: Console output after tree is rendered

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

This problem was opened in the following link but looks like it was never addressed as the poster did not respond: Problem Link

Anil
  • 57
  • 9

2 Answers2

1

Don't call methods from the template unless it is response to user action. You end up in a change detection loop.

Add a number[] property to the component:

testData: number[];

Have the component implement OnInit and set the value in ngOnInit.

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

Change template to

<ng-template [ngForOf]="testData" let-item>
The Head Rush
  • 3,157
  • 2
  • 25
  • 45
0

I think the problem is that you're using a function as the input for a property binding e.g. [ngForOf]="getTestData()"

Angular tries to check if the input value has changed during the change detection cycle, and it expects the input value to be a variable in the template, or a property on the class. If it has to call a function to retrieve the value, it will simply call it indefinitely

Try setting the data as a property on the class - see if that narrows down the issue

Note: this is also why pure pipes are necessary

Drenai
  • 11,315
  • 9
  • 48
  • 82