I have a simple component which iterates over a static array of objects and displays the content. When this component is added into the larger application, the content is displayed correctly but I am unable to register any click events on it. When I inspect the element in chrome using right click -> Inspect
I am greeted with the body tag and it doesn't drill down to the individual element as expected.
By navigating manually, inspecting the element idicates that the component is constantly being updated by the DOM (div tag flashes). By my understanding there shouldn't be any change detected since it is a static array.
Changing the object array to a simple string array ['a', 'b', 'c']
behaves as expected and the DOM isn't being updated.
Adding additional elements the template outside of the ngFor are unaffected and aren't being constantly updated.
I am using v2.4.1
Simplified Component
import { Component } from '@angular/core';
@Component({
selector: 'app-ngfor-test',
templateUrl: './ngfor-test.component.html',
styleUrls: ['./ngfor-test.component.css']
})
export class NgforTestComponent {
get items() {
return [
{
'label': 'a',
'value': 'first'
},
{
'label': 'b',
'value': 'second'
},
{
'label': 'c',
'value': 'third'
}
];
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
Template
<div class="item-container" *ngFor="let item of items">
<label>{{ item.label | uppercase }}</label>
<span>{{ item.value }}</span>
</div>
As @seidme mentioned the getter is called every time change detection runs, which can be quite often.
get items() {
return [
{
'label': 'a',
'value': 'first'
},
{
'label': 'b',
'value': 'second'
},
{
'label': 'c',
'value': 'third'
}
];
}
returns a new object instance every time it is called, which causes ngFor
to re-render the list.
If you change it to
items = [
{
'label': 'a',
'value': 'first'
},
{
'label': 'b',
'value': 'second'
},
{
'label': 'c',
'value': 'third'
}
];
get items() {
return this.items;
}
it will stop re-rendering, because Angular recognizes it got the same object instance and nothing has changed and nothing needs to be updated or re-rendered.
You're passing a getter to the *ngFor
directive. get
syntax binds an object property to a function that will be called when that property is looked up (every time Angular runs change detection), which in your case always returns a new array object (reference changes), forcing the Angular to re-render the list.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With