#javascript #asp.net-core #react-redux
#javascript #asp.net-core #react-redux
Вопрос:
Я новичок в React с Redux и работаю над новым веб-приложением, в котором есть некоторые базовые операции crud. Я создаю это с помощью ASP.NET Ядро с шаблоном репозитория.
Мое приложение корректно отображает данные, и я также могу корректно добавлять данные, проблема в том, что обновление моих данных не работает. Пока данные передаются в контроллер, вы можете видеть изменения, содержащиеся в параметре, как только я пытаюсь зафиксировать данные, они не обновляются.
Мой проект настроен следующим образом, я сократил некоторые его части, чтобы включить только компонент, с которым я работаю.
Shelly.Data
|-BaseEntity.cs
|-Vessel.cs
Shelly.Repo
|-IRepository.cs
|-Repository.cs
|-ShellyContext.cs
Shelly.Services
|-IVesselService.cs
|-VesselService.cs
Shelly.UI
|-ClientApp
|-src
|-components
|-vessels
|-VesselsComponent.js
|-store
|-Vessels.js
Я включил код из своего репозитория в этот вопрос, поскольку я не уверен, что проблема связана с моей настройкой React, но, возможно, кто-нибудь сможет мне с этим помочь.
Repo / IRepository.cs
public interface IRepository<TEntity> where TEntity : BaseEntity
{
IEnumerable<TEntity> GetAll();
TEntity Get(long id);
void Insert(TEntity entity);
void Update(TEntity entity);
void Delete(TEntity entity);
void Remove(TEntity entity);
void SaveChanges();
}
Repo / Repository.cs
public class Repository<TEntity> : IRepository<TEntity> where TEntity : BaseEntity
{
private readonly ShellyContext _dbContext;
private DbSet<TEntity> entities;
string errorMessage = string.Empty;
public Repository(ShellyContext context)
{
this._dbContext = context;
entities = context.Set<TEntity>();
}
...
public void Update(TEntity entity)
{
if (entity == null)
{
throw new ArgumentNullException("entity");
}
_dbContext.SaveChanges();
}
public void SaveChanges()
{
_dbContext.SaveChanges();
}
...
}
Сервисы / IVesselService
public interface IVesselService
{
IEnumerable<Vessel> GetVessels();
Vessel GetVessel(long id);
void InsertVessel(Vessel vessel);
void UpdateVessel(Vessel vessel);
void DeleteVessel(long id);
}
Services/VesselService
public class VesselService : IVesselService
{
private IRepository<Vessel> vesselRepository;
public VesselService(IRepository<Vessel> vesselRepository)
{
this.vesselRepository = vesselRepository;
}
public void UpdateVessel(Vessel vessel)
{
vesselRepository.Update(vessel);
}
}
The next part is the controller which is called from react to carry out the CRUD operations and also serve up the data to the API. Reading and Added seem to work but Updating isn’t, you can see the updated data being passed in vessel
but it doesn’t seem to commit and just refreshes with the old data.
Controllers/VesselDataController.cs
[Route("api/[controller]")]
public class VesselDataController : Controller
{
private readonly IVesselService vesselService;
public VesselDataController(IVesselService vesselService)
{
this.vesselService = vesselService;
}
...
[HttpPost]
public ActionResult AddVessel([FromBody]Vessel vessel)
{
vesselService.InsertVessel(vessel);
return Ok(new
{
success = true,
returncode = "200"
});
}
[HttpPut]
public ActionResult Update([FromBody]Vessel vessel)
{
vesselService.UpdateVessel(vessel);
return Ok(new
{
success = true,
returncode = "200"
});
}
}
Here is the code for my React/Redux configuration. Again, I’ve only included code for my relative component.
ClientApp/src/components/VesselsComponent.js
import React, { Component } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { actionCreators } from '../../store/Vessels';
class VesselsComponent extends Component {
state = {
name: "",
imo: "",
editing: ""
};
componentWillMount() {
this.props.requestVessels();
}
toggleEditing(itemId) {
console.log("Editing" ' ' itemId);
this.setState({ editing: itemId });
}
handleVesselUpdate(vessel) {
this.props.updateVessel(vessel);
setTimeout(this.props.requestVessels, 600);
}
handleEditItem() {
let itemId = this.state.editing;
var editVessel = this.props.vessels.find((v) => v.Id === itemId);
editVessel.IMO = this.refs[`IMO_${itemId}`].value;
editVessel.AddedDate = this.refs[`AddedDate_${itemId}`].value;
editVessel.ModifiedDate = this.refs[`ModifiedDate_${itemId}`].value;
this.handleVesselUpdate(editVessel);
this.setState({ editing: "" });
}
renderItemOrEditField(vessel) {
if (this.state.editing === vessel.Id) {
return (
<tr key={vessel.Id}>
<td>{vessel.Name}</td>
<td>{vessel.IMO}</td>
<td>
<input onKeyDown={this.handleEditField} type="text" ref={`IMO_${vessel.Id}`} name="IMO" defaultValue={vessel.IMO} />
<input onKeyDown={this.handleEditField} type="text" ref={`AddedDate_${vessel.Id}`} name="AddedDate" defaultValue={vessel.AddedDate} />
<input onKeyDown={this.handleEditField} type="text" ref={`ModifiedDate_${vessel.Id}`} name="ModifiedDate" defaultValue={vessel.ModifiedDate} />
</td>
<td>
<button onClick={this.handleEditItem.bind(this)} label="Update Item">Update</button>
</td>
</tr>
)
} else {
return (
<tr key={vessel.Id}>
<td>{vessel.Name}</td>
<td>{vessel.IMO}</td>
<td><button onClick={this.toggleEditing.bind(this, vessel.Id)} className="btn btn-info">Edit</button></td>
</tr>);
}
}
renderVesselsTable(props) {
return (
<table className="table">
<thead className="thead-dark">
<tr>
<th>Name</th>
<th>IMO</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{props.vessels.map(vessel =>
this.renderItemOrEditField(vessel)
)}
</tbody>
</table>
)
}
render() {
return (
<div>
<h3>Vessels</h3>
{this.renderVesselsTable(this.props)}
<table className="table">
<thead className="thead-dark">
</thead>
<tbody>
<tr>
<td>Name:</td>
<td>
<input className="form-control" id="vesselName" type="text" value={this.state.name} onChange={(ev) => this.setState({ name: ev.target.value })} />
</td>
</tr>
<tr>
<td>IMO:</td>
<td>
<input className="form-control" id="vesselImo" type="text" value={this.state.imo} onChange={(ev) => this.setState({ imo: ev.target.value })} />
</td>
</tr>
<tr>
<td>
<button className="btn btn-default btn-success" onClick={this.addVessel.bind(this)}>Add Vessel</button>
</td>
</tr>
</tbody>
</table>
</div>
);
}
}
export default connect(
state => state.vessels,
dispatch => bindActionCreators(actionCreators, dispatch)
)(VesselsComponent);
Наконец, вот Vessel.js
из store
.
const requestVesselsType = 'REQUEST_VESSELS';
const receiveVesselsType = 'RECEIVE_VESSELS';
const requestVesselType = 'REQUEST_VESSEL';
const receiveVesselType = 'RECEIVE_VESSEL';
const addVesselType = 'ADD_VESSEL';
const updateVesselType = "UPDATE_VESSEL";
const initialState = { vessels: [], vessel: {}, isLoading: false };
let currentvessel = {};
export const actionCreators = {
requestVessels: () => async (dispatch, getState) => {
dispatch({ type: requestVesselsType });
const url = 'api/VesselData/GetVessels';
const response = await fetch(url);
const allvessels = await response.json();
dispatch({ type: receiveVesselsType, allvessels });
},
requestVessel: () => async (dispatch, getState) => {
dispatch({ type: requestVesselType });
const url = 'api/VesselData/GetVessel/${id}';
const response = await fetch(url);
const vessel = await response.json();
dispatch({ type: receiveVesselType, vessel });
},
updateVessel: (vessel) => async (dispatch, getState) => {
const baseURL = "/api/VesselData";
const data = JSON.stringify({
Id: vessel.Id,
Name: vessel.Name,
IMO: vessel.IMO,
ModifiedDate: vessel.ModifiedDate,
AddedDate: vessel.AddedDate
});
const fetchTask = fetch(baseURL, {
method: "PUT",
headers: {
Accept: "application/json",
"Content-Type" : "application/json",
},
body: data
})
.then((data => {
dispatch({ type: updateVesselType, vessel: data })
}))
}
}
export const reducer = (state, action) => {
state = state || initialState;
if (action.type === requestVesselsType) {
return {
...state,
isLoading: true
};
}
if (action.type === receiveVesselsType) {
return {
...state,
vessels: action.allvessels,
isLoading: false
}
}
if (action.type === requestVesselType) {
return {
...state,
isLoading: true
};
}
if (action.type === receiveVesselType) {
currentvessel = action.vessel;
return {
...state,
vessel: currentvessel,
isLoading: false
}
}
if (action.type === updateVesselType) {
return {
...state,
isLoading: false
};
}
return state;
};
Итак, это мое приложение, оно базовое, и я все еще учусь по ходу дела, но я не вижу никакой логической причины отсутствия фиксации в методе update. Сохранение контекста обрабатывается в репозитории, и я знаю, что он попадает в него, и запись не обновляется. Кто-нибудь может помочь мне понять, где я ошибся?
Ответ №1:
Если ваш вопрос содержит полный код, я полагаю, проблема в вашем методе обновления репозитория. Это ничего не делает.
public void Update(TEntity entity)
{
if (entity == null)
{
throw new ArgumentNullException("entity");
}
_dbContext.SaveChanges();
}
Вам нужно присоединить объект, который вы хотите обновить, к DbContext
. Вы можете сделать это с помощью метода DbContext.Update
Попробуйте вызвать Update
раньше SaveChanges
, вот так
public void Update(TEntity entity)
{
if (entity == null)
{
throw new ArgumentNullException("entity");
}
_dbContext.Update(entity); //add this line
_dbContext.SaveChanges();
}
Комментарии:
1. Боже, ты на 100% прав. Слишком просто, возможно, я слишком долго смотрел на это. Спасибо за проверку моей работы на вменяемость, огромная помощь 🙂 приветствия