代码之家  ›  专栏  ›  技术社区  ›  Chris W.

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

  •  0
  • Chris W.  · 技术社区  · 6 年前

    我用 react-ace 在我的react应用程序中创建css文本编辑器。

    看起来像…

    import Ace from 'react-ace'
    
    ...
      <Ace 
        mode="css" 
        value={value} 
        onChange={onValueChange} 
        onValidate={onValidate} 
        ...
      />
    ...
    

    这可以很好地工作,并很好地显示css语法错误和警告。此外, onValidate 返回错误/警告“annotations”数据结构。

    但是,在应用程序的其他地方,需要运行这个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;
    };
    

    但是,此函数返回的注释总是 [] !我想这是因为我 访问 注释setter/getter接口,而不是实际运行注释创建者。但我不知道这些注释实际上是什么工作的。

    我看过 Creating a Syntax Highlighter for Ace ,但不知道是否需要/为什么需要一个web工作者参与其中。

    谢谢!

    0 回复  |  直到 6 年前
        1
  •  2
  •   Chris W.    6 年前

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

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

    docs

    请注意,当前每个EditSession都会创建一个新的工作进程,因此最好对现有的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);
        });
      });
    };