2017-02-06 3 views
3

Я пытаюсь сохранить сохраненный контент в редакторе (после обновления, например).Как отобразить сохраненные данные Draft-JS в редакторе? (React + Meteor)

  • В настоящее время контент поступает из базы данных в консоль.log и отображается как ожидается.
  • Но я не могу сохранить его в редакторе.

[Изменить] Удалена ссылка проекта проекта, см. Решение ниже.

Я использую:
Draft-JS
react-draft-wysiwyg

Вот в ~/импорт/коллекции/bins.js

import { Mongo } from 'meteor/mongo'; 

    Meteor.methods({ 
     'bins.insert': function() { 
     return Bins.insert({ 
      createdAt: new Date(), 
      content: '', 
      sharedWith: [], 
      ownerId: this.userId 
     }); 
     }, 

     'bins.remove': function(bin) { 
     return Bins.remove(bin); 
     }, 

     'bins.update': function(bin, content) { 
     return Bins.update(bin._id, { $set: { content } }); 
     } 
    }); 

    export const Bins = new Mongo.Collection('bins'); 

~/клиент/компоненты/Урны/bins_main.js

import React, { Component } from 'react'; 
    import { createContainer } from 'meteor/react-meteor-data'; 
    import { Bins } from '../../../imports/collections/bins'; 
    import BinsEditor from './bins_editor'; 

    class BinsMain extends Component { 
     render() { 
     if (!this.props.bin) { return <div>Loading...</div>; } 

     return (
      <div> 
      <BinsEditor bin={this.props.bin} /> 
      </div> 
     ); 
     } 
    } 

    export default createContainer((props) => { 
     const { binId } = props.params; 
     Meteor.subscribe('bins'); 

     return { bin: Bins.findOne(binId) }; 
    }, BinsMain); 
+0

Можете ли вы предоставить более подробную информацию ион пожалуйста? Это звучит как проблема с вашей подпиской на данные, код React - это только часть рендеринга – Mikkel

+0

Несомненно, спасибо, я только что отредактировал @Mikkel – Sbe88

+0

Я не пробовал ваш код, но вот 2 вопроса, которые могут вам помочь. Почему вы не обновляете состояние в методе handleChange с помощью this.setState ({editorState})? Какая поддержка defaultEditorState в редакторе, возможно, поддержка editorState - это тот, который вы ищете? Надеюсь, поможет. –

ответ

1

example app - полный пример с помощью Draft-JS + React + Meteor + Material-UI + Accounts-UI + Material-UI-Accounts.

Вы можете

  • Создать ящик, связанный с вашей учетной записью пользователя (если в системе)
  • Редактировать бин
  • автосохранение бен при редактировании

Вот в bins_editor.js

