Почему моя запись не обновляется в приложении ASP.NET CORE React Redux? - PullRequest
0 голосов
/ 22 марта 2019

Я новичок в React с Redux, и я работаю над новым веб-приложением, которое имеет некоторые базовые операции.Я создаю это с помощью ASP.NET Core с шаблоном хранилища.

Мое приложение правильно показывает данные, и я также могу правильно добавлять данные, проблема в том, что обновление моих данных не работает.Пока данные передаются в контроллер, вы можете видеть изменения в параметре, как только я пытаюсь зафиксировать данные, которые он не обновляет.

Мой проект настроен следующим образом, я сократилнекоторые части включают только компонент, с которым я работаю.

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);
}

Услуги / 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);            
    }
}

Следующая часть - это контроллер, который вызывается из реагивыполнять операции CRUD, а также передавать данные в API.Чтение и добавление, кажется, работают, но обновление не работает, вы можете видеть, что обновленные данные передаются в vessel, но они не фиксируются и просто обновляются со старыми данными.

Контроллеры/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"
        });
    }
}

Вот код для моей конфигурации React / Redux.Опять же, я включил только код для моего относительного компонента.

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;
};

Итак, это мое приложение, оно базовое, и я все еще учусь, но не вижу логической причины отсутствия фиксации в обновлении.метод.Сохранение контекста обрабатывается в репозитории, и я знаю, что оно попадает в него, а записи не обновляются.Может кто-нибудь помочь мне понять, где я ошибся?

1 Ответ

1 голос
/ 22 марта 2019

Если ваш вопрос содержит полный код, я считаю, что проблема в методе обновления вашего репозитория. Он ничего не делает.

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();
}
...