当前位置: 首页 > Web前端 > JavaScript

使用monaco-editor,registerCompletionItemProvider注册了多次,最终导致提示内容重复显示

时间:2023-03-27 15:29:19 JavaScript

最近项目实现了一个提示功能,输入某个符号,显示匹配的内容,类似代码提示功能。最终我选择了微软开发的一个js库monaco-editor,而vscode也是基于这个库开发的。在开发过程中,遇到了一些问题。因为文档不是很友好,搞了半天才解决问题。下面主要记录遇到的问题和解决方法。希望以后遇到这些问题的童鞋们能赶快避坑。遇到的问题及解决方法问题:在AntdModal中使用monaco-editor,显示Modal后关闭Modal,再次打开Modal,monaco-editor的提示内容会重复,显示几次Modal,相应的内容也会重复几次秒,如下图所示:解决思路一:调试后发现registerCompletionItemProvider方法被执行了多次。第一个猜测可能是插件创建了多次,没有被销毁。查阅了相应的文档,发现有一个插件提供了一个destroyed方法:monaco.editor.dispose()因此,尝试在组件被销毁之前调用上面的方法,但是运行后并没有生效。上面的问题依然存在,这个方法不行~思路二:既然registerCompletionItemProvider已经执行了很多次,那就给组件添加一个全局计数器count,组件注册一次后执行count+1一次。只有当count===0时,才会执行相应的插件注册逻辑,否则直接取缓存数据。部分代码片段如下:letcount=0;monaco.languages.registerCompletionItemProvider(languageName,{triggerCharacters:['['],provideCompletionItems:function(model,position,context){count=count+1;if(count===1){letsuggestions=[];如果(context.triggerCharacter==='['){[...dimensions,...modules].forEach((item,index)=>{suggestions.push({label:item.customName,insertText:`${item.customName}]`,kind:12,});});}return{suggestions};}},});这种方法简单粗暴,如果需要插件提示的内容是固定的,直接使用缓存数据就可以解决这个问题。但!!!我遇到的需求是提示的内容是根据接口动态抓取的。所以,这个方法还是不行~思路三:Google和百度都找不到满意的答案,于是去monaco-editor的GitHubissues找答案。一开始是根据关键字registerCompletionItemProvider搜索,没有发现类似的问题。然后尝试搜索provideCompletionItems关键字,最终在issues中找到了2个类似的问题,链接如下:https://github.com/microsoft/monaco-editor/issues/2217https://github.com/microsoft/monaco-editor/issues/2084最终解决方案:registerCompletionItemProvider注册创建时,将创建的对象存储如下:一起毁灭。代码如下:useEffect(()=>{//todo//xxxxxxreturn()=>{//destroymonacoProviderRef.current?.dispose();monacoRef.current?.dispose();};},[]);最终测试,bug完美解决!问题:设置编辑器默认主题,但是第一次显示Modal时,默认主题不生效,第一次后主题才会生效,如下图:设置默认主题如下:monaco.editor.defineTheme('myCoolTheme',{base:'vs',inherit:false,colors:{token:'value',foreground:'#00c1de'},rules:[{标记:'值',前景:'#00c1de'}],});解决方法是在官方文档中找到设置主题的api,发现上面的代码就是主题的定义操作。如果想第一次运行生效,需要手动设置上面定义的主题monaco.editor.setTheme('myCoolTheme');终于,问题解决了,效果如下:愿世上没有难解的bug!中秋节快乐!!!