#reactjs
#reactjs
Вопрос:
Объект:
let skillObj1 = {
levels: [1, 4, 5, 7, 8, 9, 10, 12, 13, 14, 15, 16, 18, 19, 20, 22, 25, 29, 30, 32, 34, 35, 38],
skills: [['axe', 'dagger', 'flail', 'polearm', 'spear', 'sword', 'archery', 'whip', 'evaluation', 'enhanced damage', 'staff', 'parry', 'rescue', 'recall'], ['dirt kicking'], ['hand to hand', 'second attack'],
['fast healing'], ['kick'], ['trip'], ['shield block'], ['dual wield', 'bash'], ['dodge'], ['haggle', 'lunge'], ['lash', 'disarm'], ['crush', 'warcry', 'meditation'],
['shield cleave', 'berserk'], ['third attack'], ['recovery'], ['dual parry', 'pugil'], ['counter'], ['ground control', 'defend'],
['fourth attack'], ['battle tactics'], ['enhanced damage II'], ['enlist'], ['block retreat']]
};
Цикл, который я хотел бы использовать, но, очевидно, неверен:
tableData(props) {
let data = '';
for (var i = 0; i < this.props.levels.length; i ) {
data.concat('<tr><td>Level ' props.levels[i] '</td>');
for (var j = 0; j < props.skills[i].length; j ) {
if (j % 2 === 0) {
data.concat('<td>' props.skills[i][j] '</td</tr>');
if (j !== props.skills[i].length - 1) { data.concat('<tr><td></td>');}
} else {
data.concat('<td>' props.skills[i][j] '</td>');
if (j === props.skills[i].length - 1) {data.concat('<td></td></tr>');}
}
}
}
return data;
};
Мой рендеринг:
render() {
return (
<Table striped bordered hover variant="dark">
<thead>
<tr>
<th><strong>Your list of skills:</strong></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
{this.tableData}
</tbody>
</Table>
);
}
Чего я пытаюсь достичь:
Я хочу создать таблицу с 3 столбцами, то есть по 3 <td>
в строке. В первом <td>
будет уровень, на котором приобретается способность. Это будет показано только в первой строке, где начинаются возможности для этого уровня. Все последовательные строки будут иметь первое <td>
пустое место до достижения записей следующего уровня. Фактические возможности будут только во 2-м и 3-м столбцах / <td>
-х.
Вроде как это, извините, если это плохой пример:
|-----|-----|-----|
|Lvl1 | axe |sword|
|-----|flail|-----|
|Lvl2 |kick |trip |
|-----|punch|smell|
|-----|slap |-----|
|Lvl5 |-----|-----|
Редактировать:
Я вижу много людей, использующих методы .map()
и .filter()
для обработки подобных вещей, но моя проблема в том, что у меня есть несколько условий, с которыми я не уверен, как справиться.
Если я попытаюсь просто распечатать массив, <td>
с .map()
ним все будет хорошо, но либо мои навыки JavaScript / jsx сейчас просто плохи, либо есть лучший способ справиться с условиями, чтобы он печатался в формате, который я ищу.
Правка2
Теперь я пытаюсь заставить что-то подобное работать в рендеринге:
let levels = this.props.skills.levels;
let skills = this.props.skills.skills;
{levels.map(function(obj, i) {
return (
<tr><td>Level {obj}</td>
skills[i].map(function(obj2, j) {
if (j % 2 === 0) {
<TableData skill={obj2[i][j]} /></tr>
if (j !== obj2[i].length - 1) { <tr><TableData /> }
} else {
<TableData skill={obj2[i][j]} /></td>;
if (j === props.skills[i].length - 1) {<TableData /></tr>}
}
});
)
)}
Редактировать 3
Я подумал, что, возможно, троичный оператор может быть подходящим. Я все еще получаю много ошибок jsx, потому что элементы jsx не закрыты «должным образом», хотя цель оператора — закрыть их.
{levels.map(function(obj, i) {
return (<tr><td>Level {obj}</td>
skills[i].map(function(obj2, j) {
(j % 2 === 0) ?
(j !== obj2[i][j].length - 1) ? (<TableData skill={obj2[i][j]} /></tr><tr><TableData />) : (<TableData skill={obj2[i][j]} /></tr>)
: (j === obj2[i].length - 1) ? (<TableData skill={obj2[i][j]} /></td><TableData /></tr>) : (<TableData skill={obj2[i][j]} /></td>);
});
)
)}
Редактировать 4 Приближается
tableData(props) {
let levels = this.props.skills.levels;
let skills = this.props.skills.skills;
let data = [];
for (var i = 0; i < levels.length; i ) {
//<tr>beginning
data.push(<Level level={i} key={i * 100} />);
for (var j = 0; j <= skills[i].length; j ) {
if (j % 2 === 0) {
data.push(<TableData skill={skills[i][j]} key={i j} />); //</tr> end
if (j !== skills[i].length - 1) { data.push(<TableData key={(i j) * 200} />);}//<tr> beginning
} else {
data.push(<TableData skill={skills[i][j]} key={i j} />);
if (j === skills[i].length - 1) {data.push(<TableData key={(i j) * 100} />)} //</tr> end
}
}
}
return data;
};
С помощью этой функции я могу печатать все в тегах данных таблицы. Однако я все еще не могу поместить теги строк таблицы туда, куда им нужно. Если я не закрываю теги, я получаю ошибку jsx, даже если конечный результат теоретически должен быть правильным.
Комментарии:
1. Предполагается, что каждый массив в навыках соответствует уровню?
2. @Yatrix Да, индекс каждого уровня соответствует индексу массива внутри массива навыков. Таким образом, уровень 1 с индексом 0 соответствует [‘axe’, ‘dagger’, ‘flail’, …], который также является индексом 0 навыков.
3. Итак, в первом <td> есть уровень, во втором td есть навыки, но что должно быть в третьем td?
4. Что-то вроде этого codesandbox.io/s/headless-cdn-vgqfx ?
5. Рад, если бы я мог помочь :). Я опубликовал свой ответ, поэтому вы можете пометить его как решение
Ответ №1:
На мой взгляд, лучший способ — сначала структурировать данные, а затем отобразить их позже, чтобы вам не приходилось возиться с закрывающими тегами и т.д. Вы могли бы использовать цикл for и выполнять итерации по каждому 2 элементу для создания таблицы.
<div className="App">
<table>
<tbody>
{levels.map((item, i) => {
var skl = [];
for (let j = 0; j < skills[i].length; j = j 2) {
if (j < 2) {
skl.push(
<tr>
<td>Level {item}</td>
<td>{skills[i][0]}</td>
<td>{skills[i][1]}</td>
</tr>
);
} else {
skl.push(
<tr>
<td></td>
<td>{skills[i][j]}</td>
<td>{skills[i][j 1]}</td>
</tr>
);
}
}
return (
<React.Fragment>
{skl.map((item) => {
return item;
})}
</React.Fragment>
);
})}
</tbody>
</table>
</div>