AngularJS:服务变量更改不适用
AngularJS : Service variable changes not applying
我目前遇到一个问题,当我在服务中调用一个函数来更改它自己的内部变量时,它似乎不会保留,除非我从控制器更改它。当我在更改变量后立即将变量输出到控制台时,它显示正确的值。但是,当我在控制器中调用一个函数来打印对象以进行控制台时,它会显示原始值。
我遇到问题的变量是 "isSignedIn",即使在 "console.log('Signin:' + isSignedIn);" 行显示 true 之后,它始终显示 false(通过登录控制器中的 $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 更改
当我点击登录功能时,控制台记录 "New State SigningIn" 并且 dom 更改为 "Currently Signedin: SigningIn" 但是当我触发下一个事件时,控制台记录 "New State SignedIn" 但是DOM 仍然反映旧值 "Currently Signedin: SigningIn" 因此绑定似乎只在第一次更新而不是后续时间。
您 return 作为服务的对象中的值与您之前定义的 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()}}
绑定仍未更新(仅当某些其他操作以某种方式 "forces" 时)。这可能是因为该值由 Angular 的摘要周期之外的内容更新,所以没有任何内容告诉 Angular 在正确的时刻更新内容。
查看代码,state
在 property.changed
的回调中分配了一个新值(顺便说一句,property
应该用 var
正确声明!)。尝试将该行包装在 $apply() 中以使 Angular 更新绑定!
在调用函数返回的服务(工厂)值的地方添加一个 $watch。如果它在服务中发生变化,它将更新值。
$scope.$watch(function() { return ModalService.getInfo(); }, function(){
$scope.info = ModalService.getInfo();
});
我目前遇到一个问题,当我在服务中调用一个函数来更改它自己的内部变量时,它似乎不会保留,除非我从控制器更改它。当我在更改变量后立即将变量输出到控制台时,它显示正确的值。但是,当我在控制器中调用一个函数来打印对象以进行控制台时,它会显示原始值。
我遇到问题的变量是 "isSignedIn",即使在 "console.log('Signin:' + isSignedIn);" 行显示 true 之后,它始终显示 false(通过登录控制器中的 $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 更改
当我点击登录功能时,控制台记录 "New State SigningIn" 并且 dom 更改为 "Currently Signedin: SigningIn" 但是当我触发下一个事件时,控制台记录 "New State SignedIn" 但是DOM 仍然反映旧值 "Currently Signedin: SigningIn" 因此绑定似乎只在第一次更新而不是后续时间。
您 return 作为服务的对象中的值与您之前定义的 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()}}
绑定仍未更新(仅当某些其他操作以某种方式 "forces" 时)。这可能是因为该值由 Angular 的摘要周期之外的内容更新,所以没有任何内容告诉 Angular 在正确的时刻更新内容。
查看代码,state
在 property.changed
的回调中分配了一个新值(顺便说一句,property
应该用 var
正确声明!)。尝试将该行包装在 $apply() 中以使 Angular 更新绑定!
在调用函数返回的服务(工厂)值的地方添加一个 $watch。如果它在服务中发生变化,它将更新值。
$scope.$watch(function() { return ModalService.getInfo(); }, function(){
$scope.info = ModalService.getInfo();
});