Angular ngFor: как остановить обновление DOM, если в свойствах элемента есть новые ссылки с одинаковыми значениями - PullRequest
0 голосов
/ 24 сентября 2019

Просто нужно начать с небольшого фона приложения (упрощенно) ...

У меня есть приложение Angular, которое только что обновило списки элементов, полученных при опросе серверной службы.

Например, следующие контейнеры данных ...

class IdDescription {
      public id: string
      public description : string
}

class MyItem {
       public prop1 : IdDescription;
       public prop2 : IdDescription;
       public prop3 : IdDescription; 
       // etc
}

class IncomingUpdates {
      public updates: Array<MyItem>;
}

В моем компоненте у меня будет свойство хранить массив элементов ..

public data: Array<T>;

И в разметкеУ меня есть ngFor для данных

<div *ngFor="let item of data [@slideInOut]='slideInOutState' >
  <div tappable (click)='clickItem(item)'>
    <ion-ripple-effect></ion-ripple-effect>
    <ion-grid>
      <ion-row>            
        <ion-col class='card-main-data-col'>
          <div <b>{{item.prop1.description}}</b></div>
          <div [@valueUpdated]='item.prop2'>{{item.prop2.description}}</div>
          <div [@valueUpdated]='item.prop3'>{{item.prop3.description}}</div>              
         </div>
        </ion-col>
      </ion-row>
    </ion-grid>
  </div>

Когда обновляется prop2 или prop3, у меня есть триггер (valueUpdated) для запуска небольшой анимации ...

 trigger('valueUpdated', [
    state('void => *', style({ transform: 'translate3d(0, 0, 0)' })),
    state('* <=> *', style({ transform: 'translate3d(0, 0, 0)' })),

    transition('void => *', []),
    transition('* => void', []),
    transition('* <=> *', [
      animate(1000, style({ color: 'green', fontWeight: 'bold' }))
    ])
  ]),

Итак, соответствующая часть, когда я вижу эти изменения, выделяется жирным и зеленым цветом.

До сих пор, когда у меня есть входящие данные, у меня есть код для проверки значений, ищите существующий MyItem и затем обновите все ссылки на свойство IdDescription, ЕСЛИ они изменились (т.е. я нахожу по идентификатору).Так что это всегда работало, и я вижу, что они меняются на зеленый (анимация), когда я обновляю ссылку на свойство.

Теперь мне интересно, слишком много ли я делаю, (т.е. все это проверка), и если Angular может сделать большую часть этого для моего.Кроме того, я рассматриваю возможность начать использование ngrx, где шаблон обычно не изменяет всю ссылку на список при любых обновлениях, и позволяет Angular обрабатывать обновления DOM.

Чтобы проверить сейчас, я обновляюpublic data: Array<T>; ссылка .Сначала я мог видеть (через пользовательский интерфейс и инструменты разработки), что когда я это делал, весь список DOM был регенерирован.

this.data = newState; // now replace reference

Затем я обнаружил, что могу добавить trackBy для выполнения сравнений ..т. е.

<div *ngFor="let item of daya;trackBy: trackByFunction" 

с

public trackByFunction(index: number, item: MyItem) {
  if (!item)
    return null;

  return item.prop1.code;
}

т. е. prop1 является идентификатором всего элемента.

Теперь, из того, что я мог видеть, элементы, гдебольше не заменялось в DOM, именно то, что мне было нужно - так Angular делает сравнение и определяет, что данные данных были одинаковыми, поэтому не обновляет основные элементы.

Однако я ДЕЙСТВИТЕЛЬНО все еще вижу свойствоанимация запускается, поэтому я предполагаю, что эти "дочерние" элементы DOM пока еще заменяются.

Наконец-то!

Мой вопрос в том, есть ли способ также использовать своего рода «trackBy» для этих «дочерних» свойств, поэтому Angular знает, что они имеют одинаковые значения, и поэтому не обновляет DOM (и, следовательно,анимации не запускаются)?

Заранее спасибо за любую помощь!

1 Ответ

0 голосов
/ 24 сентября 2019

Попробуйте использовать NgZone runOutsideAngular().Вы должны запустить свой код вне angular.

вот так https://stackoverflow.com/a/39626378/1710501

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...