【发布时间】:2018-06-14 09:53:06
【问题描述】:
我有一个对象数组,需要像未标记列表一样递归地渲染每个对象:
<ul>
<li>
</li>
</ul>
所有数据都像简单的 JSON 一样来自服务器:
{
"Id": 1,
"Description": "asd",
"Src": " ",
"Lft": 0,
"Rgt": 9
},
{
"Id": 2,
"Description": "asd2",
"Src": " ",
"Lft": 1,
"Rgt": 2
},
{
"Id": 3,
"Description": "asd3",
"Src": " ",
"Lft": 3,
"Rgt": 8
},
{
"Id": 4,
"Description": "asd4",
"Src": " ",
"Lft": 4,
"Rgt": 5
},
{
"Id": 5,
"Description": "asd5",
"Src": " ",
"Lft": 6,
"Rgt": 7
}
我正在使用嵌套集模型进行添加和删除。添加/删除是好的,添加新元素会生成并重新计算正确的键(删除相同的) 另外,我可以只渲染所有项目(在我的情况下是一行)。但目标是使其视图分层。 这是我如何渲染 lft|rgt 的示例(但我使用的是通常的 JS)
为了渲染我使用下一个函数(function renderItems(items)):
renderItems(items) {
let node = document.getElementById('root');
node.innerHTML = '';
if (items.length) {
var ul = document.createElement('ul');
var tree = fetchChildElement(ul);
node.appendChild(tree);
}
function fetchChildElement(container, lft, rgt) {
items.filter(filterItems); //go through data array
return container;
function filterItems(item) {
if (item.Lft === (lft || 0)) {
var element = document.createElement('li');
element.innerHTML = (item.Lft + " | " + item.Rgt);
//check if element got nested elements, if true - call function again
if (item.Lft + 1 < item.Rgt) {
var childContainer = document.createElement('ul');
var child = fetchChildElement(childContainer, item.Lft + 1, item.Rgt - 1);
element.appendChild(child);
}
//add element to container
container.appendChild(element);
//check if next element exists and call function for them
if (rgt && item.Rgt < rgt) {
fetchChildElement(container, item.Rgt + 1, rgt);
}
}
}
}
}
这是我的组件: Item.js
class Item extends Component {
render() {
let { item, showModalPlusClicked, deleteItem } = this.props
return (
<li className="item">
{item.Description &&
<div>
<img src={item.Src} alt="" />
{"Description: " + item.Description}
<div className="buttons">
<button className="addBtn btn" onClick={(id) => showModalPlusClicked(item)}>+</button>
<button className="removeBtn btn" onClick={(id) => deleteItem(item.Id)}>-</button>
</div>
<p>lKey is {item.Lft} <span>|||| rKey is {item.Rgt}</span></p>
<p>______________________</p>
<p>id is {item.Id}</p>
</div>
}
</li>
)
}
}
这是我的 ItemList.js 组件,我认为所有递归魔法都应该是:
class ItemList extends Component {
render() {
let { items, showModalPlusClicked, deleteItem } = this.props
return (
<div className='items'>
<ul>
{items.map((item) =>
<Item
key={item.Id}
item={item}
src={item.Src}
desc={item.description}
lft={item.lft}
rgt={item.rgt}
showModalPlusClicked={showModalPlusClicked}
deleteItem={deleteItem}
/>
)}
</ul>
</div>
)
}
}
下面是一个屏幕截图,它如何使用正确样式化的项目(但不是分层)呈现,也使用了 display:inline-block in li.items 以便更好地理解
顺便说一句,要渲染第一张图片上的项目,我只需将 {this.renderItems(items)} 传递给 ItemList 的 render() 方法。
所以,最后我觉得还是把上面所有的词都复述一遍比较好。
- 我有一个对象数组 ItemsList。
- ItemList 中的每个对象都是 Item。
- 每个项目都有 2 个主要标识符(leftKey - lft 和 rightKey - rgt),它们应该用于在无序列表 () 中显示项目。
- 我得到了 javascript 函数,它可以获取此键并在 index.html 中显示 smth,但我不明白如何重新制作它(或者可能函数应该完全是另一个)
- 另外,我将不同的数据传递到我的 JS 函数中,它使 ul>li 正确,所以我真的认为所有更改都应该在其中。
编辑 “那样”我的意思是 - 项目组件呈现为无序列表(参见第一张图片)。我该图像只有左右键,而不是它们应该有整个 Item 组件(如图像 2 上)
编辑 任何想法如何实现这一点?我绝望了……
【问题讨论】:
-
输出应该是什么?喜欢在第一个屏幕上?
-
是的,输出应该像在第一个屏幕上一样,但不仅仅是左右键(就像我的情况一样)。应该是反应组件Item。
标签: javascript reactjs recursion react-redux nested-sets