我是一个红宝石开发商,而且是新的角色。我一直在关注许多指南,但我很感激您解决这个问题的任何帮助。我理解angular有懒惰加载的想法,但我不确定这与我的场景如何相符。我正在制作的应用程序包含一个登录屏幕,该屏幕会向服务器发送您的凭据。服务器使用jwt签名令牌进行响应,以用于套接字连接。
为简单起见,我有2个控制器,LoginCtrl
和HomeCtrl
。我的工厂名为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
..
无论如何,我知道这是一个巨大的文本块,如果有任何善意的人愿意阅读这个,我会非常感激!
答案 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
只能创建一次。