2015-08-15 20 views
1

即时通讯目前有在那里,当我调用一个函数,改变它似乎不留,除非我从控制器改变它自己的内部变量服务的问题。在我更改变量后立即将该变量输出到控制台时,它会显示正确的值。但是,当我在控制器中调用打印对象到控制台的函数时,它会显示原始值。AngularJS:服务变量的变化不适用

即使在“console.log('Signin:'+ isSignedIn)”之后,变量Im的问题仍然是“isSignedIn”,它总是显示false(用login控制器中的$ scope.verify方法确认);“显示正确。

感谢的时候,由于任何指导未来!

服务商Skype

angular.module('Skype', ['ng']) 
    .service('skypeClient', function() { 
     //Service Properties 
     var client = new Skype.Web.Model.Application; 
     this.errors = []; 
     this.errorCount = -1; 
     var isSignedIn = false; 
     var state = 'SignedOut'; 

     var init = function() { 
      client.signInManager.state.when('SignedIn', function() { 
       isSignedIn = true; 
       console.log('Signin:' + isSignedIn); // This outputs the correct value 
      }); 
      property = client.signInManager.state; 
      property.changed(function (status) { 
      state = status; 
      console.log("New State"+status) }); 
      } 

     //Signin Function 
     var signIn = function (username,password) { 
      client.signInManager.signIn({ 
       username: username, 
       password: password 
      }).then(function() { 
       isSignedIn = true; 
       this.errorCount++; 
       console.log(this.errorCount); 
      }); 
     } 

     //SignOut Function 
     var signOut = function() { 
     client.signInManager.signOut() 
     .then(function() { 
      this.isSignedIn = false; 
     }, function (error) { 
      this.erros.push(error); 
      this.errorCount++; 
     }); 
     } 

     return { 
      signIn: signIn, 
      signOut: signOut, 
      init: init, 
      state: state, 
      isSignedIn: isSignedIn 
     }; 

}); 

控制器登录

'use strict'; 
angular.module('login', ['ngRoute', 'classy', 'Metio.Skype']) 
.config(['$routeProvider', function ($routeProvider) { 
    $routeProvider.when('/login', { 
     templateUrl: 'app/views/login.html', 
     controller: 'loginCntrl' 
    }); 
}]).controller('loginCntrl', function ($scope,skypeClient) { 

    skypeClient.init(); 

    $scope.skypeClient = skypeClient; 
    console.log('LoginCntrl Loaded'); 

    $scope.signIn = function() { 
     skypeClient.signIn($scope.user, $scope.password); 
    } 
    $scope.signOut = function() { 
     skypeClient.signOut(); 
    } 
    $scope.verify = function() { 
     console.log(skypeClient); 
    } 
}); 

[编辑] 根据pdenes建议(意见),同样的问题,但更清洁修改代码

厂的Skype

.factory('skypeClient', function() { 
     //Service Properties 
     var client = new Skype.Web.Model.Application; 
     var state = 'SignedOut'; 
     //Initialize Listeners 
     var init = function() { 
      client.signInManager.state.when('SignedIn', function() { 
       console.log('Signin:' + state); // This outputs the correct value 
      }); 
      property = client.signInManager.state; 
      property.changed(function (status) { 
       state = status; 
       console.log("New State" + state); 
      }); 
      console.log('init'); 
      } 
     //Signin Function 
     var signIn = function (username, password) { 
      client.signInManager.signIn({ 
       username: username, 
       password: password 
      }).then(function() {console.log('LoggedIn');}); 
     } 
     init(); 
     return { 
      signIn: signIn, 
      state: function(){return state} 
     } 
    }); 

控制器登录

.controller('loginCntrl', function ($scope,skypeClient) { 
    $scope.skypeClient = skypeClient; 
    $scope.signIn = function() { 
     skypeClient.signIn($scope.user, $scope.password); 
    } 
    $scope.verify = function() { 
     console.log(skypeClient); 
     console.log($scope.skypeClient); 
    } 
}); 

DOM标记

<input type="checkbox">Keep Me Signed In (Currently Signedin: {{skypeClient.state()}}) 

控制台输出和DOM变化

当我打的登入功能控制台登录“新国SigningIn”和DOM更改为“目前Signedin:SigningIn”但是当我的下一个触发的事件控制台登录“新国SignedIn”,但DOM仍然反映旧值“Currently Signedin:SigningIn”,因此绑定仅显示为第一次更新,但不是后续时间。

回答

7

在返回为服务对象的值是不一样的,你前面定义的变量isSignedIn。所以:

... 
var isSignedIn = false; 
... 
return { 
    isSignedIn: isSignedIn 
    //   ^this is false when the object is created 
    //   and will remain false, no matter how you 
    //   change the value of the above variable later 
}; 

要在封闭从服务暴露的isSignedIn的价值,你需要的功能,喜欢的东西:

... 
return { 
    ... 
    isSignedIn: function() { 
    return isSignedIn; // <- this refers to the above variable itself 
    } 
}; 

编辑:后续的更新代码这个问题...

显然,值在内部正确更新,但{{skypeClient.state()}}绑定仍然没有更新(只有当某种其他动作以某种方式“强制”它)。这可能是因为Angular的摘要循环之外的值更新了值,所以没有任何信息告诉Angular在适当的时候更新内容。

看代码,state分配回调中新值property.changed(顺便说一句,property应该适当地与var声明!)。尝试在$apply()中包装该行以使Angular更新绑定!

+0

谢谢你的令人难以置信的快速响应!当我尝试使用{{skypeClient.isSignedIn()}}绑定时,两部分问题看起来并未更新,当值更改时(我是否需要添加手表?)。第二部分是不是在服务中使用“this.isSignedIn”服务中的返回块,而是直接从控制器访问它?我曾尝试过这种第二种方法,但遇到了同样的问题。 – strspl

+0

它可能有助于说明,看来如果我调用打印服务对象到控制台的$ scope.verify方法,值更新谢谢 – strspl

+0

不客气! :)第一个:{{skypeClient.isSignedIn()}}绑定对我来说工作正常,你不应该需要手表...你可以请张贴一些代码,看看你想要做什么?第二:你是对的,我刚刚注意到你使用的是服务而不是工厂 - 所以你不应该返回一个对象,而应该填充“this”(你的函数是一个构造函数)。 – pdenes

0

在调用由函数返回的服务(工厂)值的地方添加$ watch。如果它在服务中发生变化,它将更新值。

$scope.$watch(function() { return ModalService.getInfo(); }, function(){ 
    $scope.info = ModalService.getInfo(); 
}); 

See solution