Проблемы с использованием Microsoft.JSInterop в приложениях Blazor
У меня есть экран клиента, который я создал с помощью Razor View, он имеет только все опции CRUD.
Проблема заключается в том, что когда я создаю или изменяю ВСЕ ПРОСМОТР ВИДА УЧЕТНОЙ ЗАПИСИ на странице Загрузка..., и это неправильно.
Только Delete работает отлично, когда я удаляю клиента, обновляется только таблица регистрации
Контроллер был создан с опцией Entity Framework: API Controller с действиями, используя Entity Famework
Смотрите код для моего Razor View.
@using TesteBlazor.Shared
@using TesteBlazor.Shared.Models
@page "/clientes"
@using Microsoft.JSInterop
@inject HttpClient Http
<h1> Blazor - CRUD com EF Core</h1>
<hr />
<table width="100%" style="background:#05163D;color:honeydew">
<tr>
<td width="20"> </td>
<td>
<h2>Cadastro de Clientes</h2>
</td>
<td> </td>
<td align="right">
<button class="btn btn-info" onclick="@AddNovoCliente">Incluir Novo Cliente</button>
</td>
<td width="10"> </td>
</tr>
<tr>
<td colspan="2"></td>
</tr>
</table>
<hr />
<form>
<table class="form-group">
<tr>
<td>
<label for="Name" class="control-label">Código</label>
</td>
<td>
<input type="text" class="form-control" bind="@cliente.ClienteId" readonly />
</td>
<td width="20"> </td>
<td>
<label for="Name" class="control-label">Nome</label>
</td>
<td>
<input type="text" class="form-control" bind="@cliente.Nome" />
</td>
</tr>
<tr>
<td>
<label for="Email" class="control-label">Email</label>
</td>
<td>
<input type="text" class="form-control" bind="@cliente.Email" />
</td>
<td width="20"> </td>
<td>
<label for="Pais" class="control-label">Pais</label>
</td>
<td>
<input type="text" class="form-control" bind="@cliente.Pais" />
</td>
</tr>
<tr>
<td>
<button type="submit" class="btn btn-success" onclick="@(async () => await AddCliente())"
style="width:220px;">
Salvar
</button>
</td>
</tr>
</table>
</form>
<table width="100%" style="background:#0A2464;color:honeydew">
<tr>
<td width="20"> </td>
<td>
<h2>Detalhes dos Clientes</h2>
</td>
</tr>
<tr>
<td colspan="2"></td>
</tr>
</table>
@if (_clientes == null)
{
<p><em>Carregando...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Codigo</th>
<th>Nome</th>
<th>Email</th>
<th>Pais</th>
</tr>
</thead>
<tbody>
@foreach (var cli in _clientes)
{
<tr>
<td>@cli.ClienteId</td>
<td>@cli.Nome</td>
<td>@cli.Email</td>
<td>@cli.Pais</td>
<td>
<button class="btn btn-primary" onclick="@(async () => await EditCliente(@cli.ClienteId))"
style="width:110px;">
Editar
</button>
</td>
<td>
<button class="btn btn-danger" onclick="@(async () => await DeleteCliente(@cli.ClienteId))">
Deletar
</button>
</td>
</tr>
}
</tbody>
</table>
}
@functions {
Cliente[] _clientes;
Cliente cliente = new Cliente();
string ids = "0";
bool exibeLinhaIncluida = false;
//carrega clientes
protected override async Task OnInitAsync()
{
_clientes = await Http.GetJsonAsync<Cliente[]>("/api/Clientes/");
}
//adicionar novo cliene
void AddNovoCliente()
{
cliente = new Cliente();
}
// Adicionar detalhes
protected async Task AddCliente()
{
if (cliente.ClienteId == 0)
{
await Http.SendJsonAsync(HttpMethod.Post, "/api/Clientes/", cliente);
}
else
{
await Http.SendJsonAsync(HttpMethod.Put, "/api/Clientes/" + cliente.ClienteId, cliente);
}
cliente = new Cliente();
_clientes = await Http.GetJsonAsync<Cliente[]>("/api/Clientes/");
}
// Editar
protected async Task EditCliente(int clienteID)
{
ids = clienteID.ToString();
cliente = await Http.GetJsonAsync<Cliente>("/api/Clientes/" + Convert.ToInt32(clienteID));
}
// deletar
protected async Task DeleteCliente(int clienteID)
{
ids = clienteID.ToString();
await Http.DeleteAsync("/api/Clientes/" + Convert.ToInt32(clienteID));
_clientes = await Http.GetJsonAsync<Cliente[]>("/api/Clientes/");
}
}
1 ответ
@Cyberlacs,
- Вы не должны использовать элемент таблицы для макета. Вы можете использовать этот элемент для отображения табличных данных.
- Вы не должны использовать элемент формы в своем коде, а также не должны использовать атрибут типа кнопки для "отправки". Когда вы нажимаете кнопку отправки, браузер отправляет данные вашей формы на сервер обычным способом. Никто на сервере, однако, не приветствует опубликованные данные формы. Но, увы, обработчик события нажатия кнопки также вызывается сразу после "post back":
onclick="@(async () => await AddCliente())"
, которые используют Ajax для вызова вашего сервера, используя, на этот раз, HttpClient. Вы должны понимать, что Blazor - это структура пользовательского интерфейса для создания SPA-приложений, таких как Angular. Не отправляйте и не отправляйте сообщения в обычном порядке. Ваш SPA связывается с Сервером, используя HttpClient. HttpClient использует Ajax-вызовы для этой цели. Правда в том, что HttpClient использует JavaScript Fetch API (не XmlHttpRequest).
Примечание. Насколько мне известно, внутренний код Blazor должен отменять отправку формы, вызывая event.preventDefault() в коде JavaScript, который используется для выполнения JSInterop.
Решение: удалите элемент формы и используйте вместо него элемент div. Кроме того, установите атрибут типа кнопки "кнопка"
Сделайте ваши компоненты проще...
Надеюсь это поможет...