角度如何更改绑定到事件侦听器的变量

时间:2015-01-27 22:37:03

标签: angularjs

我是一个红宝石开发商,而且是新的角色。我一直在关注许多指南,但我很感激您解决这个问题的任何帮助。我理解angular有懒惰加载的想法,但我不确定这与我的场景如何相符。我正在制作的应用程序包含一个登录屏幕,该屏幕会向服务器发送您的凭据。服务器使用jwt签名令牌进行响应,以用于套接字连接。

为简单起见,我有2个控制器,LoginCtrlHomeCtrl。我的工厂名为signaling

以下是HomeCtrl的样子:

angular.module('myApp')

.controller('HomeCtrl',function($scope, $state, $ionicPopup, $http, config, signaling){

  $scope.homeDo = function () {
    signaling.socket.emit("ping","nothing")

  };
  signaling.socket.on("pong", function(m){
    console.log("it worked!");
  })

});

现在signaling使用socketFactory创建套接字。我的问题首先从这开始:我希望用户通过发布到服务器接收的令牌创建用户的套接字连接。如何在运行时使用令牌创建该套接字连接。这是信令工厂代码:

angular.module('myApp')

.factory('signaling', function(socketFactory,$localStorage, config, $state,$ionicPopup) {

  this.token = {};
  this.socket = socketFactory({ioSocket: io.connect(config.api+'/?token=' + this.token, { 'forceNew': true})})

  return this;
  }
});

如您所见,应用程序首次运行时未设置信令的令牌。套接字尝试连接未定义的标记参数。我不想要这个。我想显式设置工厂的令牌,然后只有在我成功登录后才创建套接字。

这是我的LoginCtrl代码:

angular.module('myApp')

.controller('LoginCtrl',function($scope, $state, $ionicPopup, $http, config, socketFactory, signaling, $localStorage){
 $scope.data = {};
 $scope.login = function () {
    $http.post(config.api+'/login',{
    username: $scope.data.username,
    password: $scope.data.password})
    .success(function(data, status, headers) {
      signaling.token = data.token;
      signaling.socket = socketFactory({ioSocket: io.connect(config.api+'/?token=' + data.token, { 'forceNew': true})})
      $state.go('app.home');
     })
    .error(function(data, status, headers, config) {
        $state.go('app.login');
    });
  };    
});

现在让我们说我在登录后点击了成功回调,然后我获得了令牌。 signaling.socket现在是我想要使用的正确套接字,但是现在所有偶数监听器都没有设置为监听它。例如,在HomeCtrl代码的早期,我有了监听器:

signaling.socket.on("pong", function(m){
  console.log("it worked!");
})

如果服务器发出" pong"那么代码将不会执行因为我怀疑应用程序第一次运行时。 signaling.socket是使用未定义标记创建的套接字。我已通过手动添加正确的令牌验证了这一点。

据我所知,我可能应该回去看书并阅读更多有关Angular的内容,但是我无法理解这一点。

TL; DR - 我有一个对象(信令),它有一个实例变量socket我想将socket变量设置为非运行时的东西,但是在运行时,我在null signaling.socket上注册事件监听器。我想要重新注册事件,或者不要在运行时运行HomeCtrl ..

无论如何,我知道这是一个巨大的文本块,如果有任何善意的人愿意阅读这个,我会非常感激!

1 个答案:

答案 0 :(得分:0)

即使您无法在运行时运行HomeCtrl,也可以将signaling.socket添加到HomeCtrl范围的观察列表并监控其更改,如下所示

$scope.$watch('signaling.socket', function(socket) {
  if (socket) {
    socket.on("pong", function(m){
      console.log("it worked!");
    });
  }
});

这样,当您在LoginCtrl中使用令牌创建新套接字时,HomeCtrl将捕获此更改并将处理程序pong绑定到新创建的套接字。

如果用户不被允许查看主页,除非他们已登录,则有更好的解决方案

app.run(function ($rootScope, $state, signaling) {
  $rootScope.$on('$stateChangeStart',
    function (event, toState, toParams, fromState, fromParams) {
      if (toState === 'home' && !!signaling.token) {
        event.preventDefault();
        $state.go('login');
      }
      $state.go(toState.name, toParams);
    }
}

只有在令牌存在后才会初始化HomeCtrl,而signaling.socket只能创建一次。