2017-12-27 40 views
4

私の簡単なdraft.jsを使ってproject外部のフォームからアップロードした画像をエディタのコンテンツに挿入しようとしています。私が使用するエディタは、draftjsエディタを内部的に使用するreact-draft-wysiwyg です。全体のソースが含まれていDraft.jsは外部フォームからアップロードした画像を挿入できません

import React, { Component } from 'react'; 

class UploadForm extends Component { 

    state={ 
     lastImgUploaded:"" 
    }; 


    onChange(event){ 
     event.preventDefault(); 
     console.log("File Changed"); 

     const file=event.target.files[0]; 

     const reader = new window.FileReader(); 
     reader.onloadend=() => { 
      fetch('http://localhost:9090/image',{ 
      method: 'POST', 
      headers: { 
       'Accept': 'application/json', 
       'Content-Type': 'application/json', 
      }, 
      body: JSON.stringify({ 
       name: file.name, 
       data: reader.result, 
      }), 
      }) 
      .then((resp) => resp.json()) 
      .then((data) => { 
       console.log('Uploaded Data',data); 
       const imageUrl='http://localhost:9090/image/'+data.name; 
       if(this.props.uploadCallback){ this.props.uploadCallback(imageUrl); } 
       this.setState({'lastImgUploaded':imageUrl}) 
      }); 
     } 

     reader.readAsDataURL(file); 
    } 

    render(){ 
     return (
     <div> 
      <h3>Upload an image and set it into the editor</h3> 
      <input type="file" onChange={ this.onChange.bind(this) } name="file"/> 
     </div>); 
    } 
} 

export default UploadForm; 

そして、私が持っているとApp.js:

私のエディタがMyEditor.jsからレンダリングされます。

import React, { Component } from 'react'; 
import { EditorState,AtomicBlockUtils } from 'draft-js'; 
import { Editor } from 'react-draft-wysiwyg'; 

import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css'; 


class MyEditor extends Component { 
    state = { 
     editorState: EditorState.createEmpty(), 
    } 

    onEditorStateChange: Function = (editorState) => { 
     this.setState({ 
     editorState, 
     }); 
    }; 

    uploadCallback(file,callback) { 
     return new Promise((resolve, reject) => { 
     var reader = new window.FileReader(); 
     reader.onloadend=() => { 
      fetch('http://localhost:9090/image',{ 
      method: 'POST', 
      headers: { 
       'Accept': 'application/json', 
       'Content-Type': 'application/json', 
      }, 
      body: JSON.stringify({ 
       name: file.name, 
       data: reader.result, 
      }), 
      }) 
      .then((resp) => resp.json()) 
      .then((data)=>{ 
       console.log('Uploaded Data',data); 
       const imageUrl='http://localhost:9090/image/'+data.name; 
       resolve({data:{ link: imageUrl } }); 
      }); 
     } 
     reader.readAsDataURL(file); 
     }); 
    } 

    insertImage(url) { 
     console.log(this); 
     const contentState = this.state.editorState.getCurrentContent(); 
     const contentStateWithEntity = contentState.createEntity(
     'image', 
     'IMMUTABLE', 
     { src: url }, 
    ); 
     const entityKey = contentStateWithEntity.getLastCreatedEntityKey(); 
     const newEditorState = EditorState.set(
     contentState, 
     { currentContent: contentStateWithEntity }, 
    ); 
     const state=AtomicBlockUtils.insertAtomicBlock(newEditorState, entityKey, ' '); 
     this.setState({editorState:state}); 
    }; 

    render() { 
     const { editorState } = this.state; 
     const config={ 
     image: { uploadCallback: this.uploadCallback } 
     } 
     return (
      <Editor 
       editorState={editorState} 
       wrapperClassName="demo-wrapper" 
       editorClassName="demo-editor" 
       onEditorStateChange={this.onEditorStateChange} 
       toolbar={ config } 
      /> 
    ); 
    } 
} 

export default MyEditor; 

そして、私は、次のアップローダーを持っていますアプリ:

import React, { Component } from 'react'; 
import Editor from './MyEditor'; 
import UploadForm from './UploadForm'; 
import logo from './logo.svg'; 
import './App.css'; 

class App extends Component { 
    state={ 
    uploadedImage:"" 
    }; 

    uploadCallback(link){ 
    this.setState({'uploadedImage':link}); 
    this.__editor.insertImage(link).bind(this.__editor); 
    } 

