需要方向通过数组遍历
请原谅我的无知。我刚刚开始使用反应,我相信我错过了一些非常简单的东西。因此,根据我从loadData获取的数据量,我需要在1 2或3列中显示数据。我正在使用ul和li。我根据屏幕大小计算可以放入一列中的人数。我试图让他们都在一个UL,但我需要在顶部的标题行,所以我真的需要高达3 uls的第一个李有头信息。我如何循环并创建我需要的uls数量?我试图在回归周期中进行循环,但我无法做到这一点。任何帮助是极大的赞赏。需要方向通过数组遍历
var appointmentBoardSection = React.createClass({
displayName: "appointmentBoardSection",
getInitialState: function() {
return {
key: null,
results: [],
parameters: this.props.parameters,
type: "",
};
},
shouldComponentUpdate: function(nextProps, nextState) {
console.info("this.state.key: " + this.state.key);
console.info("nextState.key: " + nextState.key);
if (this.state.key !== nextState.key) {
console.info("NO MATCH!!!!");
//this.forceUpdate();
return true;
}
return false;
},
componentDidMount: function() {
console.info("MOUNTED!!!");
var _this = this;
_this.loadData();
setInterval(function() {
_this.loadData();
}, 10000);
},
loadData: function() {
console.info("LOADING DATA....");
var _this = this;
$.when(_api.callPromise('apiRouter.ashx', 'getAppointmentsBoard', JSON.stringify(masterPage.reporting.parameters), this.props.type)).then(function(data) {
var totalData = data.args[0];
if (totalData.length <= 0) {
$("div#" + _this.props.type).hide();
} else {
$("#no_data").hide();
$("div#" + _this.props.type).show();
}
_this.setState({
results: totalData,
key: Math.random()
});
masterPage.hidePleaseWait(true);
});
},
render: function() {
var contHeight = $(window).height();
var offsetTop = $("div.appt_bd_container").offset().top;
var realEstate = contHeight - 400;
var perColumn = Math.round(realEstate/70);
console.info("height: " + $(window).height());
console.info("offsetTop: " + offsetTop);
console.info("perColumn: " + perColumn);
var maxICanShow = perColumn * 3;
var limitResults = false;
var colCount = 3;
var colDef = "";
var colWidth = 100;
var numberOfColsNeeded = Math.round(this.state.results.length/perColumn);
if (numberOfColsNeeded > 3) {
colCount = 3;
} else {
colCount = numberOfColsNeeded;
}
switch (colCount) {
case 2:
colWidth = 50;
break;
case 3:
colWidth = 33.333;
break;
default:
colDef = "";
colWidth = 100;
}
if (this.state.results.length > maxICanShow) {
var i = 1;
console.info("this.state.results.length: " + this.state.results.length);
console.info("maxICanShow: " + maxICanShow);
while (i < this.state.results.length - (maxICanShow - 1)) {
this.state.results.pop();
i++;
}
}
var curColData = [];
var overallCount = this.state.results.length;
var testArr = [];
for (var i = 0; i < colCount; i++) {
testArr.push({});
}
if (this.state.results.length > perColumn) {
for (var i = 0; i < perColumn; i++) {
if (overallCount > 0) {
curColData.push(this.state.results.shift());
overallCount--;
}
}
}
var myTest = [];
return (<
ul className = "appt_bd" >
<
li className = "appt_bd_header"
style = {
{
width: colWidth + '%'
}
} >
<
span className = "appt_bd_header_main" > {
this.props.title
} < /span> <
span className = "appt_bd_header_sub" > Appts Set < /span> <
span className = "appt_bd_header_sub" > Appts Show < /span> <
/li> {
curColData.map(function(row) {
return <AppointmentBoardRow colWidth = {
colWidth
}
key = {
row.userId
}
row = {
row
}
/>;
})
} <
/ul>
);
}
});
var AppointmentBoardRow = React.createClass({
render: function() {
var row = this.props.row;
return (<
li className = "appt_bd_row"
style = {
{
width: this.props.colWidth + '%'
}
}
key = {
row.userId
} >
<
span className = "appt_bd_desc" >
<
span className = "appt_bd_rank" > {
row.rank
} < /span> <
span className = "appt_bd_avatar_container" > < div className = {
row.className
} > < span className = "initials" > {
row.initials
} < /span></div > < /span> <
span className = "appt_bd_user" >
<
span className = "appt_bd_description_main" > {
row.userName
} < /span> <
span className = "appt_bd_description_sub" > {
row.role
} < /span> <
/span> <
/span> <
span className = "appt_bd_data" >
<
span className = "appt_bd_data_main" > {
row.apptsSetCount
} < /span> <
span className = "appt_bd_data_sub" > /{row.apptsSetGoal}</span >
<
/span> <
span className = "appt_bd_data" >
<
span className = "appt_bd_data_main" > {
row.apptsShowCount
} < /span> <
span className = "appt_bd_data_sub" > /{row.apptsShowGoal}</span >
<
/span> <
/li>
);
}
});
****编辑回应乔希......我现在有一个问题是没有显示,虽然我可以验证你是正确的。这里是我的nee渲染:
render: function() {
var contHeight = $(window).height();
var offsetTop = $("div.appt_bd_container").offset().top;
var realEstate = contHeight - 400;
var perColumn = Math.round(realEstate/70);
var maxICanShow = perColumn * 3;
var colWidth = 100;
var uls = _.chunk(_.take(this.state.results, maxICanShow), perColumn);
let li = "";
return (
<div>
{uls.map((lis) => {
<ul className="appt_bd">
<li className="appt_bd_header" style={{ width: colWidth + '%' }}>
<span className="appt_bd_header_main">{this.props.title}</span>
<span className="appt_bd_header_sub">Appts Set</span>
<span className="appt_bd_header_sub">Appts Show</span>
</li>
lis.map(li => {<li className="appt_bd_row" style={{ width: this.props.colWidth + '%' }} key={li.userId}>
<span className="appt_bd_desc">
<span className="appt_bd_rank">{li.rank}</span>
<span className="appt_bd_avatar_container"><div className={li.className}><span className="initials">{li.initials}</span></div></span>
<span className="appt_bd_user">
<span className="appt_bd_description_main">{li.userName}</span>
<span className="appt_bd_description_sub">{li.role}</span>
</span>
</span>
<span className="appt_bd_data">
<span className="appt_bd_data_main">{li.apptsSetCount}</span>
<span className="appt_bd_data_sub">/{li.apptsSetGoal}</span>
</span>
<span className="appt_bd_data">
<span className="appt_bd_data_main">{li.apptsShowCount}</span>
<span className="appt_bd_data_sub">/{li.apptsShowGoal}</span>
</span>
</li>})
</ul>
})}
</div>
);
}
通过使用lodash你可以简化你的算法,建立布局。请参阅下面的render
render: function() {
var contHeight = $(window).height();
var offsetTop = $("div.appt_bd_container").offset().top;
var realEstate = contHeight - 400;
var perColumn = Math.round(realEstate/70);
var maxICanShow = perColumn * 3;
var uls = _.chunk(_.take(this.state.results, maxICanShow), perColumn);
switch (uls.length) {
case 2:
colWidth = 50;
break;
case 3:
colWidth = 33.333;
break;
default:
colDef = "";
colWidth = 100;
}
开始后,这个你不需要任何你写的,直到 return {...
的其他代码,但你需要将模板映射到uls
而非curColData
。它会是这个样子(简单化):
uls.map((lis) => {
<ul>
<li> my header </li>
lis.map(li => <li></li>)
</ul>
})
值得一提的是我的解决方案使用的return
鉴于这是要避免双重迭代在可能的情况 - 尤其是在潜在的大集合;但是因为你的集合不会是(给定容器的大小)并且你想要动态地构建嵌套元素,它似乎是需求的正确模式。
now uls
将是一个数组数组,它将数据映射到您提出的视图结构。具体而言,您的ul
将由uls
中的每个阵列表示;那么,嵌套数组中的每个项目将代表一个li
。 以uls[0]
作为你的第一个ul
和uls[0][0]
将是你第一个ul
的第一个li
。
_.take
文件可以发现here
_.chunk
文件可以发现here
希望,让您的数据转变成类似的结构您需要的视图将有助于推动你。
我还会说,代码还有其他许多问题。例如,React人可能会告诉你,将jQuery混合在一起是一个禁忌。
UPDATE 9/15/17 我想了一下,发现有一个更加冗长的方式,没有双重迭代。您只需要不超过三列,我们可以使用它来绘制三个单独的元素,全部包含要显示的总项目的块。如果该块发生不存在(项目数量少于max this.state.results.length < maxICanShow
),由于方便的花花束,这不会成为问题。请参见下面的代码:
class ListPane extends React.Component {
render() {
var contHeight = 900;//$(window).height();
var offsetTop = 50; //$("div.appt_bd_container").offset().top;
var realEstate = contHeight - 400;
var perColumn = Math.round(realEstate/70);
var maxICanShow = perColumn * 3;
var uls = "abcedefhijklmnopqrstuvwxyz".split("");
var chunks = _.chunk(_.take(uls, maxICanShow), perColumn);
var colWidth = 0;
var colA = _.map(_.nth(chunks, 0), item => <li>{item}</li>)
var colB = _.map(_.nth(chunks, 1), item => <li>{item}</li>)
var colC = _.map(_.nth(chunks, 2), item => <li>{item}</li>)
const listItems = chunks.map((lis) =>
<ul>
<li> {lis} </li>
</ul>
);
switch (chunks.length) {
case 2:
colWidth = 50;
break;
case 3:
colWidth = 33.333;
break;
default:
colWidth = 100;
}
return (
<div>
<ul>
{colA}
</ul>
<ul>
{colB}
</ul>
<ul>
{colC}
</ul>
</div>
)
}
}
通知我利用的_.nth
其保护代码从潜在null
或unresolveable参考。
此外,检查出这个codepen
有可能进行其他方面的改进。
- 代替
var colC = _.map(_.nth(chunks, 2), item => <li>{item}</li>)
, 这将是清洁的li
小号代替创建另一个类,也许ListItem
。 所以,var colC = _.map(_.nth(chunks, 2), item => <ListItem data={item} />)
- 奇怪的是,我注意到listitems的部分列从上到下流动。所以如果你
'abcedfghijkl'.split('')
你会得到两列,第二组li
位于底部。我不是很确定为什么,但并不觉得它从示威中消失了。
有关React的最终注意事项,以及为什么我不会/不会使用它。它的许可证并非真正开放,许多人都对此感到担忧。如果你刚刚进入React,现在可能是选择别的东西的好时机。见this reddit
这可能是在一个完全不同的方向,但你有没有看过css'columns'属性? –
我没有,但我现在... – BigPoppa
所以是的,我可以做这样的事情,但仍然有在每列的顶部获得标题行的问题。 – BigPoppa