2017-01-12 2 views
3

У меня есть простой компонент, который выполняет итерацию по статическому массиву объектов и отображает содержимое. Когда этот компонент добавляется в большее приложение, содержимое отображается правильно, но я не могу зарегистрировать на нем какие-либо события клика. Когда я проверяю элемент в chrome, используя right click -> Inspect, меня приветствует тег body, и он не доходит до отдельного элемента, как ожидалось.Iterating over * ngFor со статическим массивом объектов постоянно обновляет DOM

С помощью ручной навигации проверка элемента указывает, что компонент постоянно обновляется с помощью DOM (знак тега мигает). По моему мнению, не должно быть обнаружено никаких изменений, поскольку это статический массив.

Изменение массива объектов на простой массив строк ['a', 'b', 'c'] ведет себя так, как ожидалось, и DOM не обновляется.

Добавление дополнительных элементов Шаблон за пределами ngFor не изменяется и не постоянно обновляется.

Я использую v2.4.1

упрощенный компонент

import { Component } from '@angular/core'; 
 

 
@Component({ 
 
\t selector: 'app-ngfor-test', 
 
\t templateUrl: './ngfor-test.component.html', 
 
\t styleUrls: ['./ngfor-test.component.css'] 
 
}) 
 
export class NgforTestComponent { 
 
\t 
 
\t get items() { 
 
\t \t return [ 
 
\t \t \t { 
 
\t \t \t \t 'label': 'a', 
 
\t \t \t \t 'value': 'first' 
 
\t \t \t }, 
 
\t \t \t { 
 
\t \t \t \t 'label': 'b', 
 
\t \t \t \t 'value': 'second' 
 
\t \t \t }, 
 
\t \t \t { 
 
\t \t \t \t 'label': 'c', 
 
\t \t \t \t 'value': 'third' 
 
\t \t \t } 
 
\t \t ]; 
 
\t } 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

Шаблон

<div class="item-container" *ngFor="let item of items"> 
 
\t <label>{{ item.label | uppercase }}</label> 
 
\t <span>{{ item.value }}</span> 
 
</div>

ответ

1

Как упоминал @seidme, геттер называется каждый раз, когда происходит сбой обнаружения изменений, что может быть довольно часто.

get items() { 
    return [ 
     { 
      'label': 'a', 
      'value': 'first' 
     }, 
     { 
      'label': 'b', 
      'value': 'second' 
     }, 
     { 
      'label': 'c', 
      'value': 'third' 
     } 
    ]; 
} 

возвращает новый экземпляр объекта каждый раз, когда она называется, что приводит к ngFor повторной визуализации списка.

Если вы измените его на

items = [ 
     { 
      'label': 'a', 
      'value': 'first' 
     }, 
     { 
      'label': 'b', 
      'value': 'second' 
     }, 
     { 
      'label': 'c', 
      'value': 'third' 
     } 
    ]; 

get items() { 
    return this.items; 
} 

это остановит повторный рендеринг, потому что Угловая признает он получил тот же экземпляр объекта, и ничего не изменилось, и ничего не нужно обновить или повторно вынесено.

+0

Спасибо. Это помогает понять, почему массив объектов ведет себя по-разному с массивом строк. Я использую getter, потому что хочу, чтобы содержимое отображалось динамически, исходя из репликации, получаемой с сервера. –

+0

Вы по-прежнему можете обновить 'this.items', когда будет получен ответ от сервера, но таким образом он изменяется только (и повторно отображается), когда он был фактически изменен. –

+0

Спасибо за помощь, я достиг динамических значений, используя сеттер –

2

Вы передаете getter директиве *ngFor. Синтаксис get связывает свойство объекта с функцией, которая будет вызываться при поиске этого свойства (каждый раз, когда обнаружено изменение углового пробега), которое в вашем случае всегда возвращает новый объект массива (изменения ссылки), заставляя Угловое повторное рендеринг список.

+0

Спасибо, я думал, что это может быть так, но это не объясняет, почему он работает так, как ожидалось, когда массив объектов заменяется строковым массивом –

Смежные вопросы