Можно ли "внедрить" обновления в Knockout ViewModel?
В настоящее время я ищу решение своей проблемы: в нашем приложении ASP.NET MVC есть страницы, которые используются для визуализации данных в реальном времени на промышленных устройствах. Когда страница загружается, отображается значок загрузки, пока я выбираю данные модели представления с текущими значениями для всех точек данных из базы данных. Это работает довольно хорошо, но это статично, я имею в виду, что значения не меняются на странице после ее загрузки. Само веб-приложение использует TCP-прослушиватель, который получает сообщения со значениями от устройств. Эти сообщения (которые в основном состоят из идентификатора устройства, идентификатора точки данных и значения) поступают не через фиксированные интервалы, а на основе событий, например, когда значение температуры изменяется на 0,5 K вверх или вниз.
На моей странице есть несколько графических виджетов, таких как датчики и многие другие элементы, которые правильно отображают значения из исходных данных, которые загружаются при загрузке страницы. Они связаны с моделью нокаута.
Проблема заключается в следующем: всякий раз, когда новое значение поступает на сервер, я хочу показать его на странице без необходимости перезагрузки. Я определенно не хочу повторно передавать всю модель представления с несколькими сотнями точек данных на каждое сообщение, поступающее на сервер (от 1 до 15 в секунду). Чтобы добиться этого, я реализовал инфраструктуру SignalR, которая действительно отлично работает. С помощью этого механизма я теперь получаю новое значение в окне клиента (это означает, что я получаю его в Javascript и теперь у меня есть объект значения, как описано ниже).
Теперь мне нужно следующее: поскольку каждая модель представления создается динамически, все они разные. Дерево объектов и свойств не одинаково для двух устройств, поэтому каждое из них может иметь различные уровни подобъектов. Единственное, что остается неизменным, - это структура объекта, которая на самом деле содержит значение для каждого элемента данных: он всегда состоит из вышеупомянутого идентификатора устройства, идентификатора элемента данных и значения.
Мне нужен способ обновить double
-тип значения в объекте значения внутри модели представления, идентификатор устройства и идентификатор которого совпадают с вновь поступившим сообщением о значении (которое также состоит из этих двух идентичных адресу идентификаторов и значения).
Я надеюсь, что я понял идею. Есть ли способ сделать это? Какова будет лучшая практика для такого механизма? Недавно я переключился на Knockout-MVC (пакет nuget kMVC), но я также вернусь к "чистому" Knockout.js и некоторым дополнительным сценариям, если это поможет.
Спасибо за вашу помощь и рекомендации!
2 ответа
Свойства ViewModel, связанные с элементом DOM, позволяют редактировать, что фактически обновляет данные в наблюдаемом массиве KO. Возможно ли для вас изменить значение "графического виджета" (при условии, что оно использует какое-то свойство для поддержания высоты и ширины), используя идентификаторы, которые, как вы сказали, являются согласованными?
Я не проверял; Другой вариант - использовать цикл foreach KO и обновить соответствующее значение.
http://nthdegree.azurewebsites.net/mvvm-2/
Вот статья, в которой рассказывается о плагине Knockout mapping
Общая идея заключается в том, что у вас должен быть код модели представления, который загружает вашу модель.
Вы бы связали свою модель представления, которая будет иметь свойство, которое вы загружаете с сервера, с помощью вызова ajax (см. Нижнюю часть статьи).
Затем вы просто обновляете модель с результатом
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'
});
}