Подтвердить что ты не робот

Draftjs, как инициировать редактор с контентом

Наткнулся на этот классный текстовый редактор draft.js по facebook. Я пытаюсь следовать примеру в github, но я хочу создать редактор с содержимым вместо пустого редактора.

var EditorState = Draft.EditorState;

var RichEditor = React.createClass({
   getInitialState(){
      return {editorState: EditorState.createWithContent("Hello")}
      //the example use this code to createEmpty editor
     // return ({editorState: EditorState.createEmpty()})
   }
});

запустите его, но я получаю сообщение об ошибке "Uncaught TypeError: contentState.getBlockMap не является функцией"

4b9b3361

Ответ 2

Я создал набор пакетов для DraftJS, чтобы помочь с импортом и экспортом контента (HTML/Markdown). Я использую их в своем проекте react-rte. Тот, который вы, вероятно, ищете, это: draft-js-import-html на npm.

npm install draft-js-import-html

Пример того, как вы можете его использовать:

var stateFromHTML = require('draft-js-import-html').stateFromHTML;
var EditorState = Draft.EditorState;

var RichEditor = React.createClass({
  getInitialState() {
    let contentState = stateFromHTML('<p>Hello</p>');
    return {
      editorState: EditorState.createWithContent(contentState)
    };
  }
});

Модули, которые я опубликовал:

Ответ 3

Были некоторые изменения API, для ясности в этих примерах используется последний API, который v0.10.0.

Существует много способов, но в основном у вас есть три варианта в зависимости от того, хотите ли вы использовать обычный текст, стилизованный текст или разметку html для ресурса контента.

Какой простой текст очевиден, но для стилизованного текста вам нужно использовать либо сериализованный объект javasript, либо html-разметку.

Давайте начнем с простого текстового примера:

import {Editor, EditorState} from 'draft-js';

class MyEditor extends Component{

  constructor(props) {
    super(props);

    const plainText = 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.';
    const content = ContentState.createFromText(plainText);

    this.state = { editorState: EditorState.createWithContent(content)};

    this.onChange = (editorState) => {
      this.setState({editorState});
    }
  }
  render(){
    return(
      <Editor
        editorState={this.state.editorState}
        onChange={this.onChange}
      />
    )
  }
}

Для импорта стильного контента Draft.js предоставляет convertFromRaw и convertFromHTML служебные функции.

Функция convertFromRaw принимает в качестве параметра необработанный объект javascript. Здесь мы используем javascript-объект JSON в качестве источника контента:

class MyEditor extends Component{

  constructor(props) {
    super(props);

    const rawJsText = `{
      "entityMap": {},
      "blocks": [
        {
          "key": "e4brl",
          "text": "Lorem ipsum dolor sit amet, consectetuer adipiscing elit.",
          "type": "unstyled",
          "depth": 0,
          "inlineStyleRanges": [
            {
              "offset": 0,
              "length": 11,
              "style": "BOLD"
            },
            {
              "offset": 28,
              "length": 29,
              "style": "BOLD"
            },
            {
              "offset": 12,
              "length": 15,
              "style": "ITALIC"
            },
            {
              "offset": 28,
              "length": 28,
              "style": "ITALIC"
            }
          ],
          "entityRanges": [],
          "data": {}
        },
        {
          "key": "3bflg",
          "text": "Aenean commodo ligula eget dolor.",
          "type": "unstyled",
          "depth": 0,
          "inlineStyleRanges": [],
          "entityRanges": [],
          "data": {}
        }
      ]
    }`;

    const content  = convertFromRaw(JSON.parse(rawJsText));
    this.state = { editorState: EditorState.createWithContent(content)};

    this.onChange = (editorState) => {
      this.setState({editorState});
    }
  }
  render(){
    return(
      <Editor
        editorState={this.state.editorState}
        onChange={this.onChange}
      />
    )
  }
}

Draft.js обеспечивает функцию convertToRaw, чтобы вы могли преобразовать состояние вашего редактора в необработанный объект javascript для долгосрочного хранения.

И, наконец, вот как вы это делаете с html-разметкой:

class MyEditor extends Component{

  constructor(props) {
    super(props);

    const html = `<p>Lorem ipsum <b>dolor</b> sit amet, <i>consectetuer adipiscing elit.</i></p>
      <p>Aenean commodo ligula eget dolor. <b><i>Aenean massa.</i></b></p>`;

      const blocksFromHTML = convertFromHTML(html);
      const content = ContentState.createFromBlockArray(
        blocksFromHTML.contentBlocks,
        blocksFromHTML.entityMap
      );

    this.state = { editorState: EditorState.createWithContent(content)};

    this.onChange = (editorState) => {
      this.setState({editorState});
    }
  }
  render(){
    return(
      <Editor
        editorState={this.state.editorState}
        onChange={this.onChange}
      />
    )
  }
}

