Почему компонент пользовательского интерфейса Blazor не обновляется после события удаления? - PullRequest
5 голосов
/ 08 апреля 2020

Почему Blazor UI не обновляется после события удаления:

Мой компонент:

<table class="table table-striped">
    <thead>
        <tr>
            <th>Id</th>
            <th>Name</th>
            <th>Example</th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var trainingTechnique in TrainingTechniques) {
        <tr>
            <td>@trainingTechnique.Id</td>
            <td>@trainingTechnique.Name</td>
            <td>@trainingTechnique.Example</td>
            <td>
                <button type="button" 
                        class="btn btn-danger" 
                        @onclick="@(async () => await DeleteTechnique(trainingTechnique.Id))">
                    Delete
                </button>

            </td>
        </tr>
        }
    </tbody>
</table>

Мой компонент код позади:

public class TrainingTechniqueViewPageBase : ComponentBase
    {
        public List<TrainingTechniqueView> TrainingTechniques { get; set; }
        [Inject] 
        public ITrainingTechniqueConsumer TrainingTechniqueConsumer { get; set; }

        protected TrainingTechniqueForm TrainingTechniqueForm { get; set; } 
        protected override async Task OnInitializedAsync()
        {
            TrainingTechniques = (await TrainingTechniqueConsumer.GetTechniques()).ToList();
        }

        public async void TrainingTechniqueForm_OnSave()
        {
            TrainingTechniques = (await TrainingTechniqueConsumer.GetTechniques()).ToList();
            StateHasChanged();
        }

        protected void AddTrainingTechnique()
        {
            TrainingTechniqueForm.Show();
        }

        protected async Task DeleteTechnique(int id)
        {
           await (TrainingTechniqueConsumer.DeleteTrainingTechnique(id));
            this.StateHasChanged();

        }
    }
}

Метод удаления:

public async Task DeleteTrainingTechnique(int id)
{
    await _httpClient.DeleteAsync($"training/trainingtechniques/{id}");
}

Ответы [ 4 ]

3 голосов
/ 10 апреля 2020

Решение 1 : Перезагрузить список TrainingTechniques из источника

private async Task Delete(int id)
{
    await TrainingTechniqueConsumer.DeleteTrainingTechnique(id);
    TrainingTechniques = (await TrainingTechniqueConsumer.GetTechniques()).ToList();
}

Решение 2 : Удалить элемент из списка:

<table class="table table-striped">
    <thead>
        <tr>
            <th>Id</th>
            <th>Name</th>
            <th>Example</th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var trainingTechnique in TrainingTechniques)
        {
            <tr>
                <td>@trainingTechnique.Id</td>
                <td>@trainingTechnique.Name</td>
                <td>@trainingTechnique.Example</td>
                <td>
                    <button type="button" class="btn btn-danger" @onclick="@(() => DeleteTechnique(trainingTechnique.Id))">Delete</button>
                </td>
            </tr>
        }
    </tbody>
</table>

И метод удаления:

private async Task Delete(int id)
{
    TrainingTechniques.RemoveAll(x => x.Id == Id);
    await TrainingTechniqueConsumer.DeleteTrainingTechnique(id);
}
2 голосов
/ 14 апреля 2020

Удалить элемент из списка, имеющий привязку к пользовательскому интерфейсу.

protected async Task DeleteTechnique(int id)
{
    await (TrainingTechniqueConsumer.DeleteTrainingTechnique(id));
    TrainingTechniques.Remove(TrainingTechniques.Single(x => x.Id == id));
}

Я думаю, что лучше передать сам элемент вместо идентификатора. Например, удаление может быть:

protected async Task DeleteTechnique(TrainingTechniqueView corpse)
{
    await (TrainingTechniqueConsumer.DeleteTrainingTechnique(corpse.Id));
    TrainingTechniques.Remove(corpse);
}
1 голос
/ 12 апреля 2020

Вы правильно удаляете элемент в бэкэнде.
Но для того, чтобы увидеть эффект, вам придется перезагрузить данные:

protected async Task DeleteTechnique(int id)
{
   await (TrainingTechniqueConsumer.DeleteTrainingTechnique(id));
   TrainingTechniques = (await TrainingTechniqueConsumer.GetTechniques()).ToList();
 //this.StateHasChanged(); -- not necessary
}

В качестве альтернативы вы можете удалить элемент из уже загружен TrainingTechniques, небольшая оптимизация, но вы рискуете получить ошибки параллелизма.

1 голос
/ 10 апреля 2020

Ниже код работает для меня -

TrainingTechnique.razor:

<table class="table table-striped">
    <thead>
        <tr>
            <th>Id</th>
            <th>Name</th>
            <th>Example</th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var trainingTechnique in TrainingTechniques)
        {
            <tr>
                <td>@trainingTechnique.Id</td>
                <td>@trainingTechnique.Name</td>
                <td>@trainingTechnique.Example</td>
                <td>
                    <button type="button" class="btn btn-danger" @onclick="@(async () => await DeleteTechnique(trainingTechnique.Id))">Delete</button>

                </td>
            </tr>
        }
    </tbody>
</table>

Компонент:

    public class TrainingTechniqueViewPageBase : ComponentBase
    {
        public List<TrainingTechniqueView> TrainingTechniques { get; set; }
        [Inject] 
        public ITrainingTechniqueConsumer TrainingTechniqueConsumer { get; set; }

        protected TrainingTechniqueForm TrainingTechniqueForm { get; set; } 
        protected override async Task OnInitializedAsync()
        {
            TrainingTechniques = await TrainingTechniqueConsumer.GetTechniques().ToListAsync();
        }

        public async void TrainingTechniqueForm_OnSave()
        {
            TrainingTechniques = await TrainingTechniqueConsumer.GetTechniques().ToListAsync();
           await InvokeAsync(() =>
            {
                StateHasChanged();
            });
        }

        protected void AddTrainingTechnique()
        {
            TrainingTechniqueForm.Show();
        }

        protected async Task DeleteTechnique(int id)
        {
           await TrainingTechniqueConsumer.DeleteTrainingTechnique(id);
           TrainingTechniques =null;
           TrainingTechniques = await TrainingTechniqueConsumer.GetTechniques().ToListAsync();
           await InvokeAsync(() =>
            {
                StateHasChanged();
            });

        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...