简体   繁体   English

使用socket.io的自更新角度工厂

[英]self-updating angular factory with socket.io

I'm trying to use an angular factory to provide a shared piece of state to my controllers. 我正在尝试使用角度工厂为控制器提供共享的状态。 I also want this factory to automatically update its state by listening to a websocket. 我还希望该工厂通过侦听WebSocket自动更新其状态。 The goal is that I can write my data-fetching logic in one place, and then have the UI components update themselves automatically. 目的是我可以在一个地方编写数据获取逻辑,然后让UI组件自动更新。

The problem I'm running into is that, while the factory is updating itself, the controllers never see the updates. 我遇到的问题是,尽管工厂正在自我更新,但控制器从未看到过更新。 Here's an example of what I'm trying to do: 这是我要执行的操作的一个示例:

app.factory('Socket', function () {
    var Socket = io.connect();
    return Socket;
});

app.factory('UpdateCounter', ['Socket', function (Socket) {
    var counter = 0;
    Socket.on('update', function () {
        counter += 1;
    });
    return counter;
}]);
app.controller('MyController', ['$scope','UpdateCounter', function ($scope,UpdateCounter) {
    $scope.counter = UpdateCounter;
    ...
}]);

MyController will see UpdateCounter = 0 and never see the changes. MyController将看到UpdateCounter = 0并且永远不会看到更改。

I'm not surprised that this doesn't work, but I don't know why it doesn't work; 我对此并不奇怪并不感到惊讶,但我不知道为什么它不起作用。 nor do I know what I should be doing to get the behaviour I need. 我也不知道该怎么做才能获得所需的行为。

You need to tell Angular that an update has occurred. 您需要告诉Angular已经发生了更新。

app.factory('UpdateCounter', ['Socket', '$rootScope', function (Socket, $rootScope) {
    var counter = 0;
    Socket.on('update', function () {
        counter += 1;
        $rootScope.$apply();
    });
    return counter;
}]);

There are a few ways you can do this. 有几种方法可以做到这一点。 The first and simple is adding a watch so that the controller knows to watch the value for change. 第一个也是最简单的方法是添加一个监视,以便控制器知道监视更改的值。

app.controller('MyController', ['$scope','UpdateCounter', function ($scope,UpdateCounter) {
    $scope.$watch(function(){
        return UpdateCounter;
    }, function(newVal){
        $scope.counter = newVal;
    })
}]);

The second and probably better way is to return an object that can be referenced 第二种可能更好的方法是返回一个可以引用的对象

app.factory('UpdateCounter', ['Socket', function (Socket) {
    var counter = { count: 0 };

    Socket.on('update', function () {
        counter.count += 1;
    });
    return counter;
}]);

app.controller('MyController', ['$scope','UpdateCounter', function ($scope,UpdateCounter) {
    $scope.counter = UpdateCounter;
}]);

In your view, you can reference counter.count to get the count and it will be automatically updated. 在您看来,您可以引用counter.count来获取计数,它将自动更新。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM