Как заставить рендеринг компонента в Angular 2? В целях отладки при работе с Redux я хотел бы заставить компонент перерисовать его, это возможно?
Как принудительно перепрофилировать компонент в Angular 2?
Ответ 1
Рендеринг происходит после обнаружения изменений. Для принудительного обнаружения изменений, чтобы значения свойств компонентов, которые изменились, были переданы в DOM (а затем браузер отобразит эти изменения в представлении), вот несколько вариантов:
-  ApplicationRef.tick() - аналогично Angular 1 $rootScope.$digest()- т$rootScope.$digest()Проверить полное дерево компонентов
-  NgZone.run(callback) - аналогично $rootScope.$apply(callback)- т$rootScope.$apply(callback)Оценивает функцию обратного вызова внутри зоны Angular 2. Я думаю, но я не уверен, что это заканчивается проверкой полного дерева компонентов после выполнения функции обратного вызова.
-  ChangeDetectorRef.detectChanges() - аналогично $scope.$digest()- т.е. проверять только этот компонент и его дочерние элементы
 Вам нужно будет импортировать, а затем внедрить ApplicationRef, NgZone или ChangeDetectorRef в ваш компонент.
Для вашего конкретного сценария я бы порекомендовал последний вариант, если изменился только один компонент.
Ответ 2
tx, нашел обходной путь, в котором я нуждался:
  constructor(private zone:NgZone) {
    // enable to for time travel
    this.appStore.subscribe((state) => {
        this.zone.run(() => {
            console.log('enabled time travel');
        });
    });
run zone.run заставит компонент повторно выполнить рендеринг
Ответ 3
Подход ChangeDetectorRef
import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
export class MyComponent {
    constructor(private cdr: ChangeDetectorRef) { }
    selected(item: any) {
        if (item == 'Department')
            this.isDepartment = true;
        else
            this.isDepartment = false;
        this.cdr.detectChanges();
    }
}
Ответ 4
Другие ответы здесь предоставляют решения для запуска циклов обнаружения изменений, которые обновят представление компонента (что не совпадает с полным повторным рендерингом).
Полный повторный рендеринг, который приведет к уничтожению и повторной инициализации компонента (вызов всех хуков жизненного цикла и перестроение представления), можно выполнить с помощью ng-template, ng-container и ViewContainerRef следующим образом:
<div>
  <ng-container #outlet >
  </ng-container>
</div>
<ng-template #content>
  <child></child>
</ng-template>
Затем в компоненте, имеющем ссылку как на #outlet, так и на #content, мы можем очистить содержимое торговых точек и вставить другой экземпляр дочернего компонента:
@ViewChild("outlet", {read: ViewContainerRef}) outletRef: ViewContainerRef;
@ViewChild("content", {read: TemplateRef}) contentRef: TemplateRef<any>;
private rerender() {
    this.outletRef.clear();
    this.outletRef.createEmbeddedView(this.contentRef);
}
Дополнительно исходный контент должен быть вставлен в ловушку AfterContentInit:
ngAfterContentInit() {
    this.outletRef.createEmbeddedView(this.contentRef);
}
Полное рабочее решение можно найти здесь https://stackblitz.com/edit/angular-component-rerender.
Ответ 5
Я принудительно перезагружаю свой компонент, используя * ngIf.
Все компоненты внутри моего контейнера возвращаются к крюкам полного жизненного цикла.
В шаблоне:
<ng-container *ngIf="_reload">
    components here 
</ng-container>
Тогда в файле ts:
public _reload = true;
private reload() {
    setTimeout(() => this._reload = false);
    setTimeout(() => this._reload = true);
}
Ответ 6
ChangeDetectorRef.detectChanges() обычно является наиболее сфокусированным способом сделать это. ApplicationRef.tick() обычно слишком сложный подход кувалдой.
Чтобы использовать ChangeDetectorRef.detectChanges(), вам понадобится это вверху вашего компонента:
import {  ChangeDetectorRef } from '@angular/core';
... тогда обычно вы называете это псевдонимом, когда вставляете его в свой конструктор следующим образом:
constructor( private cdr: ChangeDetectorRef ) { ... }
Затем в соответствующем месте вы называете это так:
this.cdr.detectChanges();
Место, куда вы звоните ChangeDetectorRef.detectChanges(), может быть очень важным. Вам необходимо полностью понять жизненный цикл и то, как именно ваше приложение функционирует и отображает его компоненты. Здесь нет альтернативы тому, чтобы полностью выполнить домашнюю работу и убедиться, что вы понимаете жизненный цикл Angular наизнанку. Затем, как только вы поймете это, вы сможете использовать ChangeDetectorRef.detectChanges() надлежащим образом (иногда очень легко понять, где вы должны его использовать, в других случаях он может быть очень сложным).
