Search code examples
javascriptreactjsace-editor

How to change the content inside an ace editor when I clicked on another file?


I'm learning Reactjs and want to write a web editor.

There will be a file list on the left, and an editor in the middle. When I click on a file, the content of the editor will be changed.

We are using brace which is a commonjs-compatible version of ACE editor. We use such code to turn a normal dir to an editor:

https://github.com/dujuanxian/webpanda/blob/ace/app/scripts/ui/Editor.js#L46

componentDidMount: function() {
    var editor = ace.edit(this.props.name);
    editor.getSession().setMode('ace/mode/'+this.props.mode);
    editor.setTheme('ace/theme/'+this.props.theme);
},

The editor will be shown correctly when I open the home page which show the first file by default, but if I click on another file, the editor will be disappeared, and only left a normal div with the content.

You can clone the repo: https://github.com/dujuanxian/webpanda, and run:

$ git checkout ace
$ npm install
$ bower install
$ gulp watch

to start the server and open the home page automatically.

I have two options which can fix it but I don't know how to do it:

  1. When I click on another file, recreate the ACE editor again (which is slow so not preferred)
  2. Reuse the rendered ACE editor, just change the content (I'm not sure if that's possible)

How to fix it?


Solution

  • You can change the content of the editor using setValue method of the editor you are using.

    I removed this.props.content from the section element because it was causing section to be re-rendered and markup generated by ace plugin was removed. Instead I set content inside componentDidUpdate method if this.props.content has changed:

    componentDidMount: function() {
        this.editor = ace.edit(this.props.name);
        this.editor.getSession().setMode('ace/mode/'+this.props.mode);
        this.editor.setTheme('ace/theme/'+this.props.theme);
        this.editor.setValue(this.props.content);
    },
    componentDidUpdate : function(prevProps, prevState){
        if(this.props.content != prevProps.content){
           this.editor.setValue(this.props.content);
           this.editor.clearSelection();
        }
    },
    render: function() {
        return (<section id={this.props.name}></section>);
    }