【问题标题】:socket.emit only working for one controller AngularJSsocket.emit 仅适用于一个控制器 AngularJS
【发布时间】:2018-01-14 05:13:25
【问题描述】:

大家好,我遇到了一个奇怪的问题。我的 socket.emit 正在为我的一个控制器工作,但它不适用于另一个控制器。

server.js(服务器端)

io.sockets.on('connection', function(socket){
  console.log('User ' + socket.id + ' connected');
  socket.emit('test');
});

QueueController.js(客户端)(工作)

app.controller('QueueController', ['$scope', '$location', '$rootScope', 'socket',
    function($scope, $location, $rootScope, socket){

    socket.on('chat start', function(data){
        $rootScope.$apply(function(){
            $location.path('/chat');
        });
    });

    socket.on('test', function(){
        console.log('hello world'); //this displays fine in the console
    });
});

ChatController(客户端)(不工作)

app.controller('ChatController', ['$scope', '$rootScope', 'socket', 
    function($scope, $rootScope, socket){

    socket.on('test', function(){       
        console.log('hello world'); //this does not display at all  
    });
});

我读到需要将socket.emit 包装在一个

socket.on('connect', function(){ ... },但这不起作用。

这些是我的路线:

app.js

var app = angular.module('ChatApp', ['ngRoute', 'ngAnimate', 'luegg.directives', 'btford.socket-io']);

app.config(function($routeProvider, $locationProvider){
    $routeProvider
    .when('/', {
        controller:'HomeController',
        templateUrl:'views/home.html'
    })
    .when('/queue', {
        controller:'QueueController',
        templateUrl:'views/queue.html'
    })
    .when('/chat', {
        controller:'ChatController',
        templateUrl:'views/chat.html'
    })
    .otherwise({
        redirectTo: '/'
    });
});

有什么想法吗?

【问题讨论】:

  • 您知道根据您当前的路线只有一个控制器处于活动状态吗?
  • 我不知道。我必须怎么做才能切换到新的活动控制器?有可能吗?
  • 当您转到yourapp/queue 时,您将获得您在路由配置中定义的模板和控制器。如果你去 /chat(你可以在 url bar 中输入或在页面的某处放置一个链接)你会得到带有它的模板的 chatcontroller。如果您想在路由中添加额外的控制器,则需要在该路由的模板中的某个位置放置一个带有 ng-controller 的元素。

标签: angularjs node.js socket.io


【解决方案1】:

在您的情况下,这主要是范围问题。在您的路由配置中,每个控制器都被定义为拥有顶级作用域的控制器。并且当您更改页面时,该顶级范围控制器会一起切换。

一种解决方法是构建一个将在所有页面中使用的控制器,例如 MasterCtrl 或 RootCtrl。然后,您可以将该控制器附加到 body 标签或 html 标签。然后,无论您在哪个页面,该控制器都会触发,您可以实现多页面套接字服务。

<html ng-app='YourApp' ng-controller="MasterCtrl">

或

<body ng-app='YourApp' ng-controller="MasterCtrl">

但是,我最终建议您使用组件(可从 Angular.js 1.5 获得)。将您的 scoket 服务放在一个组件中。在任何情况下都可以使用它来使用套接字。由于组件默认具有独立的作用域,因此您可以实现套接字服务而不必担心作用域冲突。

查看此网址以进一步了解组件。 https://toddmotto.com/exploring-the-angular-1-5-component-method/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-05
    • 1970-01-01
    相关资源
    最近更新 更多