Как получить данные в JSX и загрузить на страницу? - PullRequest
0 голосов
/ 24 февраля 2020

Я пытаюсь использовать ядро ​​ASP. NET с реакцией и jsx, пока что я могу получить данные, но когда я запускаю FetchCustomer.tsx, он пуст.

Это контроллер

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using ICTask1.Models;

namespace ICTask1.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class CustomersController : ControllerBase
{
    private readonly DBContext _context;

    public CustomersController(DBContext context)
    {
        _context = context;
    }

    // GET: api/Customers
    [HttpGet]
    public async Task<ActionResult<IEnumerable<Customer>>> GetCustomer()
    {
        return await _context.Customer.ToListAsync();
    }

    // GET: api/Customers/5
    [HttpGet("{id}")]
    public async Task<ActionResult<Customer>> GetCustomer(int id)
    {
        var customer = await _context.Customer.FindAsync(id);

        if (customer == null)
        {
            return NotFound();
        }

        return customer;
    }

    // PUT: api/Customers/5
    // To protect from overposting attacks, please enable the specific properties you want to bind to, for
    // more details see https://aka.ms/RazorPagesCRUD.
    [HttpPut("{id}")]
    public async Task<IActionResult> PutCustomer(int id, Customer customer)
    {
        if (id != customer.ID)
        {
            return BadRequest();
        }

        _context.Entry(customer).State = EntityState.Modified;

        try
        {
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!CustomerExists(id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }

        return NoContent();
    }

    // POST: api/Customers
    // To protect from overposting attacks, please enable the specific properties you want to bind to, for
    // more details see https://aka.ms/RazorPagesCRUD.
    [HttpPost]
    public async Task<ActionResult<Customer>> PostCustomer(Customer customer)
    {
        _context.Customer.Add(customer);
        await _context.SaveChangesAsync();

        return CreatedAtAction("GetCustomer", new { id = customer.ID }, customer);
    }

    // DELETE: api/Customers/5
    [HttpDelete("{id}")]            
    public async Task<ActionResult<Customer>> DeleteCustomer(int id)
    {
        var customer = await _context.Customer.FindAsync(id);
        if (customer == null)
        {
            return NotFound();
        }

        _context.Customer.Remove(customer);
        await _context.SaveChangesAsync();

        return customer;
    }

    private bool CustomerExists(int id)
    {
        return _context.Customer.Any(e => e.ID == id);
    }
}}

Это мой FetchCustomer.tsx

import * as React from 'react';
import { RouteComponentProps } from 'react-router';
import { Link, NavLink } from 'react-router-dom';

interface FetchCustomerData {
customerList: CustomerData[];
loading: boolean;
}

export class FetchCustomer extends React.Component<RouteComponentProps<any, any>, FetchCustomerData> {

constructor(props: any) {
    super(props);
    this.state = { customerList: [], loading: true };
    fetch('api/Customers')
        .then(response => response.json() as Promise<CustomerData[]>)
        .then(data => {
            this.setState({ customerList: data, loading: true });
        });

    this.handleDelete = this.handleDelete.bind(this);
    this.handleEdit = this.handleEdit.bind(this); 
}

public render() {
    let contents = this.state.loading
        ? <p><em>Loading...</em></p>
        : this.renderCustomerTable(this.state.customerList);

    return <div>
        <p>
            <Link to="api/Customer">Create New</Link>
        </p>
        {contents}
    </div>;
}

//Delete
private handleDelete(id: number) {
    if (!confirm("Are you sure?" + id))
        return;
    else {
        fetch('api/Customers/5/' + id, {
            method: 'delete'
        }).then(data => {
            this.setState(
                {
                    customerList: this.state.customerList.filter((rec) => {
                        return (rec.customerId != id);
                    })
                });
        });
    }
}

private handleEdit(id: number) {
    this.props.history.push('api/Customers' + id);
}

private renderCustomerTable(customerList: CustomerData[]) {

    return <table className='table'>
        <p>This is table</p>
        <thead>
            <tr>
                <th>ID</th>
                <th>Name</th>
                <th>Address</th>
                <th>Action</th>
                <th>Action</th>
            </tr>
        </thead>
        <tbody>
            {
                customerList.map(cust =>
                    <tr key={cust.customerId}>
                    <td></td>
                        <td>{cust.name}</td>
                        <td>{cust.address}</td>
                        <td>
                            <a className="action" onClick={(id) => this.handleEdit(cust.customerId)}>Edit</a>  |
                        <a className="action" onClick={(id) => this.handleDelete(cust.customerId)}>Delete</a>
                        </td>
                        </tr>
            )}
        </tbody>
    </table>;

}

}

