使用AngularJS

时间:2017-12-10 01:02:35

标签: angularjs socket.io

我过去遇到过问题,其中SocketIO在使用AngularJS时会发出重复事件。出现这种情况的原因有两个常见原因:

  • connect事件侦听器中创建事件侦听器。
  • 多次动态创建事件侦听器(通常使用AngularJS)。

幸运的是,有两种常见的解决方案符合上述情况。请参阅接受的答案以了解这些解决方案。

1 个答案:

答案 0 :(得分:0)

connect事件监听器

中创建事件监听器

如果在connect事件侦听器中创建侦听器,则会发生此错误。只需将这些侦听器移到connect事件侦听器之外。

在:

socket.on('connection', _ => {
    console.log('Connected');

    socket.on('someOtherEvent', data => {
        console.log(data);
    });
});

后:

socket.on('connection', _ => {
    console.log('Connected');
});

socket.on('someOtherEvent', data => {
    console.log(data);
});

多次动态创建事件侦听器(通常使用AngularJS)。

如果在控制器中注册事件侦听器,这是一个常见问题。要解决此问题,请按以下方式编辑您的服务:

angular.module('socketIO', []).factory('socket', $rootScope => {
    class SocketHandler {
        constructor(url) {
            this._socket = false;
            this._url = url;
            this._events = {};

            this._build();
        }

        _build() {
            // Change for your configuration options below.
            this._socket = io.connect(this._URL);
        }

        on(event, callback) {
            if(this._events.hasOwnProperty(event))
                return this._events[event];

            return this._events[event] = this._socket.on(event, (...args) => {
                $rootScope.$apply(_ => {
                    callback.apply(this._socket, args);
                });
            });
        }

        emit(event, data, callback = false) {
            return this._socket.emit(event, data, (...args) => {
                if(!callback)
                    return;

                $rootScope.$apply(_ => {
                    callback.apply(this._socket, args);
                });
            });
        }
    }

    return { build: SocketHandler };
});

然后,您可以在构造函数中使用它:

angular.module('someController', socketIO => {
    const socket = socketIO.build('your socket url');
});

此修复工作原因是因为当您在AngularJS(使用默认路由器)中切换页面时,它会重新创建控制器的实例。这意味着多个事件侦听器现在绑定到单个事件。我们通过在SocketHandler._events中缓存我们的事件侦听器来阻止这种情况发生,并在缓存后返回缓存的侦听器。