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更改

当我点击登录功能时,控制台记录“New State SigningIn”,而dom更改为“Currently Signedin:SigningIn”,但是当我得到下一个事件时,控制台记录“New State SignedIn”,但DOM仍然反映旧值“目前正在签名:SigningIn“,因此绑定只会在第一次更新时显示,但不会随后显示。


作为服务返回的对象中的值与前面定义的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在适当的时候更新内容。

看看代码, stateproperty.changed的回调中被分配了一个新的值(顺便说一句, property应该正确地声明为var !)。 尝试在$ apply()中包装该行以使Angular更新绑定!


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

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

见解决方案

链接地址: http://www.djcxy.com/p/77539.html

上一篇: AngularJS : Service variable changes not applying

下一篇: AngularJS and WebSockets beyond