import React from "react"; 
    import {Editor, EditorState, ContentState, RichUtils, convertToRaw, convertFromRaw} from "draft-js"; 

    export default class BinsEditor extends React.Component { 

     constructor(props) { 
     super(props); 

     let editorState; 


     if (!this.props.bin.content) { 
      this.state = {editorState: EditorState.createEmpty()}; 
      console.log('empty'); 
      } else { 
      const rawContent = this.props.bin.content; 
      const parsedContent = convertFromRaw(JSON.parse(rawContent)); 

      this.state = {editorState: EditorState.createWithContent(parsedContent)}; 
      console.log('not empty'); 
      } 
      this.focus =() => this.refs.editor.focus(); 
      this.onChange = (editorState) => { 
       this.setState({editorState}); 
       const contentState = editorState.getCurrentContent(); 
       const rawContent = JSON.stringify(convertToRaw(contentState)); 

       Meteor.call('bins.update', this.props.bin, rawContent); 
       console.log(rawContent); 
      } 

      this.handleKeyCommand = (command) => this._handleKeyCommand(command); 
      this.toggleBlockType = (type) => this._toggleBlockType(type); 
      this.toggleInlineStyle = (style) => this._toggleInlineStyle(style); 
     } 

     _handleKeyCommand(command) { 
     const {editorState} = this.state; 
     const newState = RichUtils.handleKeyCommand(editorState, command); 
     if (newState) { 
      this.onChange(newState); 
      return true; 
     } 
     return false; 
     } 

     _toggleBlockType(blockType) { 
     this.onChange(
      RichUtils.toggleBlockType(
      this.state.editorState, 
      blockType 
     ) 
     ); 
     } 

     _toggleInlineStyle(inlineStyle) { 
     this.onChange(
      RichUtils.toggleInlineStyle(
      this.state.editorState, 
      inlineStyle 
     ) 
     ); 
     } 

     render() { 
     const {editorState} = this.state; 

     // If the user changes block type before entering any text, we can 
     // either style the placeholder or hide it. Let's just hide it now. 
     let className = 'RichEditor-editor'; 
     var contentState = editorState.getCurrentContent(); 
     if (!contentState.hasText()) { 
      if (contentState.getBlockMap().first().getType() !== 'unstyled') { 
      className += ' RichEditor-hidePlaceholder'; 
      } 
     } 

     return (
      <div className="RichEditor-root"> 
      <BlockStyleControls 
       editorState={editorState} 
       onToggle={this.toggleBlockType} 
      /> 
      <InlineStyleControls 
       editorState={editorState} 
       onToggle={this.toggleInlineStyle} 
      /> 
      <div className={className} onClick={this.focus}> 
       <Editor 
       blockStyleFn={getBlockStyle} 
       customStyleMap={styleMap} 
       editorState={editorState} 
       handleKeyCommand={this.handleKeyCommand} 
       onChange={this.onChange} 
       placeholder="Tell a story..." 
       ref="editor" 
       spellCheck={true} 
       /> 
      </div> 
      <div>{JSON.stringify(convertToRaw(editorState.getCurrentContent()))}</div> 
      </div> 
     ); 
     } 
    } 

    // Custom overrides for "code" style. 
    const styleMap = { 
     CODE: { 
     backgroundColor: 'rgba(0, 0, 0, 0.05)', 
     fontFamily: '"Inconsolata", "Menlo", "Consolas", monospace', 
     fontSize: 16, 
     padding: 2, 
     }, 
    }; 

    function getBlockStyle(block) { 
     switch (block.getType()) { 
     case 'blockquote': return 'RichEditor-blockquote'; 
     default: return null; 
     } 
    } 

    class StyleButton extends React.Component { 
     constructor() { 
     super(); 
     this.onToggle = (e) => { 
      e.preventDefault(); 
      this.props.onToggle(this.props.style); 
     }; 
     } 

     render() { 
     let className = 'RichEditor-styleButton'; 
     if (this.props.active) { 
      className += ' RichEditor-activeButton'; 
     } 

     return (
      <span className={className} onMouseDown={this.onToggle}> 
      {this.props.label} 
      </span> 
     ); 
     } 
    } 

    const BLOCK_TYPES = [ 
     {label: 'H1', style: 'header-one'}, 
     {label: 'H2', style: 'header-two'}, 
     {label: 'H3', style: 'header-three'}, 
     {label: 'H4', style: 'header-four'}, 
     {label: 'H5', style: 'header-five'}, 
     {label: 'H6', style: 'header-six'}, 
     {label: 'Blockquote', style: 'blockquote'}, 
     {label: 'UL', style: 'unordered-list-item'}, 
     {label: 'OL', style: 'ordered-list-item'}, 
     {label: 'Code Block', style: 'code-block'}, 
    ]; 

    const BlockStyleControls = (props) => { 
     const {editorState} = props; 
     const selection = editorState.getSelection(); 
     const blockType = editorState 
     .getCurrentContent() 
     .getBlockForKey(selection.getStartKey()) 
     .getType(); 

     return (
     <div className="RichEditor-controls"> 
      {BLOCK_TYPES.map((type) => 
      <StyleButton 
       key={type.label} 
       active={type.style === blockType} 
       label={type.label} 
       onToggle={props.onToggle} 
       style={type.style} 
      /> 
     )} 
     </div> 
    ); 
    }; 

    var INLINE_STYLES = [ 
     {label: 'Bold', style: 'BOLD'}, 
     {label: 'Italic', style: 'ITALIC'}, 
     {label: 'Underline', style: 'UNDERLINE'}, 
     {label: 'Monospace', style: 'CODE'}, 
    ]; 

    const InlineStyleControls = (props) => { 
     var currentStyle = props.editorState.getCurrentInlineStyle(); 
     return (
     <div className="RichEditor-controls"> 
      {INLINE_STYLES.map(type => 
      <StyleButton 
       key={type.label} 
       active={currentStyle.has(type.style)} 
       label={type.label} 
       onToggle={props.onToggle} 
       style={type.style} 
      /> 
     )} 
     </div> 
    ); 
    }; 
Смежные вопросы