Ответ 4

Вы можете использовать convertFromHTML для импорта html с помощью createWithContent

import { convertFromHTML, ContentState } from 'draft-js'

const html = '<div><p>hello</p></div>'
const blocksFromHTML = convertFromHTML(html)
const content = ContentState.createFromBlockArray(blocksFromHTML)
this.state = { 
  editorState: EditorState.createWithContent(content)
}

Как показано в черновике convertFromHtml example. Обратите внимание, что версия 0.9.1 не может импортировать изображения, тогда как 0.10.0 может.

В 0.10.0 createFromBlockArray изменяется на:

const content = ContentState.createFromBlockArray(
  blocksFromHTML.contentBlocks,
  blocksFromHTML.entityMap
)

Ответ 5

Я нашел, что это чистый способ делать вещи с богатой функциональностью. Вы можете добавить дополнительные плагины в будущем, экспортировать контент как .md и т.д., Не изменяя структуру вашего компонента.

import Draft from 'draft-js';

import DraftPasteProcessor from 'draft-js/lib/DraftPasteProcessor';
const { EditorState, ContentState } = Draft;
import Editor from 'draft-js-plugins-editor';

import createRichButtonsPlugin from 'draft-js-richbuttons-plugin';
const richButtonsPlugin = createRichButtonsPlugin();

class DescriptionForm extends React.Component {

state = {
  editorState: this._getPlaceholder(),
}

_getPlaceholder() {
  const placeholder = 'Write something here';
  const contentHTML = DraftPasteProcessor.processHTML(placeholder);
  const state = ContentState.createFromBlockArray(contentHTML);
  return Draft.EditorState.createWithContent(state);
}

_onChange(editorState) {
  this.setState({
    editorState,
  });
}

render () {
    let { editorState } = this.state;
    return (
      <div>
          <Editor
            editorState={editorState}
            onChange={this._onChange.bind(this)}
            spellCheck={false}
            plugins={[richButtonsPlugin, videoPlugin]}
          />
      </div>
    );
  }
}

Ответ 6

Когда вам нужно запустить редактор с открытым текстом.

Используйте EditorState.createWithContent и ContentState.createFromText методов. Рабочий пример - https://jsfiddle.net/levsha/3m5780jc/

constructor(props) {
  super(props);

  const initialContent = 'Some text';
  const editorState = EditorState.createWithContent(ContentState.createFromText(initialContent));

  this.state = {
    editorState
  };
}

Когда вам нужно запустить редактор с содержимым из строки разметки html.

Используйте convertFromHTML и ContentState.createFromBlockArray. Рабочий пример - https://jsfiddle.net/levsha/8aj4hjwh/

constructor(props) {
  super(props);

  const sampleMarkup = `
        <div>
        <h2>Title</h2>
        <i>some text</i>
      </div>
    `;

  const blocksFromHTML = convertFromHTML(sampleMarkup);
  const state = ContentState.createFromBlockArray(
    blocksFromHTML.contentBlocks,
    blocksFromHTML.entityMap
  );

  this.state = {
    editorState: EditorState.createWithContent(state),
  };
}

Когда у вас есть массив строк, и вы хотите запустить редактор с некоторыми типами блоков draft.js по умолчанию.

Вы можете создать массив ContentBlocks с конструктором new ContentBlock(...) и передать его методу ContentState.createFromBlockArray. Рабочий пример с unordered-list-item - https://jsfiddle.net/levsha/uy04se6r/

constructor(props) {
  super(props);
  const input = ['foo', 'bar', 'baz'];

  const contentBlocksArray = input.map(word => {
    return new ContentBlock({
      key: genKey(),
      type: 'unordered-list-item',
      characterList: new List(Repeat(CharacterMetadata.create(), word.length)),
      text: word
    });
  });

  this.state = {
    editorState: EditorState.createWithContent(ContentState.createFromBlockArray(contentBlocksArray))
  };
}

Когда вам нужно запустить редактор с контентом из ContentState исходной структуры JS.

Если вы ранее сохранили состояние содержимого в исходной структуре JS с помощью convertToRaw (читайте этот ответ). Вы можете запустить редактор с помощью convertFromRaw. Рабочий пример - https://jsfiddle.net/levsha/tutc419a/

constructor(props) {
  super(props);

  this.state = {
    editorState: EditorState.createWithContent(convertFromRaw(JSON.parse(editorStateAsJSON)))
  };
}