【问题标题】:AngularJs - RequireJs - Socket.io : Not playing well togetherAngularJs - RequireJs - Socket.io:一起玩得不好
【发布时间】:2015-03-18 20:01:50
【问题描述】:

我有一个两部分的问题:

I. --- 当我在 requirejs 路径文件中加载 socket.io 时,虽然它可能出现在浏览器的脚本集合中,但当我在工厂对象中使用它时,我收到错误, "io" 未定义。但是,如果我直接从 HTML 页面加载 socket.io.js,我不会收到错误消息。 我找到了another person had the exact issue here,但没有找到解决方案。

II. --- 我正在使用 ocLazyLoad,我的应用程序是按功能模块化的。我选择将我从 Brian Ford's example 复制的 $socket factory 对象直接放在我的根模块 ['app'] 中。我知道每次使用延迟加载场景中的服务时都需要加载它们,而不管之前对它们的调用如何。但是,这似乎是错误的。如果我想让我的应用程序实时,这意味着我必须将它列为每个州的依赖项。应该有更有效的方法来做到这一点,但我看不出如何。

问题一:

  1. 建立 RequireJs 依赖并添加到 bootstrap

    一个。 RequireJs的路径文件:

      //socket.io
      'socket.io' : '/vendor/socket.io-client/lib/socket.io'
      //shim
      'socketio': {exports: 'io'}
    

    b.引导文件

    window.name = "NG_DEFER_BOOTSTRAP!";
      define([
        'require',
        'jquery',
        'socket.io',
        'angular',
         .....
    

    观察:这一切都按预期工作,socket.io.js 现在在我的浏览器的页面加载脚本集合中证明了这一点。

  2. $socket 工厂服务

    一个。 app.socket.js(来自 Brian Ford 的工厂文件)文件:

   define(['app'], function (app) {
   app.factory('$socket',['$rootScope', function ($rootScope) {
     /////////////////////
     // PROBLEM IS HERE //
     /////////////////////
      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);
                    }
                });
            })
        }
    };
}]); });

b.使用 $socket 工厂的控制器

 define(['angular'], function(ng) {
  'use strict';

  /* @ngInject */
  MyDashboardCtrl.$inject = ['$socket','MyDashboardSvc'];
  ng.module('MyDashboard').controller('MyDashboardCtrl', MyDashboardCtrl);
  function MyDashboardCtrl($socket, MyDashboardSvc) {
  ....

观察:从 require 的路径文件加载 socket.io.js 后,一旦控制器将工厂作为依赖项调用,我就会收到此错误:

              ReferenceError: io is not defined

如果我直接从 HTML 加载 socket.io.js,问题就会消失:

<script src="vendor/socket.io-client/lib/socket.io.js"></script> 
<script src="app/require/rconfig.js"></script> 
<script src="vendor/requirejs/require.js" data-main="app/app.bootstrap.js"></script>

问题二:

我想让我的整个应用程序实时化。这是否意味着,如果我打算使用延迟加载,我需要在每个 BLESSED $state 中列出 $socket 工厂?

【问题讨论】:

    标签: angularjs socket.io requirejs


    【解决方案1】:

    我讨厌我的解决方案。我将socket.io对象放在requirejs内部的windows上,然后使用角度的$window对象找到它。这真的很糟糕——但它会让我在找到更好的解决方案的同时继续编码。这里有相关和不相关的部分:

    <script text="text/javascript">
        require.config({
          paths: {
            angular: "<path to angular>" 
            socketIO: [
                "/socket.io/socket.io"
            ],
            myNgApplicationJs: "/client/my-angular-all"
          },
          shim: {
            socketIO: { deps: [] },
            angular: { deps: [
                "jQuery",
                "socketIO"
            ] },
            myNgApplicationJs: {deps: [
                "angular", "socketIO"
            ]}
          }
        });
    
        require([
            "myNgApplicationJs"
            ,"socketIO"
        ], function(noop, io) {
    
            // a hack to make the socket.io available on the $window in angular
            window.io = io
    
            angular.bootstrap(document, ['myNgApplication']);
    
            return {};
        });
    </script>
    

    然后(基于从 Brian Ford 偷取的代码):

    angular.module('myNgApplication').factory('MySocketIO', function ($log, $window, $rootScope) {
    
        if(!$window.io) {
            throw new Exception("assure the socket.io is added to the window object. e,g, window.io")
        }
    
        // Hack socket.io off of the $window object 
        var io = $window.io
        var socket = io();
    
        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);
                        }
                    });
                })
            }
        };
    });
    

    这让我可以将 hack 抽象出来——尽我所能。如果我找到更好的解决方案,我只需要更改 requirejs peice 和 MySocketIO 实现。

    然后我像这样编写业务级工厂代码:

    angular.module('myNgApplication').factory('BlahProxy', function ($log, MyHttp, MySocketIO) {
        var Blah = {}
    
        Blah.onUpdate = function(callback) {
            // don't expose socket-io message type to the controllers
            MySocketIO.on('send:testIV', callback)
        }
    
        return Blah
    })
    

    然后在我的控制器中利用这些工厂:

    angular.module('myNgApplication').controller('myBlahGridCtrl', function ($scope, $log, BlahProxy) {
    
        $scope.messages = []
    
        // handle whatever message types explicitly
        BlahProxy.onUpdate(function (message) {
            $scope.messages.push(message);
        })
    
    })
    

    【讨论】:

      【解决方案2】:

      我遇到了同样的问题,它通过在我的 socketfactory 文件依赖项中添加“socket.io”来解决。在您的情况下,请尝试以下更改:

      一个。 app.socket.js 文件:

         define(['app', 'socket.io'], function (app, io) {
            app.factory('$socket',['$rootScope', function ($rootScope) {
                //........
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-10-23
        • 2015-05-08
        • 1970-01-01
        • 1970-01-01
        • 2013-07-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多