在html5 websocket中的viewModel knockoutjs中设置数据

时间:2015-08-07 20:27:54

标签: html5 knockout.js websocket requirejs

我正在尝试创建从HTML5 Websocket获取数据的knockout.js组件。 Websocket代码在单独的脚本中,例如util.js.我能够连接并从套接字获取数据,但不知道在组件的ViewModel中如何正确设置相应的属性。

Websocket - util.js:

     var options = {
    server: '127.0.0.1',
    port: '12345'
};

var socket, loadedFlag;
var timeout = 2000;
var clearTimer = -1;
var data = {};

function handleErrors(sError, sURL, iLine)
{
    return true;
};
function getSocketState()
{
    return (socket != null) ? socket.readyState : 0;
}

function onMessage(e)
{
    data=$.parseJSON(e.data);

 // ???? Is it possible to have here something like
 // ???? viewModel.getDataWS1(data);
}

function onError()
{
    clearInterval(clearTimer);
    socket.onclose = function () {
        loadedFlag = false;
    };
    clearTimer = setInterval("connectWebSocket()", timeout);
}

function onClose()
{
    loadedFlag = false;
    clearInterval(clearTimer);
    clearTimer = setInterval("connectWebSocket()", timeout);
}

function onOpen()
{
    clearInterval(clearTimer);
    console.log("open" + getSocketState());
}

function connectWebSocket()
{

    if ("WebSocket" in window)
    {
        if (getSocketState() === 1)
        {
            socket.onopen = onOpen;
            clearInterval(clearTimer);
            console.log(getSocketState());
        }
        else
        {
            try
            {
                host = "ws://" + options.server + ":" + options.port;
                socket = new WebSocket(host);
                socket.onopen = onOpen;
                socket.onmessage = function (e) {
                    onMessage(e);
                };
                socket.onerror = onError;
                socket.onclose = onClose;
            }
            catch (exeption)
            {
                console.log(exeption);
            }
        }
    }
}

组件(productDisplay.js) - 创建以便可以在多个页面上使用:

define([
    'jquery',
    'app/models/productDisplayModel',
    'knockout',
    'mapping',
    'socket'
],
        function ($, model, ko, mapping) {
            ko.components.register('product', {
                viewModel: {require: 'app/models/productModel'},
                template: {require: 'text!app/views/product.html'}
            });

        });

Product ViewModel(productModel.js) - 我很难将viewModel属性设置为来自websocket的数据:

var viewModel = {};

define(['knockout', 'mapping', 'jquery'], function (ko, mapping, $) {

    function Product(name, rating) {
        this.name = name;
        this.userRating = ko.observable(rating || null);
    }

    function MyViewModel() {
        this.products = ko.observableArray(); // Start empty
    }

    MyViewModel.prototype.getDataWS1 = function () {

     //Websocket has not connected and returned data yet, so data object is empty
     // ???? Is there anyway I can add something like promise so that the value is set once socket is connected? 
        this.products(data);
    };

// apply binding on page load
    $(document).ready(function () {
        connectToServer1();
        viewModel = new MyViewModel();

        ko.applyBindings(viewModel);
        viewModel.getDataWS1();
    });

});

感谢您的任何想法。

1 个答案:

答案 0 :(得分:1)

您可以按以下方式收到消息时更新observable:

<强> util.js中

function onMessage(e) {
    var productData = $.parseJSON(e.data);
    viewModel.addNewProduct(productData);
}

<强> productModel.js

function Product(name, rating) {
    this.name = name;
    this.userRating = ko.observable(rating || null);
}

function MyViewModel() {
    this.products = ko.observableArray(); // Start empty
}

MyViewModel.prototype.addNewProduct(product) {
  var newProduct = new Product(product.name, product.rating);
  this.products.push(newProduct);
}

基本上这个想法是当你得到一条消息(在onMessage函数中)时,你将解析数据并调用viewmodel中的一个函数,将消息数据添加到viewmodel属性(observables,observableArrays等)