4

I'm currently looking for a solution to my issue: In our ASP.NET MVC application there are pages that are used for realtime data visualization of industrial devices. When the page gets loaded, a loading icon is shown while I fetch the viewmodel data with the current values for all the datapoints from a database. That works quite well, but it is static, by which I mean that the values don't change on the page after it finished loading. The web application itself uses a TCP listener that receives messages with values from the devices. These messages (which basically consist of a device id, a datapoint id and the value) don't arrive in fixed intervals but event-based, e.g. when a temperature value changes 0.5 K up or down.

On my page I have some graphical widgets like gauges and many other elements that correctly show the values from the initial data that gets loaded on the page load. They are bound to the Knockout viewmodel.

The problem is this: whenever a new value arrives on the server, I want to show it on the page without the need for a reload. I definitely don't want to re-transmit the whole viewmodel with some hundred datapoints on every message that arrives on the server (appr. 1 to 15 per second). In order to achieve that, I implemented the SignalR framework, which really works great. With that mechanism I now receive the new value in the client window (that means, I receive it in Javascript and now have a value object like described below).

What I need now is this: as every viewmodel gets built dynamically, they are all different. The object and properties tree is not the same for two devices, so each of them can have varying levels of subobjects. The only thing that is the same is the structure of the object that actually holds the value for each datapoint: it always consists of the aforementioned device id, the datapoint id and the value.

I need a way to update the double-type value inside the value object within the viewmodel whose device id and datapoint id match the newly arrived value message (that also consists of these two address-like ID's and the value).

I hope I got the idea across. Is there a way to do this? What would be the best practice for such a mechanism? I recently switched to Knockout-MVC (kMVC nuget package), but I'd also go back to "pure" Knockout.js and some additional scripting if that helps.

Thanks for your help and recommendations!

csharpwinphonexaml
  • 3,659
  • 10
  • 32
  • 63
Rob
  • 11,492
  • 14
  • 59
  • 94
  • It I understand you problem correctly, I think you should look at computed Observables. That way you can account for new values being received. You need to compute your new values and then delete the data, or you will run out of memory eventually. http://knockoutjs.com/documentation/computedObservables.html – Barry West Apr 22 '14 at 20:30
  • 4
    Some sample code would be helpful – AD.Net Apr 22 '14 at 20:38
  • You properly could make an array with key/values and bind your data to a function taking the key and returning the value. when you update the data point you would have to update the key/value in the array. – Michael Skarum Apr 22 '14 at 20:59
  • Something like this: http://jsfiddle.net/RrBB7/2/ – Michael Skarum Apr 22 '14 at 21:16
  • 1
    Have you looked at the knockout-mapping plugin? http://knockoutjs.com/documentation/plugins-mapping.html – cwohlman May 01 '14 at 00:38
  • Also consider using a client-side data store such as Breeze.js - http://www.breezejs.com/ that handles this for you. – PW Kad May 06 '14 at 16:40

2 Answers2

1

http://nthdegree.azurewebsites.net/mvvm-2/

Here is an article speaking to the Knockout mapping plugin

The general idea is that you should have your view model code which loads your model.

You would bind up your view model which will have a property you load from the server with an ajax call (see bottom of article).

You then just update the model with the result with

ko.mapping.fromJS(newData, mapping, modelToUpdate)


var mapping = {}; //define your mapping (see documentation or blog post)

function ViewModel(){
    var self = this; 

    self.model = ko.mapping.fromJS({}, mapping);
    self.hub = $.connection.myHub(); 
    self.hub.client.updateModel = function(data){
       ko.mapping.fromJS(data, mapping, self.model);
    };
    self.hub.start().done(function(){
       //you could either make a call or have the "OnConnected" method trigger an 'updateModel'
    });
}
Matthew
  • 411
  • 4
  • 14
1

ViewModel properties when linked to a DOM element allows editing which is actually updating the data in the KO observable array. Is it possible for you to change the "graphical widget"'s value (assuming that it is using some property to maintain height and width) using the IDs which you said are consistent?

I have not tested; the other option is to use KO foreach loop and update the related value.

user3104116
  • 153
  • 1
  • 11