export class CustomerData {
customerId: number = 0;
name: string = "";
address: string = "";
}

API в контроллере клиента работает нормально, вот вывод. Я использовал api / Customers в FetchCustomer.

Когда я запускаю проект, нет ошибки, страница загружается нормально, но данные не видны

enter image description here

Когда я запускаю FetchCustomer Я получаю это

enter image description here

Ответы [ 2 ]

0 голосов
/ 24 февраля 2020

В вашем коде есть несколько проблем:

  1. Как указано выше в @Agney, вы должны изменить загрузку на false при загрузке. В противном случае сама таблица не будет отображена.
  2. Ваш сервер возвращает список клиентов со свойством Id, а клиент TypeScript ожидает свойство customerId. Вам необходимо сопоставить массив {id, name, address} с массивом {customId, name, address}
  3. Вы вложили элемент <p> в <table/>, что неверно.
  4. The * Функция 1020 * выдвигает URL как this.props.history.push('api/Customers' + id);. Скорее всего, вы должны изменить его на ('api/Customers/'+ id);
  5. Кроме того, у вас есть 5 <th> в <thead> при 4 <td> в каждом ряду.

Чтобы исправить вышеуказанные проблемы, вы можете изменить код, как показано ниже:

export class FetchCustomer extends React.Component<RouteComponentProps<any, any>, FetchCustomerData> {

    constructor(props: any) {
        super(props);
        this.state = { customerList: [], loading: true };
        fetch('api/Customers')
            .then(response => response.json())
            // map each {id} to {customId}
            .then(data => data.map((d: any) => { return { ...d, customerId : d.id };}) )
            .then((data: CustomerData[]) => {
                // change {loading} to false
                this.setState({ customerList: data, loading: false});
            });
        this.handleDelete = this.handleDelete.bind(this);
        this.handleEdit = this.handleEdit.bind(this);
    }

    public render() {
        let contents = this.state.loading
            ? <p><em>Loading...</em></p>
            : this.renderCustomerTable(this.state.customerList);

        return <div>
            <p>
                <Link to="api/Customer">Create New</Link>
            </p>
            {contents}
        </div>;
    }

    //Delete
    private handleDelete(id: number) {
        if (!confirm("Are you sure?" + id))
            return;
        else {
            fetch('api/Customers/5/' + id, {
                method: 'delete'
            }).then(data => {
                this.setState(
                    {
                        customerList: this.state.customerList.filter((rec) => {
                            return (rec.customerId != id);
                        })
                    });
            });
        }
    }

    private handleEdit(id: number) {
        this.props.history.push('api/Customers/' + id);
    }

    private renderCustomerTable(customerList: CustomerData[]) {

        return <div>
        <p>This is table</p>
        <table className='table'>
            <thead>
                <tr>
                    <th >ID</th>
                    <th>Name</th>
                    <th>Address</th>
                    <th>Action</th>
                </tr>
            </thead>
            <tbody>
                {
                    customerList.map(cust =>
                        <tr key={cust.customerId}>
                            <td>{cust.customerId}</td>
                            <td>{cust.name}</td>
                            <td>{cust.address}</td>
                            <td>
                                <a className="action" onClick={(id) => this.handleEdit(cust.customerId)}>Edit</a>  |
                                <a className="action" onClick={(id) => this.handleDelete(cust.customerId)}>Delete</a>
                            </td>
                        </tr>
                    )}
            </tbody>
        </table>
        </div>;

    }

}
0 голосов
/ 24 февраля 2020

Фактические данные обещания будут в файле response.data. Попробуйте дать код ниже.

this.setState({ customerList: data.data, loading: true });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...