javascript - 在 AngularJs 中使用 socket.io 进行用户更新时出现错误

标签 javascript angularjs node.js sockets

您好,每当用户更改其首选语言时,我都会尝试自动更新文章列表。

我尝试执行此操作的方法是每当用户在数据库中进行更改时更新IO 套接字

但是我的努力似乎没有成功,我不知道为什么。

由于我是socket.io的新手,所以我想我应该向这里的编码大神寻求一些帮助。

愿软件与您同在^^

PS:该项目是一个 Angular fullstack 项目,由 Yeoman 搭建

<小时/>

编码时间!


客户端/组件/articlebar/articlebar.controller.js

'use strict';

angular.module('unityAcademyApp')
.controller('ArticlebarCtrl', function ($scope, $location, Auth, socket) {
  $scope.articles = {};

  function populateArticles(){ 
       ...
        Some functionality where $scope.articles are set
        ...
    };

    socket.syncUpdates('user', $scope.articles, function() {
        console.log('hit');
        populateArticles();
    });
});


客户端/组件/socket/socket.service.js

/* global io */
'use strict';

angular.module('unityAcademyApp')
  .factory('socket', function(socketFactory) {

    // socket.io now auto-configures its connection when we ommit a connection url
    var ioSocket = io('', {
      // Send auth token on connection, you will need to DI the Auth service above
      // 'query': 'token=' + Auth.getToken()
      path: '/socket.io-client'
    });

    var socket = socketFactory({
      ioSocket: ioSocket
    });

    return {
      socket: socket,

      /**
       * Register listeners to sync an array with updates on a model
       *
       * Takes the array we want to sync, the model name that socket updates are sent from,
       * and an optional callback function after new items are updated.
       *
       * @param {String} modelName
       * @param {Array} array
       * @param {Function} cb
       */
      syncUpdates: function (modelName, array, cb) {
        cb = cb || angular.noop;

        /**
         * Syncs item creation/updates on 'model:save'
         */
        socket.on(modelName + ':save', function (item) {
          var oldItem = _.find(array, {_id: item._id});
          var index = array.indexOf(oldItem);   // this is line 39
          var event = 'created';

          // replace oldItem if it exists
          // otherwise just add item to the collection
          if (oldItem) {
            array.splice(index, 1, item);
            event = 'updated';
          } else {
            array.push(item);
          }

          cb(event, item, array);
        });

        /**
         * Syncs removed items on 'model:remove'
         */
        socket.on(modelName + ':remove', function (item) {
          var event = 'deleted';
          _.remove(array, {_id: item._id});
          cb(event, item, array);
        });
      },

      /**
       * Removes listeners for a models updates on the socket
       *
       * @param modelName
       */
      unsyncUpdates: function (modelName) {
        socket.removeAllListeners(modelName + ':save');
        socket.removeAllListeners(modelName + ':remove');
      }
    };
  });


服务器/config/socketio.js

/**
 * Socket.io configuration
 */

'use strict';

var config = require('./environment');

// When the user disconnects.. perform this
function onDisconnect(socket) {}

// When the user connects.. perform this
function onConnect(socket) {
    // When the client emits 'info', this listens and executes
    socket.on('info', function (data) {
        console.info('[%s] %s', socket.address, JSON.stringify(data, null, 2));
    });

    // Insert sockets below
    require('../api/translation/translation.socket').register(socket);
    require('../api/comment/comment.socket').register(socket);
    require('../api/article/article.socket').register(socket);
    require('../api/language/language.socket').register(socket);
    require('../api/thing/thing.socket').register(socket);
    require('../api/user/user.socket').register(socket);
}

module.exports = function (socketio) {
    // socket.io (v1.x.x) is powered by debug.
    // In order to see all the debug output, set DEBUG (in server/config/local.env.js) to including the desired scope.
    //
    // ex: DEBUG: "http*,socket.io:socket"

    // We can authenticate socket.io users and access their token through socket.handshake.decoded_token
    //
    // 1. You will need to send the token in `client/components/socket/socket.service.js`
    //
    // 2. Require authentication here:
    // socketio.use(require('socketio-jwt').authorize({
    //   secret: config.secrets.session,
    //   handshake: true
    // }));

    socketio.on('connection', function (socket) {
        socket.address = socket.handshake.address !== null ?
            socket.handshake.address.address + ':' + socket.handshake.address.port :
            process.env.DOMAIN;

        socket.connectedAt = new Date();

        // Call onDisconnect.
        socket.on('disconnect', function () {
            onDisconnect(socket);
            console.info('[%s] DISCONNECTED', socket.address);
        });

        // Call onConnect.
        onConnect(socket);
        console.info('[%s] CONNECTED', socket.address);
    });
};


服务器/api/user/user.socket.js

/** * 当模型改变时向客户端广播更新 */

'use strict';

var User = require('./user.model');

exports.register = function(socket) {
  User.schema.post('save', function (doc) {
    onSave(socket, doc);
  });
  User.schema.post('remove', function (doc) {
    onRemove(socket, doc);
  });
}

function onSave(socket, doc, cb) {
  socket.emit('user:save', doc);
}

function onRemove(socket, doc, cb) {
  socket.emit('user:remove', doc);
}
<小时/>

到目前为止遇到的错误

到目前为止,我在运行代码时遇到以下错误

TypeError: array.indexOf is not a function
    at Socket.<anonymous> (socket.service.js:39)
    at socket.js:24
    at angular.js:17782
    at completeOutstandingRequest (angular.js:5490)
    at angular.js:5762
        (anonymous function)        @ angular.js:12416
        $get                        @ angular.js:9203
        (anonymous function)        @ angular.js:17785
        completeOutstandingRequest  @ angular.js:5490
        (anonymous function)        @ angular.js:5762

最佳答案

我不确定您为什么会收到该错误,但我想我知道为什么您的数据没有更新。

您必须将回调函数包装在 $timeout 函数中才能触发更改。例如,您可以这样做:

$timeout(function(){
    cb(event, item, array);
}, 0);

请记住在套接字工厂中包含 $timeout 指令。

关于javascript - 在 AngularJs 中使用 socket.io 进行用户更新时出现错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32288241/

相关文章:

javascript - D3如何创建圆轴和样式选项

node.js - 在 Socket.IO 中将数据保存在套接字上

node.js - 如何避免 MONGODB 模型中的模式重复

javascript - Linting jsx-a11y 向 div 元素添加角色

javascript - SQL 从数据库中选择一个值

javascript - 更改asp.net中的标签文本

javascript - 类型错误 : Cannot set property '10' of undefined with angularjs

javascript - 如何配置 Angular ui-router 不使用严格的 URL 匹配模式

node.js - 我可以使用 MongoDb 驱动程序从 node.js 调用 rs.initiate() 和 rs.Add() 吗?

javascript - 选择全部复选框 Angular Material 5 | Gmail 样式如果选择个人,它也会选择