2014-12-17 3 views
1

В настоящее время я пытаюсь заставить responseJS работать со следующей установкой:Как перестроить существующий Dom in reactjs?

Я получаю xml-DOM с сервера. Его серверная сторона визуализировала «пользовательский» DOM, который normaly потребляется другим клиентом (а не html, а java), который отображает компоненты.

<row id="a"> 
    <label id="aa" width="140" text="Title" /> 
    <field id="ab" bgpaint="" width="200" text="" enabled="true" /> 
</row> 

Я определил некоторые ReactComponents с React.createClass(). Поэтому у меня есть ярлык, поле и строка (div).

В настоящее время я не могу решить, как отредактировать компоненты xml-DOM. Я иду через xml-DOM и получил сниппет сверху. Если я найду оболочку «строка», я вызываю React.createElement (Row, {},?)? Но я не знаю, какие дети будут заполнять '?' прежде чем я углубиться в xml-DOM. Если я прохожу через xml-DOM, пока не получаю «endNode» без детей, как я могу создать элементы реакции снизу вверх? Должен ли я создать суперструн и как-то назвать его javascript.

Есть ли способ создать строку, а последующие добавить детей? Должен ли я использовать реквизиты компонентов? Что-то вроде:

//<row> found 
var newRow = React.createElement(Row, {}, ?); 
... 
//found the label in the row 
var newLabel = React.createElement(Label, {}, "Title"); 
newRow.add(newLabel); 

я едва могу прийти к решению - это можно сделать с отреагирует? Или я пытаюсь сделать что-то, на что не реагируют? Наверное, я совершенно не понимаю концепцию ребенка. Или, может быть, это не совсем реакция - сама проблема ...

Любые советы для меня?

Greetz

ответ

1

Создать массив детей, прежде чем звонить createElement. Например (jsfiddle):

function pascalize(str) { 
    return str.split("-").map(function(name) { 
     return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase(); 
    }).join(""); 
} 

function attrsToProps(attrs) { 
    var obj = {}; 
    for (var i = 0; i < attrs.length; ++i) { 
     obj[attrs[i].nodeName] = attrs[i].value; 
    } 
    return obj; 
} 

function toReact(node, components) { 
    if (node.nodeType === 1) { 
     var children = [].map.call(node.childNodes, function(child) { 
      return toReact(child, components); 
     }); 
     return React.createElement(components[pascalize(node.nodeName)], 
            attrsToProps(node.attributes), 
            children); 
    } else if (node.nodeType === 3) { 
     return (node.nodeValue + "").trim(); 
    } 
    return ""; 
} 

function xmlToReactComponents(xmlDom, components) { 
    if (xmlDom && xmlDom.documentElement) { 
     return React.createElement("div", [], [].map.call(xmlDom.documentElement.childNodes, function(child) { 
      return toReact(child, components); 
     })); 
    } 
} 

Использование в jsfiddle является:

var xml = document.querySelector("#xml").innerHTML; 
var parser = new DOMParser(); 
var dom = parser.parseFromString(xml, "text/xml"); 

var defaultClass = { 
    render: function() { 
     return React.createElement("div", {}, "id: " + this.props.id, this.props.children); 
    } 
}; 

var components = { 
    Row: React.createClass(defaultClass), 
    Label: React.createClass(defaultClass), 
    Field: React.createClass(defaultClass) 
} 
var result = xmlToReactComponents(dom, components); 
React.render(result, document.body); 

Вам необходимо пройти все компоненты XML-могли бы создать в объекте иначе все это не удается

+0

Вы могли бы просто представляйте его как «Tree {component: String, реквизит: Object, children: [Tree]}' и просто '.children.map (renderTree)' для рекурсивного рендеринга. – FakeRainBrigand

+0

@FakeRainBrigand и как вы получаете ссылку на класс компонента? – Esailija

+0

Объект компонентов в вашем примере - это сопоставление имен компонентов классам компонентов. Это именно то, что я буду использовать. – FakeRainBrigand

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