Problems with @using Microsoft.JSInterop in Blazor applications

二次信任 提交于 2019-12-13 11:06:05

问题


I have a client screen that I created using Razor View, it only has all CRUD options.

The problem is when I create or change an account's ALL VIEW VIEW of Loading ... and this is not correct.

Only Delete works perfectly, when I delete a client, only the registration table is updated

The Controller was created with the Entity Framework option: API Controller with actions, using Entity Famework

See the code for my 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">&nbsp;</td>
        <td>
            <h2>Cadastro de Clientes</h2>
        </td>
        <td>&nbsp;</td>
        <td align="right">
            <button class="btn btn-info" onclick="@AddNovoCliente">Incluir Novo Cliente</button>
        </td>
        <td width="10">&nbsp;</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">&nbsp;</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">&nbsp;</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">&nbsp;</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,

  1. You should not use the table element for layout. You may use this element to display tabular data.
  2. You should not use the form element in your code, nor should you use the button's type attribute to "submit". When you click the submit button, the browser post your form data to the server the normal way. No one on the server, however welcomes the posted form data. But alas, your button's click event handler is also called, right after the "post back": onclick="@(async () => await AddCliente())", which use Ajax call to your server, using, this time, HttpClient. You must understand, Blazor is a UI framework to create SPA applications, like Angular. No submit or post back the normal way. Your SPA communicates with the Server using HttpClient. HttpClient employ Ajax calls for this purpose. Truth is HttpClient uses the JavaScript Fetch API (Not XmlHttpRequest).

Note: As far as I know, internal Blazor code is supposed to cancel the submission of the form, calling event.preventDefault() in the JavaScript code used to perform JSInterop.

Solution: remove the form element and use a div element instead. Also, set the button's type attribute to "button"

Make your components simpler...

Hope this helps...



来源:https://stackoverflow.com/questions/54064493/problems-with-using-microsoft-jsinterop-in-blazor-applications

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!