dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.43k stars 10.02k forks source link

Blazor component lifecycle and state management. #42758

Closed GevorDanielyan closed 2 years ago

GevorDanielyan commented 2 years ago

Hello everyone.

I have a general question related Blazor. I'm creating a program for dealers. In backend side I use gRPC, and for frontend side Blazor Server. For creating Blazor components I use Blazorise, which is great for me.

For example, I have a component, which is a Blazorise Data Grid. I created bool parameter and passed it to Data Grid as reference for Editable. This is because on another page where I use this component, I need it to be editable in one place and not editable in another. How can I do it so that on one page where I change the data, on the other non-editable page, the data appears at once?

Let's imagine that I open 2 different pages of the program in separate browsers or in separate tabs, on one page where I edit the data, it is necessary for the change to be visible on the other page at that moment, not after refreshing the page.

This is non editable grid in one page when I used data grid component.

image

And in another page this is editable

image

When I'm changing something in one page where my component's grid is editable , I need that immediately appears changes in another page where that same grid is non editable . How can I do this?

This is my component

@using Grpc.Core
@using TariffgRPCService
@using Blazorise.DataGrid
@using GrpcService.BlazorApp.Models
@using Google.Protobuf.WellKnownTypes
@inject ILogger<Tariff> _logger
@inject TariffgRPCService.TariffService.TariffServiceClient _tarifServiceClient

<h6>@tariffForDepositing</h6>
<Div Style="display: flex; justify-content: space-between; width: 31%;">
    <DataGrid TItem="TariffModel"
              Data="_tariff"
              Virtualize
              Editable="@Editable"
              EditMode="DataGridEditMode.Popup"
              RowUpdated="@OnRowUpdated"
              Hoverable
              HeaderThemeContrast="ThemeContrast.Light"
              Bordered="true"
              Style="font-size: .80em;"
              Responsive>

        <DataGridColumns>
            <DataGridCommandColumn Context="dataGridContext"
                                   NewCommandAllowed="false"
                                   EditCommandAllowed="true"
                                   DeleteCommandAllowed="false"
                                   TItem="TariffModel">
                <EditCommandTemplate>
                    <Button Color="Color.Primary" Clicked="dataGridContext.Clicked">Edit</Button>
                </EditCommandTemplate>
            </DataGridCommandColumn>
            <DataGridColumn TItem="TariffModel" Field="@nameof(TariffModel.Iso)" Caption="ISO" Sortable="false" />
            <DataGridColumn TItem="TariffModel" Field="@nameof(TariffModel.Value)" Caption="Cash In" Editable="true" Sortable="false" />
        </DataGridColumns>
    </DataGrid>
</Div>

@code {

    [Parameter]
    public bool Editable { get; set; }

    private const string tariffForDepositing = "Հետևյալ անկանխիկ արտարժույթների հաշիվներին մուտքագրման համար սահմանվում են սակագներ";

    private List<TariffModel>? _tariff;
    Empty emptyRequest = new Empty();
    [Inject] IMessageService? MessageService { get; set; }

    protected override async Task OnInitializedAsync()
    {
        _tariff = new List<TariffModel>();
        await GetTariffAsync();
        await base.OnInitializedAsync();
    }

    private async Task GetTariffAsync()
    {
        try
        {
            using (var call = _tarifServiceClient.GetTariff(emptyRequest))
            {
                await foreach (var response in call.ResponseStream.ReadAllAsync())
                {
                    var tarifResponse = new TariffModel
                        {
                            Iso = response.SYM,
                            Value = response.TIV
                        };
                    _tariff!.Add(tarifResponse);
                }
            }
        }
        catch (RpcException ex) when (ex.StatusCode == StatusCode.Internal)
        {
            _logger.LogError(ex.Message);
            throw;
        }
    }

    private async Task OnRowUpdated(SavedRowItem<TariffModel, Dictionary<string, object>> e)
    {
        var tariff = e.Item;
        UpdateTariffRequest request = new UpdateTariffRequest
            {
                Iso = tariff.Iso,
                Value = tariff.Value!.Value
            };

        var response = await _tarifServiceClient.UpdateTariffAsync(request);
        _logger.LogInformation("Updated tariff");

        if (response.Message is null)
        {
            await MessageService!.Error("Cannot update Tariff");
        }

        await MessageService!.Info("Updated successfully");
    }
}

which I use in different pages. So how can I solve my issue? Firstly I use it in page one which grid is non editable, just showing data, like this Page1 <Tariff Editable = "false"></Tariff>

and in second page where you can edit that data grid

Page2 <Tariff Editable = "true"></Tariff>

Thanks in advance

javiercn commented 2 years ago

Let's imagine that I open 2 different pages of the program in separate browsers or in separate tabs, on one page where I edit the data, it is necessary for the change to be visible on the other page at that moment, not after refreshing the page.

Thanks for contacting us.

Blazor doesn't offer any functionality to achieve this scenario out of the box. You will need to have code on one of the tabs you are using to display data to poll regularly for updates or use something like the broadcast channel API (see here) via JS interop to notify other tabs that additional data is available.

ghost commented 2 years ago

This issue has been resolved and has not had any activity for 1 day. It will be closed for housekeeping purposes.

See our Issue Management Policies for more information.