更新UI与SignalR和淘汰赛时手动更新DB [英] Update UI with SignalR and Knockout when manually updating DB

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

问题描述

我有一个搜索周围所以对于这一点,但整个事情显然没来。我有工作的仪表板,以及它们的状态,全天不断变化,我试图拼凑概念的applcation一些证据,并手动在数据库中运行更新命令触发更新。这是我已经设置了,但是当我执行更新,我没有看到在UI的任何变化,你可以看到我已经错了吗?

集线器:

 公共类DashboardHub:集线器
{
    私人只读存储库_repository;    公共DashboardHub()
    {
        _repository =新的存储库();
    }    公共无效GetJobs()
     {
         VAR工作= _repository.GetJobs();        Clients.All.allJobsRetrieved(工种);
     }
}

淘汰赛视图模型

  $(函数(){
    $(函数(){
        功能jobViewModel(ID,姓名,isPaused得到,currentStatus,COB,所有者){
            this.hub = $ .connection.dashboardHub;            //工作变量,从PARAMS初始化
            this.Id = ID;
            this.Name = ko.observable(名);
            this.IsPaused = ko.observable(isPaused得到);
            this.CurrentStatus = ko.observable(currentStatus);
            this.Cob = ko.observable(COB);
        }        功能dashboardViewModel(){
            this.hub = $ .connection.dashboardHub;            //收集工作
            this.jobs = ko.observableArray([]);            //参考收集工作
            VAR工作= this.jobs;            //加载作业,调用服务器端方法枢纽
            this.init =功能(){
                this.hub.server.getJobs();
            };            //从服务器端枢纽回调将作业发送到客户端
            this.hub.client.allJobsRetrieved =功能(allJobs){
                VAR mappedJobs = $ .MAP(allJobs,功能(作业){
                    返回新jobViewModel(job.Id,job.Name,job.IsPaused,job.CurrentStatus,job.CoB,个体经营);
                });                作业(mappedJobs);
            };            //从服务器端枢纽回调发送错误信息到客户端
            this.hub.client.raiseError =功能(错误){
                $(#错误)文本(错误)。
            };
        }        //建立视图模型
        VAR视图模型=新dashboardViewModel();
        ko.applyBindings(视图模型);        //调用初始化
        $ .connection.hub.start(函数(){
            viewModel.init();
        });
    });
});


解决方案

更新我提取我的code,并把它在Github /的NuGet
https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy

要安装到MVC proejct

 安装封装SignalR.EventAggregatorProxy

旧的答案

我只是做了该为我的客户的项目之一,我用这个EventAggregator我名为FreePIE一个开源项目创建

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

快速阅读了关于EventAggregators
http://$c$cbetter.com/jeremymiller/2009/07/22/braindump-on-the-event-aggregator-pattern/

信息库code看起来像这样

 公共类FooRepository:库<富>
{
   私人只读IEventAggregator eventAggregator;   公共FooRepository(IEventAggregator eventAggregator){
      this.eventAggregator = eventAggregator;
   }   公共无效SaveFoo(富富)
   {
      //保存富
      this.eventAggregator.Publish(新FooSavedEvent(富));
   }
}

在事件聚合集线器(SignalR)我

 公共类ClientEventAggregator:集线器
{
   公共ClientEventAggregator(IEventAggregatorClientProxy代理)
   {
      //这只是一个注射单代理为第一轮毂连接方式
   }
}

代理处理由EventAggregator解雇所有后端事件。

IHandle<对象> 可改为例如一个基类 IHandle< ForwardToClientEvent> 这样你就可以选择后端事件转发到客户端

 公共类EventAggregatorClientProxy:IEventAggregatorClientProxy,IHandle<对象>
{
   公共EventAggregatorClientProxy(IEventAggregator eventAggregator)
   {
      eventAggregator.Subscribe(本);
   }   公共无效句柄(对象事件)
   {
      VAR背景= GlobalHost.ConnectionManager.GetHubContext< ClientEventAggregator>();
      context.Clients.All.event(新{类型= event.GetType()的名称,事件=事件。});
   }
}

在我的例子中的所有事件将被发送到所有客户端,你可以实施规则的改变和context.Clients.All

在客户端我重新使用这个小事件aggreagator,我写了另一个发布事件,因此质疑的http:/ /jsfiddle.net/wJtun/4/

  MyApp.MasterViewModel =功能(){
    VAR的事件= $ .connection.clientEventAggregator;    event.client.event = this.onEvent.bind(本);    $ .connection.hub.start()()完成。
    });
};
MyApp.MasterViewModel.prototype = {
   的onEvent:函数(事件){
      VAR类型= MyApp.Events [event.type]
      MyApp.eventAggregator.publish(新型(event.event));
   }
};

VAR类型= MyApp.Events [event.type]

请注意,这需要您已经定义了一个JavaScript类
MyApp.Events.FooSavedEvent。或者说,你动态地创建一个包含可发布所有事件的JS(你可以看一下对SignalR code如何创建集线器代理)。

声明:所有code以上直接在SO编辑了内存是书面的,也可以包含错误

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?

Hub:

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

解决方案

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

To install to a MVC proejct

Install-Package SignalR.EventAggregatorProxy

Old answer

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

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

The repository code looks look like this

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));
   }
}

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
   }
}

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 });
   }
}

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

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]

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).

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

这篇关于更新UI与SignalR和淘汰赛时手动更新DB的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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