如何在不实例化Ace编辑器实例的情况下使用Ace编辑器验证器?

时间:2019-03-26 08:30:48

标签: javascript css reactjs ace-editor react-ace

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

看起来像...

import Ace from 'react-ace'

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

这很好而且很花哨-突出显示CSS语法错误和警告。另外,onValidate返回错误/警告“注释”数据结构。

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

我尝试了以下操作:

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;
};

但是,此函数返回的注释始终为[]!我认为这是因为我只是访问注释设置程序/获取程序接口,而实际上没有运行注释创建程序。但是我无法弄清楚注释实际上能正常工作。

我看过Creating a Syntax Highlighter for Ace上的文档,但是不知道是否/为什么需要网络工作者参与。

谢谢!

1 个答案:

答案 0 :(得分:2)

这不起作用,因为editSession使用Web Worker来生成异步的注释:

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

docs

请注意,当前每个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);
    });
  });
};