gpt4 book ai didi

javascript - ngAfterViewInit 未在 ng-content 中触发

转载 作者:行者123 更新时间:2023-11-29 20:28:10 25 4
gpt4 key购买 nike

ngAfterViewInit使用 <ng-content> 嵌入到另一个组件中的组件未调用生命周期 Hook 像这样:

<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

最佳答案

这里有两个问题:

  1. 子组件与父组件一起实例化,而不是在 <ng-content> 时被实例化以包含它们。 (参见 https://github.com/angular/angular/issues/13921)
  2. ngAfterViewInit 表示组件已附加到 DOM,只是 View 已实例化。 (参见 https://github.com/angular/angular/issues/13925)

在这种情况下,可以解决其中一个问题:

  1. 容器指令可以重写为仅在适当时实例化内容的结构指令。请在此处查看示例:https://stackblitz.com/edit/angular-playground-mrcokp
  2. 可以重写输入指令以对实际附加到 DOM 使用react。一种方法是编写一个指令来处理这个问题。请在此处查看示例:https://stackblitz.com/edit/angular-playground-sthnbr

在许多情况下,两者都做可能是合适的。

但是,选项 #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 />

关于javascript - ngAfterViewInit 未在 ng-content 中触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58867263/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com