1

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

中心:

public class DashboardHub : Hub
{
    private readonly Repository _repository;

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

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

        Clients.All.allJobsRetrieved(jobs);
     }
}

淘汰赛视图模型

$(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();
        });
    });
});
4

2 回答 2

6

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

安装到 MVC 项目

Install-Package SignalR.EventAggregatorProxy

旧答案

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

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

快速阅读 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)我做

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<object>可以通过IHandle<ForwardToClientEvent>这种方式更改为例如基类,您可以选择将哪些后端事件转发给客户端

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

在客户端上,我使用我为另一个 SO 问题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 代码它们如何创建 Hub 代理)。

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

于 2013-05-09T20:52:57.390 回答
3

这是有道理的,应用程序不知道数据库中的数据已更改。您需要一些触发器/通知来通知应用程序查询数据库。

理想情况下,您不会手动/直接更新数据库。您将使用一些服务来查询使用数据、处理/验证数据、将数据推送到数据库。向其他系统发送数据已导入的通知。(很多不同的是这样做。)

在这种情况下,您的网站可能会收到通知数据已导入并启动仪表板查询。

于 2013-05-09T11:03:00.047 回答