<p>react-ace em contêiner redimensionável</p>

Criado em 27 mai. 2017  ·  15Comentários  ·  Fonte: securingsincity/react-ace

Estou tentando usar react-ace dentro de um div que pode ser redimensionado pelo usuário em tempo de execução (para ser preciso, o tamanho do div é controlado por um flexbox ). Por padrão, o editor ACE requer valores fixos com e de altura em pixels.

Usando a medida de reação e algum aninhamento de div , consegui fazer com que o Editor ACE redimensionasse seus limites corretamente, pelo menos visualmente. No entanto, os controles dentro do editor (por exemplo, a largura da quebra de linha, a barra de rolagem, ...) se comportam de maneira estranha, porque eles não foram devidamente notificados sobre a mudança nas dimensões do editor.

O editor ACE "vanilla" tem um método resize() para corrigir exatamente esse problema (veja este violino ).

Minha solicitação é: encaminhe resize() em react-ace ou ligue para resize() internamente em componentWillReceiveProps no caso de width e / ou height mudou.

EDIT: Eu dei uma olhada rápida no código-fonte. Você realmente faz isso:

if(nextProps.height !== this.props.height){
  this.editor.resize();
}

... mas e as mudanças na largura? Não deveria ser assim:

if(nextProps.height !== this.props.height || nextProps.width !== this.props.width){
  this.editor.resize();
}

Comentários muito úteis

Alguém descobriu como redimensionar automaticamente o contêiner com base no controle do usuário?

Consegui usar o detector de redimensionamento reativo

import AceEditor from 'react-ace'
import ReactResizeDetector from 'react-resize-detector'

export default class myComponent extends Component {

  constructor (props) {
    super(props)
    this.state = {
      editorHeight: 400,
      editorWidth: "auto"
    }
    this.onResize = this.onResize.bind(this)
  }


  onResize (w, h) {
    this.setState({
      editorHeight: h,
      editorWidth: w
    })
  }

  render () {
    <div className="resizable">
     <ReactResizeDetector handleWidth handleHeight onResize={this.onResize} />
     <AceEditor
       height={this.state.editorHeight}
       width={this.state.editorWidth}
     />
    </div>
  }
}

CSS da classe resizable

.resizable {
    overflow: auto;
    resize: both;
    height: 400px;
    width: auto;
}

Todos 15 comentários

@MartinHaeusler obrigado pelo problema. Estou trabalhando nisso agora. deve sair em 4.4.0 e estará em 5.0.0 quando isso sair

@MartinHaeusler, isso já está disponível em 4.4.0 Obrigado

Obrigado por esta resposta muito rápida! Acabei de atualizar meu package.json para usar 4.4.0 e funciona muito bem, obrigado!

@MartinHaeusler, você provavelmente poderia compartilhar um link para a solução que criou?

@dmigo : Tentei usar a medida de reação para o trabalho. No entanto, só funcionou em alguns casos, não em todos. Sempre havia alguns casos estranhos deixados em que o editor não se comportava como pretendido. No final, mudei do Ace para o CodeMirror por esse motivo. Eu tive alguns problemas lá também em tornar as coisas redimensionáveis ​​e tive que fazer alguns hacks bastante feios, mas isso funciona agora. Desculpe, descartei o protótipo do editor reage-ace redimensionável pouco depois. Mas nunca funcionou corretamente como pretendido de qualquer maneira.

@securingsincity
Tentando implementar algo semelhante ao que @MartinHaeusler fez, descobri um comportamento interessante de react-ace . Parecia que resize() não estava acontecendo corretamente.
Após alguma investigação, descobriu-se que this.editor.resize() está sendo chamado em componentWillReceiveProps que ocorre antes de render .
Faria mais sentido chamar this.editor.resize() durante componentDidUpdate , após render acontecer e ace-editor receber novos valores para height e width .
Se concordarmos com isso, ficarei feliz em corrigir isso para você (junto com o # 212). O que você diria?

@dmigo isso parece ótimo! Se acharmos que isso pode resolver os problemas, vamos resolver

@dmigo Boa captura! Esse pode ter sido o problema para mim também.

Eu estou pronto para isso!

Eu atualizei para 5.1.2 e liguei para o AceEditor com os adereços:

mode: 'json',
theme: 'chrome',
readOnly: true

Preciso adicionar algo para redimensionar para o contêiner?

Preciso adicionar algo para redimensionar para o contêiner?

Alguém descobriu como redimensionar automaticamente o contêiner com base no controle do usuário? Eu estou tentando:

  1. permitir ao usuário redimensionar ativamente o contêiner por meio da propriedade CSS resize: vertical (ou seja, permitir que o usuário arraste o canto inferior direito para redimensionar).
  2. redimensiona automaticamente o contêiner com base no número de linhas que o usuário inseriu. Com a altura padrão de 500px, se o usuário inserir mais de 27 linhas, o editor permanecerá com a mesma altura, enquanto torna o contêiner rolável para adicionar espaço extra. Eu gostaria que o contêiner aumentasse (ou diminuísse para uma altura mínima) com base nas linhas inseridas.

Alguém descobriu como redimensionar automaticamente o contêiner com base no controle do usuário?

Consegui usar o detector de redimensionamento reativo

import AceEditor from 'react-ace'
import ReactResizeDetector from 'react-resize-detector'

export default class myComponent extends Component {

  constructor (props) {
    super(props)
    this.state = {
      editorHeight: 400,
      editorWidth: "auto"
    }
    this.onResize = this.onResize.bind(this)
  }


  onResize (w, h) {
    this.setState({
      editorHeight: h,
      editorWidth: w
    })
  }

  render () {
    <div className="resizable">
     <ReactResizeDetector handleWidth handleHeight onResize={this.onResize} />
     <AceEditor
       height={this.state.editorHeight}
       width={this.state.editorWidth}
     />
    </div>
  }
}

CSS da classe resizable

.resizable {
    overflow: auto;
    resize: both;
    height: 400px;
    width: auto;
}

aqui está uma solução css pura, usando resize: both no editor div

<AceEditor
  onLoad={editorInstance => {
    editorInstance.container.style.resize = "both";
    // mouseup = css resize end
    document.addEventListener("mouseup", e => (
      editorInstance.resize()
    ));
  }}
/>

desvantagem: no redimensionamento para maior, o conteúdo do editor fica oculto

aqui está uma demonstração de violino com vanilla js

Obrigado @milahu sua solução funcionou perfeitamente para o meu caso de uso.

Obrigado @milahu variam muito.

Esta página foi útil?
0 / 5 - 0 avaliações