首页 > 解决方案 > 如何在不实例化 Ace 编辑器实例的情况下使用 Ace 编辑器验证器?

问题描述

我用来react-ace在我的 React 应用程序中创建一个 CSS 文本编辑器。

这看起来像...

import Ace from 'react-ace'

...
  <Ace 
    mode="css" 
    value={value} 
    onChange={onValueChange} 
    onValidate={onValidate} 
    ...
  />
...

这工作得很好而且很漂亮——突出显示 CSS 语法错误和警告。此外,onValidate返回错误/警告“注释”数据结构。

然而,在应用程序的其他地方,需要运行在此 React Ace 组件中使用的相同验证器,但在此组件的上下文之外。本质上我需要value通过错误/警告注释系统传递内容,但不能实例化这个反应元素。

我尝试了以下方法:

import { EditSession } from 'brace'; # "brace" is the "module" compatible version of the ace editor that our "react-ace" uses
import 'brace/mode/css';

export const getCssAnnotations = (value)=> {
  const editSession = new EditSession(value);
  editSession.setMode('ace/mode/css');
  const annotations = editSession.getAnnotations();
  return annotations;
};

然而,这个函数返回的注解总是[]! 我认为这是因为我只是在访问注释设置器/获取器接口,而不是实际运行注释创建器。但我无法弄清楚注释实际上是如何正常工作的。

我查看了有关为 Ace 创建语法荧光笔的文档,但不明白是否/为什么需要在这里涉及网络工作者。

谢谢!

标签: javascriptcssreactjsace-editorreact-ace

解决方案


这不起作用,因为 editSession 使用 web worker 来生成异步注释:

editSession.on('changeAnnotation', () => {
    let annotations = editSession.getAnnotations();
    callback(null, annotations)
});

文档

请注意,当前每个 editSession 都会创建一个新的 worker,因此最好在现有的 editSession 实例上使用 setValue,或者在调用回调之前调用 editSession.destroy()


所以一个完整的解决方案可能看起来像:

const getAnnotationsPromise = (value, mode)=> {
  const editSession = new EditSession(value);
  editSession.setMode(`ace/mode/${mode}`);

  return new Promise((resolve)=> {
    editSession.on('changeAnnotation', () => {
      const annotations = editSession.getAnnotations();
      editSession.removeAllListeners('changeAnnotation');
      editSession.destroy();
      resolve(annotations);
    });
  });
};

推荐阅读