Как использовать валидатор редактора Ace без создания экземпляра редактора Ace? - PullRequest
1 голос
/ 26 марта 2019

Я использую react-ace для создания текстового редактора CSS в моем приложении React.

Это выглядит примерно так ...

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 , но не понимаю, зачем / зачем здесь нужно привлекать веб-работника.

Спасибо!

1 Ответ

2 голосов
/ 26 марта 2019

Это не работает, потому что editSession использует веб-работника для генерации аннотаций, которые являются асинхронными:

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

* документы 1005 *

Обратите внимание, что в настоящее время каждый editSession создает нового работника, поэтому лучше использовать setValue на существующем экземпляре editSession или вызвать 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);
    });
  });
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...