摩纳哥编辑器动态调整大小

时间:2017-10-30 14:29:28

标签: javascript node.js reactjs monaco-editor

我一直在寻找一个关于在整个互联网上使用 Monaco编辑器字段时是否可以模仿html标签textarea&s; s resizing的讨论但我无法找到一个回答我的问题。

我在 React 应用程序中使用 monaco-editor npm包。您是否知道这是否易于实施?

提前谢谢!


使用纯css我选择了目标html元素,并添加了这些属性:

div{ resize: vertical; overflow: auto; }

4 个答案:

答案 0 :(得分:9)

TL; DR:将automaticLayout: true添加到编辑器的配置中。

NL; PR:

Monaco有一个内置的自动调整大小到父容器功能:

React> = 16.3.0(推荐)

constructor(props){super(props); this.ref = React.createRef();}

render(){
 return <div ref={this.editorDiv} className="editor" ></div>
}

componentDidMount(){
 let editor = monaco.editor.create(this.editorDiv.current, {
        value: "var x = 0;",
        language: 'javascript',
        automaticLayout: true // the important part
      });
}

<强>阵营&LT; 16.3.0

render(){
 return <div ref={el=>{this.editorDiv = el}} className="editor" ></div>
}
 // I use this configuration in the editor:
componentDidMount(){
 let editor = monaco.editor.create(this.editorDiv, {
        value: "var x = 0;",
        language: 'javascript',
        automaticLayout: true // the important part
      });
}

编辑器的CSS(它避免了第一次以10px高度渲染编辑器):

.editor{
 height: 100%;
} 

摩纳哥版本:^ 0.10.1,最后测试:0.12.0

注意: 该机制不会监听其容器大小的变化,polls them

答案 1 :(得分:3)

如果您对编辑器有引用,则可以调用 editor.layout() 在一些调整大小事件。 窗口调整大小的示例

window.onresize = function (){ editor.layout(); };

希望这有帮助。

答案 2 :(得分:1)

在我的情况下,我使用的是确切的CSS,但尽管autoLayout:true起作用,但我发现矫over过正(似乎将DOM间隔为100ms,并且在文档中打开了多个编辑器。因此,我最终手动实现了它:

以防万一,我的需求是不同的:我希望用户以标准方式调整容器的大小-并且在库和性能上便宜(在代码和性能上)。这就是我所做的:

css容器:resize: vertical; overflow: auto

和这个js:

function installResizeWatcher(el, fn, interval){
  let offset = {width: el.offsetWidth, height: el.offsetHeight}
  setInterval(()=>{
    let newOffset = {width: el.offsetWidth, height: el.offsetHeight}
    if(offset.height!=newOffset.height||offset.width!=newOffset.width){
      offset = newOffset
      fn()
    }
  }, interval)
}
  const typeScriptCodeContainer = document.getElementById('typeScriptCodeContainer')
  typeScriptCodeEditor = monaco.editor.create(typeScriptCodeContainer, Object.assign(editorOptions, {value: example.codeValue}))
  installResizeWatcher(typeScriptCodeContainer, typeScriptCodeEditor.layout.bind(typeScriptCodeEditor), 2000)

是,间隔2秒,并确保仅注册一次。我发现摩纳哥自动重传有一个100ms的调整时间间隔-恕我直言,这太多了。

查看实际情况:https://typescript-api-playground.glitch.me/?example=2

答案 3 :(得分:0)

这是一个古老的问题,但是可以通过react-resize-detector

来解决该问题。

基于ResizeObserver,完全可以满足需要(请检查browser compatibility

组件示例:

import React, { Component } from 'react';
import ReactResizeDetector from 'react-resize-detector';
import * as monaco from 'monaco-editor';

class Editor extends Component {
    constructor(props) {
        super(props)

        this.state = {
            width: 0,
            height: 0,
        }
        this.editor_div = React.createRef()

        this.handle_rezise = this.handle_rezise.bind(this);
    }

    componentDidMount() {
        const editor_model = monaco.editor.createModel('', 'sql');
        this.monaco_editor = monaco.editor.create(this.editor_div.current, this.props.editorOptions);
        this.monaco_editor.setModel(editor_model);
    }

    componentWillUnmount() {
        this.monaco_editor && this.monaco_editor.dispose();
    }

    handle_rezise(width, height) {
        this.monaco_editor.layout({ height, width });
    }

    render() {
        return(
            <div 
                className="editor-container"
                style={{ height: '100%' }}>
                <ReactResizeDetector
                    handleWidth
                    handleHeight
                    onResize={ this.handle_rezise }
                    refreshMode="debounce"
                    refreshRate={100} />
                <div 
                    className="editor"
                    ref={ this.editor_div }
                    style={{ height: '100%' }} />
            </div>
        )
    }
}

export default Editor;

希望有帮助