有没有一种方法可以手动重新渲染组件,例如当用户点击按钮时?
我看过类似的帖子,但这些方法对我都不起作用,例如这里
例如,
renderComponent() {
// force component re-render
}
有没有一种方法可以手动重新渲染组件,例如当用户点击按钮时?
我看过类似的帖子,但这些方法对我都不起作用,例如这里
例如,
renderComponent() {
// force component re-render
}
如果您想操作视图(添加、移除或重新附加),这里是一个示例:
import { Component, ViewContainerRef, AfterViewInit, ViewChild, ViewRef,TemplateRef} from '@angular/core';
import { ChildComponent } from './child.component';
@Component({
selector: 'host-comp',
template: `
<h1>I am a host component</h1>
<ng-container #vc><ng-container>
<br>
<button (click)="insertChildView()">Insert Child View</button>
<button (click)="removeChildView()">Remove Child View</button>
<button (click)="reloadChildView()">Reload Child View</button>
<ng-template #tpl>
<child-comp><child-comp>
<ng-template>
`
})
export class HostComponent implements AfterViewInit{
@ViewChild('vc', {read: ViewContainerRef}) vc: ViewContainerRef;
@ViewChild('tpl', {read: TemplateRef}) tpl: TemplateRef<any>;
childViewRef: ViewRef;
constructor(){}
ngAfterViewInit(){
this.childViewRef = this.tpl.createEmbeddedView(null);
}
insertChildView(){
this.vc.insert(this.childViewRef);
}
removeChildView(){
this.vc.detach();
}
reloadChildView(){
this.removeChildView();
setTimeout(() =>{
this.insertChildView();
}, 3000);
}
}
如果我理解你的问题正确,你在问关于ChangeDetectionStrategy,Angular有两个选项
enum ChangeDetectionStrategy {
OnPush: 0
Default: 1
}
如果您使用默认设置,它将在每次事件(如单击)后"重新渲染"您的视图。
如果您使用OnPush,它将在使用带有| async的observable时重新渲染,或者您可以注入ChangeDetectorRef并“请求”重新渲染。
constructor(private ref: ChangeDetectorRef) {
setInterval(() => {
this.numberOfTicks++;
// the following is required, otherwise the view will not be updated
this.ref.markForCheck();
}, 1000);
}
但是,只有当你运行在 Angular 内部时,这才是真实的。有时,如果你正在监听外部服务并且运行在 NgZone 之外,你需要执行 ngZone.run。
this._ngZone.run(() => { console.log('Do change detection here'); });
detectChanges()
或者 markForCheck()
来通知 Angular 再次渲染组件。/**
* Example:
*
* <ng-container *rerender='changingInput'>
* this content will be re-rendered everytime `changingInput` changes
* </ng-container>
*/
import { Directive,
Input,
TemplateRef,
ViewContainerRef } from '@angular/core';
@Directive({
selector: '[rerender]'
})
export class RerenderDirective {
constructor(
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef
) {}
// if detects changes of the input `val`, clear and rerender the view
@Input() set rerender(val) {
this.viewContainer.clear();
this.viewContainer.createEmbeddedView(this.templateRef);
}
}
请查看我的 Gist 获取最新更新。
<app-component1 *ngIf="FLAG"></app-component1>
TS
constructor(private changeDetectorRef: ChangeDetectorRef) {
this.FLAG = true
}
renderComponent() {
this.FLAG = false;
this.changeDetectorRef.detectChanges();
this.FLAG = true;
}
您可以通过临时覆盖路由重用策略来欺骗路由器渲染当前组件的最新副本.. 在其他一些SO答案中发现 :)
在ngOnInit中:
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
ngx-rerender
https://www.npmjs.com/package/ngx-rerender。<stuff-to-rerender *mcRerender="trigger">Some Content</stuff-to-rerender>
class MyComponent {
public trigger: number = 0;
public rerender(): void {
this.trigger++;
}
}
rerender
函数,您的组件都将被完全重新渲染。我尝试了这个帖子中的答案,但是我不得不进行修改才能使其工作。让我分享我的可行代码。
.html-----------------
<button (click)="addChild()">ADD</button>
<button (click)="removeChild()">REMOVE</button>
<ng-container #vc></ng-container>
<ng-template #tpl>
<child-component id ="child-modal"></child-component>
</ng-template>
.ts---------------------
import { Component, ViewChild, ViewContainerRef, TemplateRef, ViewRef } from '@angular/core';
export class ParentComponent{
@ViewChild('vc', { read: ViewContainerRef }) vc: ViewContainerRef;
@ViewChild('tpl', { read: TemplateRef }) tpl: TemplateRef<any>;
addChild(){
let view = this.tpl.createEmbeddedView(null);
this.vc.insert(view);
}
removeChild(){
this.vc.clear();
}
这个页面很有帮助。确保在addchild()
中添加let view = this.tpl.createEmbeddedView(null);
ChangeDetectorRef.detectChanges()
了吗? - candidJ