我有一个注入 Ace 编辑器的 Angular 组件。有时在日志中(非常罕见)我可以看到以下错误:
Error: ace.edit can't find div #aceEditor
at ie.edit (https://stepindev.com/ru/main.fcb9335868d1e005.js:1:1267133)
at t.ngAfterViewInit (https://stepindev.com/ru/main.fcb9335868d1e005.js:1:467814)
我一直无法重现这个问题。我不明白是什么原因造成的。我的理解是,当 ngAfterViewInit 启动的那一刻,DOM 就准备好了,可以使用了。
那么问题是问题的原因是什么?
组件模板:
<div id="aceEditor" #editor></div>
<!--Don't recreate console with *ngIf. It must exists all the time to be able to capture all console input/output-->
<sid-console #console class="console" (change)="onIOAppeared()" hidden></sid-console>
<ng-content></ng-content>
ngAfterViewInit 处理程序
import * as ace from 'ace-builds'
...
ngAfterViewInit(): void {
this.editor = ace.edit('aceEditor');
this.editor.setTheme('ace/theme/textmate');
this.editor.session.setMode('ace/mode/python');
this.editor.setOptions({
fontSize: '16pt'
});
this.editor.on("change", delta => this.change.emit(delta))
window.addEventListener(this.resizeEvenName, this.resizeEventListener, false);
// resize after all components above this one are settled. So we can get the correct "top" value
window.setTimeout(() => this.resizeComponents(), 0);
}
包含此组件的容器是根据 HTTP 请求动态创建的(使用 *ngIf):
<sid-robot-python-view [task]="$any(task)" *ngIf="isRobotPythonTask()" data-testId="robot-python-view"></sid-robot-python-view>
我希望错误永远不会发生。它是针对 Windows 上的 Chrome 130.0 和 Chrome 109.0 记录的。我使用 Angular 14。
根据Ace编辑器文档 - 编辑函数接受
element
而不是字符串,您可以尝试此方法而不是传入字符串吗?
import * as ace from 'ace-builds'
...
...
@ViewChild('aceEditor') aceEditor: ElementRef<any>;
...
ngAfterViewInit(): void {
if(this.editor?.nativeElement) {
this.editor = ace.edit(this.editor.nativeElement);
this.editor.setTheme('ace/theme/textmate');
this.editor.session.setMode('ace/mode/python');
this.editor.setOptions({
fontSize: '16pt'
});
this.editor.on("change", delta => this.change.emit(delta))
window.addEventListener(this.resizeEvenName, this.resizeEventListener, false);
// resize after all components above this one are settled. So we can get the correct "top" value
window.setTimeout(() => this.resizeComponents(), 0);
}
}