对于使用如下<ng-content>转换为另一个组件的组件,不会调用ngAfterViewInit生命周期挂钩:
<app-container [showContent]="showContentContainer">
<app-input></app-input>
</app-container>然而,它在没有<ng-content>的情况下工作良好。
<app-input *ngIf="showContent"></app-input>容器组件定义为:
@Component({
selector: 'app-container',
template: `
<ng-container *ngIf="showContent">
<ng-content></ng-content>
</ng-container>
`
})
export class AppContainerComponent {
@Input()
showContentContainer = false;
@Input()
showContent = false;
}输入组件定义为:
@Component({
selector: 'app-input',
template: `<input type=text #inputElem />`
})
export class AppInputComponent implements AfterViewInit {
@ViewChild("inputElem")
inputElem: ElementRef<HTMLInputElement>;
ngAfterViewInit() {
console.info("ngAfterViewInit fired!");
this.inputElem.nativeElement.focus();
}
}在这里看一个活生生的例子:https://stackblitz.com/edit/angular-playground-vqhjuh
发布于 2019-11-16 05:10:53
这里有两个问题:
<ng-content>实例化以包括它们时实例化。(参见https://github.com/angular/angular/issues/13921)ngAfterViewInit并不表示组件已附加到DOM,只是表示视图已实例化。(请参阅https://github.com/angular/angular/issues/13925)在这种情况下,问题可以通过解决它们中的任何一个来解决:
在许多情况下,两者都可能是合适的。
但是,选项#2使用自定义指令非常容易处理,为了完整起见,我将其包含在这里:
@Directive({
selector: "[attachedToDom],[detachedFromDom]"
})
export class AppDomAttachedDirective implements AfterViewChecked, OnDestroy {
@Output()
attachedToDom = new EventEmitter();
@Output()
detachedFromDom = new EventEmitter();
constructor(
private elemRef: ElementRef<HTMLElement>
) { }
private wasAttached = false;
private update() {
const isAttached = document.contains(this.elemRef.nativeElement);
if (this.wasAttached !== isAttached) {
this.wasAttached = isAttached;
if (isAttached) {
this.attachedToDom.emit();
} else {
this.detachedFromDom.emit();
}
}
}
ngAfterViewChecked() { this.update(); }
ngOnDestroy() { this.update(); }
}它可以像这样使用:
<input type=text
(attachedToDom)="inputElem.focus()"
#inputElem />发布于 2019-11-15 07:01:41
如果你检查你的stackblitz的控制台,你会看到事件在按下任何按钮之前就被触发了。我只能认为所有被投影的东西都会在你声明它的地方初始化/构造。
所以在你的例子中,就在这几行之间
<app-container [showContent]="showContentContainer">
{{test()}}
<app-input></app-input>
</app-container>如果你在app容器中添加了一个测试函数,它会被立即调用。因此,<app-input>也将立即构建。因为ngAfterVieWInit只会被调用一次(https://angular.io/guide/lifecycle-hooks),这是它已经被调用的地方。
但是,在AppInputComponent中添加以下代码有点奇怪
ngOnDestroy() {
console.log('destroy')
}该组件实际上将被立即销毁,并且永远不会再次初始化(添加构造函数或onInit日志进行检查)。
https://stackoverflow.com/questions/58867263
复制相似问题