从服务器推送websocket数据后Angularjs模型发生变化

Posted

技术标签:

【中文标题】从服务器推送websocket数据后Angularjs模型发生变化【英文标题】:Angularjs model changes after websocket data push from server 【发布时间】:2013-01-20 02:40:11 【问题描述】:

在从服务器推送 websocket 后,我​​正在尝试更改我的角度模型。每次服务器提供新数据时,如何更改 $scope.contacts 之类的值..?

我不确定是否可以使用$apply。我知道我可以访问 DOM 元素检索范围然后更改值,但应该有更好的解决方案!

我对从外部更新角度模型而不创建角度模块的解决方案非常感兴趣,因为我使用的是发出更改事件的相关数据源。有没有像 Backbone.js 那样的简单方法,你可以说:

var book = new Backbone.Model( title: 'value' );
book.set("title", "A Scandal in Bohemia");

我想要的 angularjs 是这样的:

function MyController($scope) 
    $scope.contacts = [];


datasource changed -> function () 
    MyController.set('contacts', 'value'); // change angular scope property

【问题讨论】:

是的,可以使用 $apply @Jimbo 您的回答正是我在问题中已经描述的。我正在寻找一种更简单的方法,但我认为编写自己的工厂模块是最好的解决方案。 【参考方案1】:

看看socket.io的角度服务:

angular.module('app')
  .factory('socket', ['$rootScope', function ($rootScope) 

    var socket = io.connect();

    return 
      on: function (eventName, callback) 
        socket.on(eventName, function ()   
          var args = arguments;
          $rootScope.$apply(function () 
            callback.apply(socket, args);
          );
        );
      ,
      emit: function (eventName, data, callback) 
        socket.emit(eventName, data, function () 
          var args = arguments;
          $rootScope.$apply(function () 
            if (callback) 
              callback.apply(socket, args);
            
          );
        )
      
    ;

  ]);

和使用它的控制器:

angular.module('app')
  .controller('Controller', ['$scope', 'socket', function ($scope, socket) 

    socket.emit('register')

    socket.on('register', function (data) 
        $scope.data = data;
    );

]);

【讨论】:

这是一个非常好的示例,但它不适用于我的情况,因为我正在客户端上与集合同步数据,并且这些集合会发出更改事件。我可以更改代码以使其符合您的建议,但我真正想要的是scope.contacts = db.collection('contacts').find('favorites'); 并在每次更新我的收藏时设置角度模型属性,然后调用此代码。 您在客户端使用的是哪个数据库? find() 有回调函数吗?你能显示完整的客户来源吗?【参考方案2】:

像下面那样做

 socket.onmessage = function (event) 
     scope.$apply(function()
       // modify scope values here 
     
    ;

【讨论】:

如果我错了,请纠正我,但是当我检索到我的范围时,我可以简单地通过 scope.variable = 'value' 更改值。我的问题是关于如何以一种简单的方式检索我想要更改的范围。 你创建了一个 Angular 服务来发出 websocket 请求 +1 很棒的发现@Ajaybeniwal - 我已经将您上面的代码与在您自己的 JS 中检索元素范围的能力相结合,并将其放在下面的新答案中:)【参考方案3】:

嗯,标记的答案肯定不是 OP 要求的“简单方法”。这是一个更简单的解决方案。

在您自己的 javascript 代码中任意位置检索范围:

var scope = angular.element($("#elementID")).scope();

在您的 Angular $scope 变量中更改一个值,但来自您的外部 JavaScript:

scope.$apply(function() 
    scope.yourArrayForExample.push(name: 'New, external value');
);

这是JSFiddle。

【讨论】:

以上是关于从服务器推送websocket数据后Angularjs模型发生变化的主要内容,如果未能解决你的问题,请参考以下文章

春季启动从 1.2.0 升级到 2.1.3 后,Websocket 推送通知不起作用

html5利用websocket完成的推送功能

netty websocket + 连续PERIODIC数据推送

Workerman创建WebSocket客户端和服务端推送数据

关于前后端通过websocket实现消息推送的总结

SpringBoot基于WebSocket进行推送