首页 > 解决方案 > 如果在我的 ASP.NET Core 5 Web 应用程序中通过 ajax 提交数据,KendoUI SignalR 网格不会更新

问题描述

我有一个使用 SignalR 的 KendoUI 网格。虽然如果您更新数据inline或网格本身可以正常incell工作,但如果我以使用 ajax 将其发布到我的控制器的表单中更新数据,则它不起作用。

我的理解是,如果我将集线器注入控制器然后调用(无论我需要什么,创建、更新或销毁):

await _fixtureHub.Clients.All.SendAsync("update", model);

或者

await _fixtureHub.Clients.All.SendAsync("update", model);

它会告诉客户端数据已被更改/创建,并且网格将更新以反映该更改。然而这并没有发生,我想知道我做错了什么或错过了什么。

首先,这是我的 signalR 绑定网格。

$('#fixture_grid').kendoGrid({
    dataSource: {            
        schema: {
            model: {
                id: "Id",
                fields: {
                    Created_Date: {
                        type: "date"
                    },
                    Commencement_Date: {
                        type: "date"
                    } 
                }
            }
        },
        type: "signalr",
        autoSync: true,            
        transport: {
            signalr: {
                promise: fixture_hub_start,
                hub: fixture_hub,
                server: {
                    read: "read",
                    update: "update",
                    create: "create",
                    destroy: "destroy"
                },
                client: {
                    read: "read",
                    update: "update",
                    create: "create",
                    destroy: "destroy"
                }
            }
        }
    },
    autoBind: true,
    sortable: true,
    editable: false,
    scrollable: true,
    columns: [
        {
            field: "Created_Date",
            title: "Created",
            format: "{0:dd/MM/yyyy}"                
        },
        {
            field: "Commencement_Date",
            title: "Commencement",
            format: "{0:dd/MM/yyyy}"                
        },
        {
            field: "Charterer",
            template: "#if(Charterer !=null){# #=Charterer_Name# #} else { #--# }#"
        },
        {
            field: "Region",
            template: "#if(Region !=null){# #=Region_Name# #} else { #--# }#"
        }
    ]
});

这是该网格的相对中心:

var fixture_url = "/fixtureHub";

var fixture_hub = new signalR.HubConnectionBuilder().withUrl(fixture_url, {
    transport: signalR.HttpTransportType.LongPolling
}).build();

var fixture_hub_start = fixture_hub.start({
    json: true
});

这是带有表单集成的 KendoUI 向导,我用它来更新网格,这个表单可以处理创建或更新数据,这是通过检查传入的 Id 来实现的。其中0等于新的并且>0是现有的。

function wizard_fixture() {
    let wizard_name = "#wizard-fixture";

    //Load Wizard
    $(wizard_name).kendoWizard({
        pager: true,
        loadOnDemand: true,
        reloadOnSelect: false,
        contentPosition: "right",
        validateForms: true,
        deferred: true,
        actionBar: true,
        stepper: {
            indicator: true,
            label: true,
            linear: true
        },
        steps: [
            {
                title: "Step 01",
                buttons: [                                  
                {
                    name: "custom",
                    text: "Save & Continue",                      
                    click: function () {
                        let wizard = $(wizard_name).data("kendoWizard");
                        var validatable = $(wizard_name).kendoValidator().data("kendoValidator");
                        if (validatable.validate()) {
                            $.ajax({
                                type: "POST",
                                traditional: true,
                                url: "/Home/Process_Fixture",
                                data: $(wizard_name).serialize(),
                                success: function (result) {
                                   ...do stuff                                        
                                },
                                error: function (xhr, status, error) {
                                    console.log("error")
                                }
                            });
                        }                            
                    }
                }
            ],
                form: {
                    formData: {
                        Id: fixtureviewmodel.Id,
                        Created_User: fixtureviewmodel.Created_User,
                        Created_Date: fixtureviewmodel.Created_Date,
                        Connected: fixtureviewmodel.Connected
                    },                   
                    items: [
                    {
                        field: "Fixture_Id",
                        label: "Id",
                        editor: "<input type='text' name='Id' id='Fixture_Id' /> "
                    },
                    {
                        field: "Created_User",
                        label: "Created user",
                        editor: "<input type='text' name='Created_User' id='Created_User_Fixture' />"

                    },
                    {
                        field: "Created_Date",
                        id: 'Created_Date_Fixture',
                        label: "Created date",
                        editor: "DatePicker",            
                        
                    }
               ]
            }
        },
        
    ],

});

我已经缩短了这个以演示自定义按钮和发生在Process_Fixture. 这是我的控制器,它处理:

public async Task<JsonResult> Process_Fixture(Fixture model)
    {
        if (model.Id == 0)
        {
            if (ModelState.IsValid)
            {
              
                var fixture = await _fixture.CreateAsync(model);
                Update connected clients
                await _fixtureHub.Clients.All.SendAsync("create", model);
                return Json(new { success = true, data = fixture.Id, operation = "create" });                    
            }
            return Json(new { success = false });
        }
        else
        {               
            var fixture = await _fixture.UpdateAsync(model);
            await _fixtureHub.Clients.All.SendAsync("update", model);
            return Json(new { success = true, data = fixture.Id, operation = "update" });
        }
    }

正如你所看到的,我已经注入了我的集线器,并且我已经向它调用了“创建”消息,我相信这会迫使网格更新任何已更改或创建的内容。

这是集线器本身:

public class FixtureHub : DynamicHub
{
    private readonly IRepository<Fixture> _fixtures;
    private readonly IRepository<ViewGridFixtures> _viewFixtures;

    public FixtureHub(IRepository<Fixture> fixtures, IRepository<ViewGridFixtures> viewFixtures)
    {
        _fixtures = fixtures;
        _viewFixtures = viewFixtures;
    }
    public override Task OnConnectedAsync()
    {
        Groups.AddToGroupAsync(Context.ConnectionId, GetGroupName());
        return base.OnConnectedAsync();
    }
    public override Task OnDisconnectedAsync(Exception e)
    {
        Groups.RemoveFromGroupAsync(Context.ConnectionId, GetGroupName());
        return base.OnDisconnectedAsync(e);
    }

    public class ReadRequestData
    {
        public int ViewId { get; set; }
    }
    public IQueryable<ViewGridFixtures> Read()
    {
        IQueryable<ViewGridFixtures> data = _viewFixtures.GetAll();
        return data;
    }

    public string GetGroupName()
    {
        return GetRemoteIpAddress();
    }
    public string GetRemoteIpAddress()
    {
        return Context.GetHttpContext()?.Connection.RemoteIpAddress.ToString();
    }
}

我需要一些帮助来了解如何告诉集线器更新/创建/销毁已被调用并且它需要做一些事情。目前,我觉得注入集线器然后调用clients.all.async它不是正确的方法。使用 ajax 似乎忽略了它,我想知道这两种技术是否相互对抗。

标签: asp.net-corekendo-uisignalr

解决方案


推荐阅读