tinymce自定义按钮触发MatDialog未初始化,仅窗口resize后生效如何解决
问题原因
- 你遇到的是Angular 第三方库回调脱离NgZone上下文的典型问题:TinyMCE 是独立的第三方富文本编辑器,不属于Angular生态的组件,它内部的所有回调(包括setup配置里的按钮点击回调)默认运行在Angular的NgZone管理区域之外。
- Angular的变化检测只会响应NgZone内部的异步事件,因此你在回调中打开MatDialog的操作虽然执行成功,但Angular不会自动触发对应Dialog组件的初始化和视图渲染,只有调整窗口大小这类会触发全局变化检测的操作才能让Dialog正常加载。
- 你之前将setup逻辑挪到ngOnInit没有效果,是因为只要回调是由TinyMCE触发的,不管setup定义在哪个生命周期,执行时都会脱离NgZone上下文。
修复方案
步骤1:在组件中注入NgZone
先在你当前的组件中导入并注入NgZone服务:
import { NgZone } from '@angular/core'; import { MatDialog, MatDialogRef } from '@angular/material/dialog'; // 组件类构造函数注入 constructor( private dialog: MatDialog, private ngZone: NgZone // 新增NgZone注入 ) {}
步骤2:将打开Dialog的逻辑包裹在NgZone.run中
修改TinyMCE配置里的onAction回调,把打开Dialog的代码包裹进ngZone.run()方法,将执行上下文拉回Angular的管理区域:
tinyMceConfig: any = { menubar: false, plugins: ['advlist autolink lists link image charmap print preview hr anchor pagebreak','searchreplace wordcount visualblocks visualchars code fullscreen','insertdatetime media nonbreaking save table contextmenu directionality','emoticons template paste textcolor colorpicker textpattern'], toolbar1: 'insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | code | link Upload', setup: (editor) => { editor.ui.registry.addButton('Upload', { icon: 'browse', onAction: ()=> { // 把dialog逻辑包入ngZone.run this.ngZone.run(() => { const dialogRef: MatDialogRef<any> = this.dialog.open(UploadmediaComponent, { width: '95vw', disableClose: true, panelClass: 'uploadPanel'}); dialogRef.afterClosed().subscribe(res => { if (!res) { return; } res.forEach(image => { console.log(image.url); editor.insertContent(image.url); }); }); }) } }); } };
修改后点击按钮打开Dialog时,Angular就能正常检测到变化,自动完成Dialog组件的初始化和渲染。
内容的提问来源于stack exchange,提问作者Jay
相关产品推荐
相关产品推荐

