🌵

场景 - 强制刷新 Angular 组件

 

使用 ChangeDetectorRef

Angular 中的组件不会自动刷新,因为这会导致性能问题。但是,有时候我们仍然需要强制刷新组件,例如当我们更改了组件中的某些属性,但是这些属性并未绑定到组件的视图中时。
在这种情况下,我们可以使用 Angular 的 ChangeDetectorRef 类中的 detectChanges() 方法来强制刷新组件。我们可以通过注入 ChangeDetectorRef 类来访问它,然后在需要刷新组件时调用它的 detectChanges() 方法。
例如:
import { ChangeDetectorRef } from '@angular/core';

@Component({
  selector: 'my-component',
  templateUrl: './my-component.html',
})
export class MyComponent {
  constructor(private cdr: ChangeDetectorRef) {
    // ...
  }

  someMethod() {
    // Update some property of the component
    this.myProperty = 'new value';

    // Force the component to refresh
    this.cdr.detectChanges();
  }
}
 
 
除了使用 detectChanges() 方法外,还可以通过使用 Angular 的 async pipe 来实现类似的效果。
 

使用 async pipe

 
async pipe 会自动订阅可观察对象并在值更新时自动刷新组件。例如:
import { Observable } from 'rxjs';

@Component({
  selector: 'my-component',
  templateUrl: './my-component.html',
})
export class MyComponent {
  myProperty$: Observable<any>;

  constructor() {
    // Create an observable that emits a new value every second
    this.myProperty$ = interval(1000).pipe(map(x => x * x));
  }

  someMethod() {
    // Update the observable to emit a new value
    this.myProperty$.next('new value');
  }
}
然后在组件的模板中使用 async pipe 来绑定可观察对象:
<p>{{ myProperty$ | async }}</p>
这样,每当 myProperty$ 可观察对象发出新值时,组件的视图就会自动刷新。
上面提到的两种方法都可以用于强制刷新 Angular 组件,具体使用哪种方法取决于你的需求。
 

使用 ChangeDetectorRef 的实际例子

// html
<discuss-post-comments
  
 

也可以手动的添加模版删除模版做到替换

最基本的方法是将要重新渲染的元素包装在一个 ng-template 元素中,该元素被渲染到 ng-container 中。在重新渲染时,您可以只清除 ng-container 的内容并从 ng-element 创建一个新组件。
您的模板看起来像这样:
<div>
  <ng-container #outlet [ngTemplateOutlet]="content">
  </ng-container>
</div>

<ng-template #content>
  <child-component></child-component>
</ng-template>
 
在您的 TypeScript 中,您可以使用 @ViewChild 访问 content 和 outlet 元素以进行重新渲染
export class AppComponent {
  @ViewChild('outlet', { read: ViewContainerRef }) outletRef: ViewContainerRef;
  @ViewChild('content', { read: TemplateRef }) contentRef: TemplateRef<any>;

  public rerender() {
    this.outletRef.clear();
    this.outletRef.createEmbeddedView(this.contentRef);
  }
}
 
具体内容参见下面这篇文章: