Update SyncFusion Grid after backend data source has changed

3.5k views Asked by At

I have a SyncFusion data grid tied to a backend SQL database. My crud actions are called through custom buttons that call a dialog box.

This works nicely except that the grid is not updated with the backend data after an add/edit/delete. I have tired refreshing the grid but that doesn't seem to work.

What do I need to do?

MyTemplates.razor

@page "/My_Templates"
@using WireDesk.Models
@inject IWireDeskService WireDeskService


<ReusableDialog @ref="dialog"></ReusableDialog>

<SfGrid @ref="Grid" DataSource="@Templates" TValue="Template" AllowSorting="true" Toolbar="ToolbarItems">
    <GridEvents OnToolbarClick="OnClicked" TValue="Template"></GridEvents>
    <GridColumns>
        <GridColumn Field=@nameof(Template.Owner) HeaderText="Owner" ValidationRules="@(new ValidationRules { Required = true })" Width="120"></GridColumn>
        <GridColumn Field=@nameof(Template.Users) HeaderText="Users" TextAlign="TextAlign.Left" Width="130"></GridColumn>
        <GridColumn Field=@nameof(Template.Description) HeaderText="Description" TextAlign="TextAlign.Left" Width="130"></GridColumn>
        <GridColumn Field=@nameof(Template.FundType) HeaderText="Fund Type" TextAlign="TextAlign.Left" Width="120"></GridColumn>
    </GridColumns>
</SfGrid>

@code{

    //Instantiate objects
    SfGrid<Template> Grid { get; set; }
    ReusableDialog dialog;

    //Instantiate toolbar and toolbar items
    private List<Object> ToolbarItems = new List<Object>()
{
    new ItemModel() { Text = "Create New Template", TooltipText = "Add", PrefixIcon = "e-icons e-update", Id = "Add", },
    new ItemModel() { Text = "Edit Template", TooltipText = "Edit", PrefixIcon = "e-icons e-update", Id = "Edit"}
};

    //Instatiate records
    public IEnumerable<Template> Templates { get; set; }

    //Instantiate Records
    protected override void OnInitialized()
    {
        Templates = WireDeskService.GetTemplates();
    }

    //Handle toolbar clicks
    public async Task OnClicked(Syncfusion.Blazor.Navigations.ClickEventArgs Args)
    {
        //Create Record
        if (Args.Item.Id == "Add")
        {
            Args.Cancel = true; //Prevent the default action
            dialog.Title = "This is the Add Title";
            dialog.Text = "This is the add text";
            dialog.template = new Template();
            dialog.OpenDialog();
            WireDeskService.InsertTemplate(dialog.template);
            //Grid.CallStateHasChanged();                            Doesn't Work
            //Templates = WireDeskService.GetTemplates();            Doesn't Work
        }

        //Edit Records
        if (Args.Item.Id == "Edit")
        {
            Args.Cancel = true; //Prevent the default action
            var selected = await Grid.GetSelectedRecordsAsync();
            if (selected.Count > 0)
            {
                //Call Dialog Box Here
                dialog.Title = "This is the Edited Title";
                dialog.Text = "This is the edited text";
                dialog.template = selected[0];
                dialog.OpenDialog();
                WireDeskService.UpdateTemplate(dialog.template.TemplateId, dialog.template);
                Grid.CallStateHasChanged();
            }
        }
    }
}

<style>

    .e-altrow {
        background-color: rgb(182 201 244);
    }
</style>

WireDeskService.cs

using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;

namespace WireDesk.Models
{
    public class WireDeskService : IWireDeskService

    {

        private WireDeskContext _context;
        public WireDeskService(WireDeskContext context)
        {
            _context = context;
        }

        public void DeleteTemplate(long templateId)
        {
            try
            {
                Template ord = _context.Templates.Find(templateId);
                _context.Templates.Remove(ord);
                _context.SaveChanges();
            }
            catch
            {
                throw;
            }
        }

        public IEnumerable<Template> GetTemplates()
        {
            try
            {
                return _context.Templates.ToList();
            }
            catch
            {
                throw;
            }
        }
        public void InsertTemplate(Template template)
        {
            try
            {
                _context.Templates.Add(template);
                _context.SaveChanges();
            }
            catch
            {
                throw;
            }
        }
        public Template SingleTemplate(long id)
        {
            throw new NotImplementedException();
        }
        public void UpdateTemplate(long templateId, Template template) {

            try
            {
                var local = _context.Set<Template>().Local.FirstOrDefault(entry => entry.TemplateId.Equals(template.TemplateId));
                // check if local is not null
                if (local != null)
                {
                    // detach
                    _context.Entry(local).State = EntityState.Detached;
                }
                _context.Entry(template).State = EntityState.Modified;
                _context.SaveChanges();
            }
            catch
            {
                throw;
            }
        }
        void IWireDeskService.SingleTemplate(long templateId)
        {
            throw new NotImplementedException();
        }
    }
}
1

There are 1 answers

0
rahul kishore On

We have analyzed your query and we understand that you want to save the changes in your database when data is bound to Grid using DataSource property. We would like to inform you that when data is bound to Grid component using DataSource property, CRUD actions needs to handled using ActionEvents (OnActionComplete and OnActionBegin).

OnActionBegin event – Will be triggered when certain action gets initiated.
OnActionComplete event – Will be triggered when certain action gets completed.

We suggest you to achieve your requirement to save the changes in database using OnActionBegin event of Grid when RequestType is Save. While saving the records, irrespective of Add or Update action. OnActionBegin event will be triggered when RequestType as Save. In that event we can update the changes into database.

Since the Add and Edit actions share the same RequestType “Save”, we can differentiate the current action using Args.Action argument. Similarly we request you fetch the updated data from your database and bind to Grid in OnActionComplete event of Grid.

Refer the below code example.


<SfGrid @ref="Grid" DataSource="@GridData" Toolbar="@(new List<string> { "Add", "Edit", "Delete", "Cancel", "Update" })" AllowFiltering="true" AllowSorting="true" AllowPaging="true"> 
    <GridEditSettings AllowAdding="true" AllowDeleting="true" AllowEditing="true"></GridEditSettings> 
    <GridEvents OnActionBegin="OnBegin" OnActionComplete="OnComplete" TValue="Order"></GridEvents> 
    <GridColumns> 
        <GridColumn Field=@nameof(Order.OrderID) HeaderText="Order ID" IsIdentity="true" IsPrimaryKey="true" TextAlign="TextAlign.Right" Width="120"></GridColumn> 
        <GridColumn Field=@nameof(Order.CustomerID) HeaderText="Customer Name" Width="150"></GridColumn> 
        <GridColumn Field=@nameof(Order.EmployeeID) HeaderText="Id" Width="150"></GridColumn> 
    </GridColumns> 
</SfGrid> 
@code{ 
    SfGrid<Order> Grid { get; set; } 
    public IEnumerable<Order> GridData { get; set;} 
    protected override void OnInitialized() 
    { 
        GridData = OrderData.GetAllOrders().ToList(); 
    } 
    public void OnComplete(ActionEventArgs<Order> Args) 
    { 
        if (Args.RequestType == Syncfusion.Blazor.Grids.Action.Save || Args.RequestType == Syncfusion.Blazor.Grids.Action.Refresh) 
        { 
            GridData = OrderData.GetAllOrders().ToList(); // fetch updated data from service and bind to grid datasource property 
        } 
    } 
    public void OnBegin(ActionEventArgs<Order> Args) 
    { 
        if (Args.RequestType == Syncfusion.Blazor.Grids.Action.Save) // update the changes in Actionbegine event 
        { 
            if (Args.Action == "Add") 
            { 
                //Args.Data contain the inserted record details 
                //insert the data into your database 
                OrderData.AddOrder(Args.Data); 
            } 
            else 
            { 
                //Args.Data contain the updated record details 
                //update the data into your database 
                OrderData.UpdateOrder(Args.Data); 
            } 
        }        else if (Args.RequestType == Syncfusion.Blazor.Grids.Action.Delete) 
        { 
            OrderData.DeleteOrder(Args.Data.OrderID); // delete the record from your database 
        } 
    } 
} 

Refer our UG documentation for your reference https://blazor.syncfusion.com/documentation/datagrid/events/#onactionbegin
https://blazor.syncfusion.com/documentation/datagrid/events/#onactioncomplete