手动更新数据库时使用 SignalR 和 Knockout 更新 UI [英] Update UI with SignalR and Knockout when manually updating DB

查看:20
本文介绍了手动更新数据库时使用 SignalR 和 Knockout 更新 UI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为此在 SO 周围进行了搜索,但没有发现任何明显的问题.我有一个作业仪表板,它们的状态全天都在不断变化,我正在尝试将一些概念应用程序放在一起,并通过在数据库中运行更新命令来手动触发更新.这是我设置的,但是当我执行更新时,我没有看到 UI 中有任何变化,你能看到我哪里出错了吗?

I have had a search around SO for this, but didn't come across anything obvious. I have a dashboard of jobs, and their status continually changes throughout the day and I'm trying to put together some proof of concept applcation and manually trigger the updates by running update commands in the database. This is what I have set up, but when I execute an update, I don't see any changes in the UI, can you see where I have gone wrong?

中心:

public class DashboardHub : Hub
{
    private readonly Repository _repository;

    public DashboardHub()
    {
        _repository= new Repository();
    }

    public void GetJobs()
     {
         var jobs =  _repository.GetJobs();

        Clients.All.allJobsRetrieved(jobs);
     }
}

Knockout 视图模型

Knockout View Model

$(function () {
    $(function () {
        function jobViewModel(id, name, isPaused, currentStatus, cob, owner) {
            this.hub = $.connection.dashboardHub;

            //job variables, initialised from params
            this.Id = id;
            this.Name = ko.observable(name);
            this.IsPaused = ko.observable(isPaused);
            this.CurrentStatus = ko.observable(currentStatus);
            this.Cob = ko.observable(cob);
        }

        function dashboardViewModel() {
            this.hub = $.connection.dashboardHub;

            //jobs collection
            this.jobs = ko.observableArray([]);

            //reference to jobs collection
            var jobs = this.jobs;

            //load jobs, calling server side hub method
            this.init = function () {
                this.hub.server.getJobs();
            };

            //callback from server side hub sending jobs to client
            this.hub.client.allJobsRetrieved = function (allJobs) {
                var mappedJobs = $.map(allJobs, function (job) {
                    return new jobViewModel(job.Id, job.Name, job.IsPaused, job.CurrentStatus, job.CoB, self);
                });

                jobs(mappedJobs);
            };

            //callback from server side hub sending error messages to client
            this.hub.client.raiseError = function (error) {
                $("#error").text(error);
            };
        }

        //set up the viewmodel
        var viewModel = new dashboardViewModel();
        ko.applyBindings(viewModel);

        //call to initialise
        $.connection.hub.start(function () {
            viewModel.init();
        });
    });
});

推荐答案

更新 我已经提取了我的代码并将其放在 Github/nuget 上https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy

Update I've extracted my code and put it on Github/nuget https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy

安装到 MVC 项目

Install-Package SignalR.EventAggregatorProxy

旧答案

我刚刚为我的一个客户项目做了这个,我使用了我为一个名为 FreePIE 的开源项目创建的 EventAggregator

I just did this for one of my customers project, I used this EventAggregator that I created for a open source project called FreePIE

https://github.com/AndersMalmgren/FreePIE/tree/master/FreePIE.Core/Common/Events

快速阅读 EventAggregatorshttp://codebetter.com/jeremymiller/2009/07/22/braindump-on-the-event-aggregator-pattern/

Quick read up on EventAggregators http://codebetter.com/jeremymiller/2009/07/22/braindump-on-the-event-aggregator-pattern/

存储库代码如下所示

public class FooRepository : Repository<Foo> 
{
   private readonly IEventAggregator eventAggregator;

   public FooRepository(IEventAggregator eventAggregator) {
      this.eventAggregator = eventAggregator;
   }

   public void SaveFoo(Foo foo)
   {
      //save foo
      this.eventAggregator.Publish(new FooSavedEvent(foo));
   }
}

在事件聚合中心 (SignalR) 中

In the event aggregator hub (SignalR) i do

public class ClientEventAggregator : Hub
{
   public ClientEventAggregator (IEventAggregatorClientProxy proxy)
   {
      //This is just a way of injecting the singleton proxy for the first hub connection
   }
}

处理由 EventAggregator 触发的所有后端事件的代理.
IHandle 可以更改为例如基类 IHandle 这样您就可以选择将哪些后端事件转发到客户端

Proxy that handles all backend events fired by the EventAggregator.
IHandle<object> can be changed to for example a base class IHandle<ForwardToClientEvent> this way you can choose which backend events to forward to client

public class EventAggregatorClientProxy : IEventAggregatorClientProxy, IHandle<object>
{
   public EventAggregatorClientProxy(IEventAggregator eventAggregator) 
   {
      eventAggregator.Subscribe(this);
   }

   public void Handle(object event)
   {
      var context = GlobalHost.ConnectionManager.GetHubContext<ClientEventAggregator>();
      context.Clients.All.event(new { Type = event.GetType().Name, Event = event });
   }
}

在我的示例中,所有事件都将发送到所有客户端,您可以为此实施规则并更改 context.Clients.All

In my example all events will be sent to all clients you could implement rules for that and change context.Clients.All

在客户端上,我使用我为另一个 SO 问题编写的这个小事件聚合器重新发布事件 http://jsfiddle.net/wJtun/4/

On the client I re publish the event using this little event aggreagator that i wrote for another SO question http://jsfiddle.net/wJtun/4/

MyApp.MasterViewModel = function() {
    var event = $.connection.clientEventAggregator;

    event.client.event = this.onEvent.bind(this);

    $.connection.hub.start().done();
    });
};
MyApp.MasterViewModel.prototype = {
   onEvent: function(event) {
      var type = MyApp.Events[event.type];          
      MyApp.eventAggregator.publish(new type(event.event));
   }
};

var type = MyApp.Events[event.type]

请注意,这需要您定义一个 javascript 类MyApp.Events.FooSavedEvent.或者您动态创建一个包含所有可以发布的事件的 JS(您可以查看 SignalR 代码如何创建集线器代理).

Note that this requires that you have defined a javascript class MyApp.Events.FooSavedEvent. Or that you dynamically create a JS that contains all Events that can be published (You can look at the SignalR code how they create the Hub proxy).

免责声明:以上所有代码都是在内存不足的SO编辑器中直接编写的,可能存在错误

Disclaimer: All code above was written directly in the SO editor out of memory, it can contain errors

这篇关于手动更新数据库时使用 SignalR 和 Knockout 更新 UI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