来自angularjs工厂的返回值

时间:2017-02-01 11:35:36

标签: angularjs websocket

我尝试设置此示例https://github.com/AngularClass/angular-websocket#usage 这是我的代码

App.factory('MyData', function($websocket, $q) {
var dataStream = $websocket('wss://url');
var collection = [];

dataStream.onMessage(function(message) {
    var result = JSON.parse(message.data);
    console.log(result);
    collection = result;
});

var methods = {
    collection: collection,
    get: function() {
        dataStream.send(JSON.stringify({
            api: "volume",
            date: "2017-02-01",
            interval: 600
        }));
    }
};

return methods; });

在我的控制器中,我写道:

$interval(function () {
    console.log(MyData.collection);
}, 1000);

问题是我没有收到任何值,但是在消息到达时我看到了控制台日志,所以websocket本身显然是活着的。如果我更改collection.push(result)(如示例中所示),我会收到不断增长的数组。但是,我只需要最后一个值。为什么collection = result错了?

1 个答案:

答案 0 :(得分:0)

var collection = [];实例化一个新数组,其引用存储在变量collection中。然后,此引用分配给methods.collection,因此MyData.collection。但是,使用JSON.parse实例化新数组。 collection = result;使用新数组的引用覆盖原始引用。但MyData.collection仍保留对原始数组的引用。

因此,有两种方法可以解决问题:

  1. 不要覆盖对原始数组的引用。 push很好,但在此之前,您需要清除数组才能显示最后一个值。
  2. collection.splice(0, collection.length);
    collection.push(result);
    

    但是,这将是数组中的数组。您可能需要单独推送值(Array.concat也会创建一个新数组):

    collection.splice(0, collection.length);
    result.forEach(function(value) {
      collection.push(value);
    });
    
    1. 将新数组的引用直接分配给methods.collection。在这种情况下,不需要额外的变量collection
    2. App.factory('MyData', function($websocket, $q) {
        var dataStream = $websocket('wss://url');
      
        var methods = {
          collection: [],
          get: function() {
              dataStream.send(JSON.stringify({
                  api: "volume",
                  date: "2017-02-01",
                  interval: 600
              }));
          }
        };
      
        dataStream.onMessage(function(message) {
          var result = JSON.parse(message.data);
          console.log(result);
          methods.collection = result;
        });
      
        return methods;
      });