2014-10-23 8 views
6

Мне нужно создать визуальный редактор для HTML-страницы. Кажется, что ReactJS - хороший выбор для этого. В настоящее время я столкнулся со следующей проблемой:Есть ли способ обхода дерева, созданного React?

Я смоделировал мои данные:

var Model = { 
    title: 'Hello', 
    description: 'Pellentesque eleifend urna ac purus tempus...', 
    date: new Date().toString() 
}; 

и встроенный компонент, который хранит свои данные в приведенной выше структуре:

var App = React.createClass({ 
    getInitialState: function() { 
     return { 
      value: Model 
     } 
    }, 
    handleMouseEnter: function (event) { 
     $(event.target).css('outline', '1px solid red').attr('contenteditable', true); 
    }, 
    handleMouseLeave: function (event) { 
     var t = $(event.target), v = this.state.value; 
     t.css('outline', 'none').attr('contenteditable', false); 
     v[t.attr('property')] = t.text(); 
     this.setState({value: v}); 
    }, 
    render: function() { 
     var v = this.state.value; 
     return (
      <div> 
       <pre style={{whiteSpace: 'normal'}}>{JSON.stringify(this.state)}</pre> 
       <h1 onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} property="title">{v.title}</h1> 
       <p onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} property="description">{v.description}</p> 
       <p onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} property="date">{v.date}</p> 
      </div> 
     ); 
    } 
}); 

React.renderComponent(<App />, document.getElementById('app')); 

В данном конкретном случае это работает. Но я хочу избавиться от onMouseEnter и onMouseLeave объектов недвижимости и оставить только property. Например:

<pre style={{whiteSpace: 'normal'}}>{JSON.stringify(this.state)}</pre> 
<h1 property="title">{v.title}</h1> 
<p property="description">{v.description}</p> 
<p property="date">{v.date}</p> 

Я думал о создании mixin. Затем, внутри события componentDidMount, присоедините обработчики ко всем элементам с атрибутом property. Но я не нашел пути для этого.

Мой вопрос: Есть ли способ обхода дерева, созданного React? Я заметил, что Инструмент разработчика React Developer (Chrome Extension) может это сделать.

Похожие Вопрос: React.js component creating parent child relations and iterating

+0

Итак, вам нужен способ пересечения дочерних компонентов, сгенерированных родителем? У вашего родителя есть состояние, в котором хранится массив ваших моделей. Затем в рендеринге вы можете использовать '' 'array.map''' для повторения каждой из этих моделей в массиве и возврата дочернего компонента, передающего eventHandlers, и данных модели из родительского – trekforever

+1

@trekforever плохого решения. При этом мне нужно иметь еще одну модель - для представления, из которой будут создаваться узлы DOM. Http: // jsfiddle.net/kb3gN/6684/ – vbarbarosh

+0

Я смущен тем, почему вы хотите делать то, что вы описали, - возможно, дальнейшая разработка того, что именно вы пытаетесь сделать, не может быть достигнута только с помощью 'array.map'? –

ответ

0

Так что вы хотите:

<h1 onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} property="title">{v.title}</h1> 

в

<h1 property="title">{v.title}</h1> 

Я хотел бы использовать другой Component для того, что заботится о визуализации этого конкретного типа компоненты, такие как redux-form.

Самый простой подход к достижению того, что вы хотите сделать, было бы что-то вроде:

class MyField extends Component { 
    constructor(props) { 
    super(props); 
    this.handleMouseEnter = this.handleMouseEnter.bind(this); 
    } 
    handleMouseEnter() { ... } 
    render() { 
    const { property, children } = this.props; 
    if (property === 'title') { 
     return (
     <h1 onMouseEnter...>{children}</h1> 
    ); 
    } 
    } 
} 

Тогда вы могли бы назвать его, как это на любой другой компонент:

<MyField property="title">Stackoverflow</MyField> 

Более профессиональный, но и более сложный подход, будет иметь реализацию редукционной формы Field, на которой они даже используют React.createElement для генерации HTML (что я делаю с if-else в примере выше).

Если вам нужно получить доступ к каким-либо из его данных вне его, либо вы передадите ему функцию через свойства, либо подключите этот компонент MyField к сокращению (это также относится к сокращению).

Я бы также передал через реквизиты какие-то конкретные одноразовые стили, которые вы хотите применить к своим MyField компонентам.

Смежные вопросы