ChangeDectection OnPush: ngFor не запускается, пока прямой вызов - PullRequest
0 голосов
/ 08 июля 2019

У меня проблема с ngFor при использовании Angular OnPush ChangeDetection.

Это мой код:

app.state.ts

export class Node {
    title: string;
}

export class Tree {
    nodes: Array<Node>
}

home.component.ts

@Component({
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class HomeComponent implements OnInit {
    tree$: Observable<Tree>;

    ngOnInit() {
        this.tree$ = this.store.select(state => state.tree);
    }
}

home.component.html

Number of nodes: {{ (tree$ | async).nodes.length }}
<div *ngFor="let node of (tree$ | async).nodes" class="node-list">
    {{ node.title }}
</div>

По умолчанию массив узлов пуст. Когда я отправляю действие для добавления нового узла в массив node . количество узлов в шаблоне изменяется, но список узлов по-прежнему пуст.

Я не понимаю, почему. Есть ли у вас какие-либо идеи? Спасибо!

UPDATE Добавляя * ngIf в контейнер, содержащий список узлов, он работает.

<div *ngIf="tree$">
    <div *ngFor="let node of (tree$ | async).nodes" class="node-list">
        {{ node.title }}
    </div>
</div>

Но я до сих пор не понимаю, почему. Не могли бы вы объяснить это поведение, пожалуйста?

Ответы [ 2 ]

1 голос
/ 08 июля 2019

(tree $ | async) .nodes вызовет исключение, если дерево не инициализировано.

Попробуйте

<ng-container *ngIf="tree$ | async as tree">
  Number of nodes: {{ tree.nodes.length }}
  <div *ngFor="let node of tree.nodes" class="node-list">
    {{ node.title }}
  </div>
</ng-container>

Это не приведет к падению, если дерево не определеноперед отправкой первого действия.

0 голосов
/ 08 июля 2019

ChangeDetectionStrategy.OnPush предназначен для повышения производительности компонента за счет игнорирования внутренней проверки изменений в компоненте и его директивах.Это только проверит изменения для некоторых передающих декораторов, таких как @Input.Таким образом, в этом случае, даже если мы объявим tree$ как async, компонент не сможет обнаружить это обновление для обновления до DOM.Число узлов в шаблоне изменяется, потому что length является неизменным встроенным свойством для любого Array в Javascript, который присваивается другой ячейке памяти при каждом изменении его значения.Напротив, (tree$ | async).nodes относится к той же ячейке памяти, даже если ее свойство изменено.

Существует несколько опций, которые вы можете проверить, чтобы исправить это:

...