    render() { 
    return (
     <div className="App"> 
     <header className="App-header"> 
      <img src={logo} className="App-logo" alt="logo" /> 
      <h1 className="App-title">Welcome to React</h1> 
     </header> 
     <div className="App-editor"> 
      <Editor ref={ (editor) => {this.__editor=editor; } } /> 
     </div> 
     <div className="SideBar"> 
      <div className="LastUpload"> 
      <h3>Last Uploaded Image</h3> 
      <img src={this.state.uploadedImage} /> 
      </div> 
      <div className="sideBarUpload"> 
      <UploadForm uploadCallback={ this.uploadCallback.bind(this) }/> 
      </div> 
     </div> 
     </div> 
    ); 
    } 
} 

export default App; 

達成したいのは、イメージがフォームから自分のapiにアップロードされるときです。uplアップロードした画像をエディタに挿入するのに成功しました。

insertImage(url) { 
      console.log(this); 
      const contentState = this.state.editorState.getCurrentContent(); 
      const contentStateWithEntity = contentState.createEntity(
      'image', 
      'IMMUTABLE', 
      { src: url }, 
     ); 
      const entityKey = contentStateWithEntity.getLastCreatedEntityKey(); 
      const newEditorState = EditorState.set(
      contentState, 
      { currentContent: contentStateWithEntity }, 
     ); 
      const state=AtomicBlockUtils.insertAtomicBlock(newEditorState, entityKey, ' '); 
      this.setState({editorState:state}); 
     }; 

しかし、私はエラーを取得するいくつかの理由のために:

editorState.getImmutable is not a function

私のブラウザコンソールオーバー私はMyEditor.js上の次のメソッドであることを達成しようとします。さらなる調査の結果、以下の方法でこれが起こることが判明しました。

const newEditorState = EditorState.set(
     contentState, 
     { currentContent: contentStateWithEntity }, 
    ); 

あなたは何らかの理由がありますか?

編集1

私はにMyEditorinsertImageを変更することにより、多少の誤差をSUPRESSするために管理:

uploadCallback(link){ 
    this.setState({'uploadedImage':link}); 
    console.log(this.__editor); 
    this.__editor.insertImage(link); 
} 

しかしについて:私はへuploadCallbackを変えApp.jsに続いて

insertImage: Function = (url) => { 
    const editorState = this.state.editorState; 
    const block = new ContentBlock({ 
    key: genKey(), 
    type: 'unstyled', 
    text: '<img src="'.concat(url).concat('"></img>'), 
    }); 

何らかの理由で私はエディタのコンテンツにイメージを見ることができません。理由は何ですか?

編集2

は、私は、コールバックonEditorStateChangeを使用しようとエラーがスローされませんますが、私はまだDraft.jsエディタに何も更新されたコンテンツを取得していません。結果insertImageは、このいずれかになります。

insertImage: Function = (url) => { 
     console.log("Inserting Image"); 
     const editorState = this.state.editorState; 
     const block = new ContentBlock({ 
     key: genKey(), 
     type: 'unstyled', 
     text: url, 
     }); 

     const contentState = editorState.getCurrentContent(); 
     const blockMap = contentState.getBlockMap().set(block.key, block);     
     const newState = EditorState.push(editorState, contentState.set('blockMap', blockMap)); 
     this.onEditorStateChange(newState); 
    }; 

答えて

1

エンドで反応し、ドラフトWYSIWYGのcontrolls(https://github.com/jpuri/react-draft-wysiwyg/blob/master/src/controls/Image/index.js)を見ていることで名前のメソッドを持っています

addImage: Function = (src: string, height: string, width: string, alt: string): void => { 
    const { editorState, onChange, config } = this.props; 
    const entityData = { src, height, width }; 
    if (config.alt.present) { 
     entityData.alt = alt; 
    } 
    const entityKey = editorState 
     .getCurrentContent() 
     .createEntity('IMAGE', 'MUTABLE', entityData) 
     .getLastCreatedEntityKey(); 
    const newEditorState = AtomicBlockUtils.insertAtomicBlock(
     editorState, 
     entityKey, 
     ' ', 
    ); 
    onChange(newEditorState); 
    this.doCollapse(); 
    }; 

だから、この1の上に基づいて、このいずれかを実行します。 :

insertImage: Function = (url) => { 
     console.log("Inserting Image",this.__editor); 
     const editorState = this.state.editorState; 
     const entityData = { src:url, height: 300, width: 300, }; 
     const contentStateWithEntity=editorState.getCurrentContent().createEntity('IMAGE', 'IMMUTABLE', entityData); 

     const entityKey = contentStateWithEntity.getLastCreatedEntityKey(); 

     let newEditorState = EditorState.set(editorState, { currentContent: contentStateWithEntity },); 
     newEditorState = AtomicBlockUtils.insertAtomicBlock(editorState,entityKey,' ',); 
     this.setState({editorState:newEditorState}); 
    }; 
関連する問題