我正在为此抓挠头。而且我发现这也不容易解释。我会尽力的:
我有一个html表,每行都有一个图像,除其他元素外,还有一个带下拉列表的前10个列表,用于对图像进行排名。
当用户选择排名时,数据库将相应地更新->
当前图像的前10名排名保存在图像条目中,并且继承位置的前一幅图像的排名更新为“空”。 (这已经在工作->因此,如果我重新加载页面,一切都会正常进行)。
我无法实现的是,我从数据库收到的更新后的图像数组将更新状态(或道具),因此无法获得以前继承等级的图像的选定选项值。
这是我的ImageList
组件(重要部分):
class ImageList extends Component {
constructor(props) {
super(props)
this.state = {
project: [],
description: '',
name: '',
values: [],
value: '',
positions: props.positions
}
}
updatePosition = (projectId, projectName, imageId, imgName, i, e) => {
this.props.setGridPosition(
projectId,
projectName,
imageId,
imgName,
e.target.value
)
}
getAllImages() {
let imageList = []
if (this.props.project.project) {
const { project, waiting } = this.props.project
for (let [i, img] of project.images.entries()) {
if (!img.isDeleted) {
let options = ['-', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
this.props.positions[i] = img.gridPosition
let imgSrc = `/public/${project._id}/${img.originalName}`
imageList.push(
<tr
key={img._id}
style={waiting ? { opacity: '.5' } : { opacity: '1' }}
>
<td>
<img src={imgSrc} alt="" style={{ width: '60px' }} />
</td>
<SelectFieldGroup
name={`placeInGrid_${i}`}
onChange={this.updatePosition.bind(
this,
project._id,
project.name,
img._id,
img.originalName,
i
)}
options={options}
value={this.props.positions[i]}
/>
</td>
</tr>
)
}
}
}
return imageList
}
render() {
return (
<div className={styles['image-list']}>
<table className={styles['image-table']}>
<tbody>{this.getAllImages()}</tbody>
</table>
</div>
)
}
}
const mapStateToProps = state => ({
auth: state.auth,
project: state.project
})
export default connect(
mapStateToProps,
{ deleteImage, setGridPosition }
)(ImageList)
我从上级组件接收道具-项目和位置(作为一个空数组)。
我希望问题能以某种方式解决。我将非常感谢您提供的任何帮助或指向我出问题的地方的提示。
编辑: 根据要求,为澄清起见,下面是代码的其他一些部分:
SelectFieldGroup.js
:
import React from 'react'
import PropTypes from 'prop-types'
import cx from 'classnames'
import globalStyles from './Bootstrap.module.css'
import commonStyles from './Common.module.sass'
const SelectFieldGroup = ({ name, onChange, options, value, disabled }) => {
let optionArray = []
for (let [index, option] of options.entries()) {
optionArray.push(<option key={index}>{option}</option>)
}
return (
<div className={globalStyles['form-group']}>
<select
value={value}
className={cx(
globalStyles['custom-select'],
commonStyles['custom-select'],
commonStyles['dark-input']
)}
name={name}
onChange={onChange}
disabled={disabled}
>
{optionArray}
</select>
</div>
)
}
SelectFieldGroup.propTypes = {
name: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired,
disabled: PropTypes.string
}
export default SelectFieldGroup
imageActions.
的相关部分:
export const setGridPosition = (
projectId,
projectName,
imageId,
imageName,
position
) => dispatch => {
dispatch(setWaiting())
const data = {
projectId: projectId,
projectName: projectName,
imageId: imageId,
imageName: imageName,
position: position
}
console.log(projectId)
axios
.post('/api/projects/set_grid_position', data)
.then(res => {
console.log(res.data)
dispatch({
type: SET_GRID_POSITION,
payload: res.data
})
})
.catch(err =>
dispatch({
type: GET_ERRORS,
payload: {}
})
)
}
节点表达api:
router.post(
'/set_grid_position',
passport.authenticate('jwt', { session: false }),
(req, res) => {
const errors = {}
Project.findById(req.body.projectId).then(currentProject => {
let updatedProject = currentProject
ProjectGridPosition.findOne({ position: req.body.position }).then(
gridPosition => {
if (req.body.position != '-') {
// Mark the previous position of the image as empty.
ProjectGridPosition.findOne({ imageId: req.body.imageId })
.then(oldPos => {
oldPos.isTaken = false
oldPos.save()
})
.catch(err => res.status(400).json(err))
// Set the gridPosition inside the image.
currentProject.images.forEach(img => {
if (img._id == req.body.imageId) {
img.gridPosition = req.body.position
}
})
currentProject.save(err => {
if (err) res.json(err)
else {
updatedProject = currentProject
}
})
if (gridPosition) {
if (gridPosition.projectId) {
Project.findById(gridPosition.projectId)
.then(project => {
console.log(project.name)
project.images.forEach(img => {
if (img.gridPosition == req.body.position) {
console.log(img.originalName)
img.gridPosition = '-'
}
})
project.save(err => {
if (err) {
res.json(err)
} else {
if (project == currentProject) {
updatedProject = currentProject
}
}
})
})
.catch(err => res.json(err))
}
gridPosition.projectId = req.body.projectId
gridPosition.projectName = req.body.projectName
gridPosition.imageId = req.body.imageId
gridPosition.imageName = req.body.imageName
gridPosition.isTaken = true
gridPosition.save()
res.json(updatedProject)
} else {
const newPosFields = {
projectId: req.body.projectId,
projectName: req.body.projectName,
imageId: req.body.imageId,
imageName: req.body.imageName,
position: req.body.position,
isTaken: true
}
new ProjectGridPosition(newPosFields)
.save()
.then(() => {
currentProject.save().then(() => {
res.json(currentProject)
})
})
.catch(err => res.json(err))
}
} else {
currentProject.images.forEach(img => {
if (img._id == req.body.imageId) {
img.gridPosition = req.body.position
}
})
currentProject.save(err => {
if (err) res.json(err)
ProjectGridPosition.findOne({ imageId: req.body.imageId }).then(
newPos => {
newPos.isTaken = false
newPos.save().then(() => {
currentProject.save().then(() => {
res.json(currentProject)
})
})
}
)
})
}
}
)
})
}
)
最后,是projectReducer.js
的相关部分:
import {
// ...
SET_GRID_POSITION
} from '../actions/types'
const initialState = {
project: null,
projects: null,
loading: false,
waiting: false
}
export default function(state = initialState, action) {
switch (action.type) {
// ....
case SET_GRID_POSITION:
return {
...state,
project: action.payload,
waiting: false
}
default:
return state
}
}
答案 0 :(得分:0)
因此,我设法通过重组并完全摆脱了ProjectGridPosition模型来使其工作。这样做使整个过程变得更加简单。然后,我完全重写了路线:
router.post(
'/set_grid_position',
passport.authenticate('jwt', { session: false }),
async (req, res) => {
let project = await getProjectById(req.body.projectId)
const query = {
'images.gridPosition': req.body.position
}
let formerRankProject = await getProjectByQuery(query)
project = await updateRank(project, req.body.imageId, req.body.position)
if (formerRankProject !== null) {
formerRankProject = await UpdateIfDifferentProject(
formerRankProject,
project._id,
req.body
)
formerRankProject.save()
}
project
.save()
.then(project => res.json(project))
.catch(err => res.json(err))
}
)
现在可以使用了。我不完全知道问题出在哪里,但是正如@Tex在评论中指出的那样,我有很多层次的嵌套-因此可能肯定会出问题。
我将其标记为正确的答案-尽管这可以解决,但人们知道,我仍在寻求帮助。