Связывание служебных переменных в Angular.js

Я пытаюсь создать модальный вход в систему, который будет обновлять шаблоны (только базовую информацию о пользователе - аватары, имена и т. д.) на разных контроллерах. Примерно следуя этому example, мой подход заключался в том, чтобы связать служебные переменные непосредственно внутри моих партиалов следующим образом:

частичный:

<div ng-controller="TopBarControl">
    <span>{{ userService.getInfo() }}</span>
</div>

услуга:

.service('userService', function($http) {

    this.userInfo = {
        isLogged: false         
    }

    this.getInfo = function() {
        return this.userInfo;
    }

    this.loginInit = function(userName, password) {
        $http.get('http://example.com/?json=get_nonce&controller=auth&method=generate_auth_cookie').success(
        function(data, status, headers, config) {
            var nonce = data.nonce;
            $http.get('http://example.com/?json=auth/generate_auth_cookie&nonce='+nonce+'&username='+userName+'&password='+password).success(function(data, status, headers, config) {
                if (data.status == 'ok') {
                    this.userInfo = [
                        {isLogged: true},
                        {username: data.user.username},
                        {firstName: data.user.firstname},
                        {lastName: data.user.lastname},
                        {avatar: data.user.avatar}
                    ];
                    return userInfo;
                } 
               /* handle errors and stuff*/     
        }); 
    }
})

контроллеры:

.controller('TopBarControl', function($scope, $modal, userService) {

    $scope.userService = userService;

    $scope.openLogin = function() {
        var modalInstance = $modal.open({
        templateUrl: 'views/modal.html',
        controller: ModalInstanceCtrl,
        size: 'lg'
      });
    }   
});

var ModalInstanceCtrl = function ($scope, $modalInstance, userService) {
  $scope.login = function () {
    userService.loginInit(this.userName, this.password);
  };

  $scope.ok = function () {
    $modalInstance.close($scope.returnResolveVariable);
  };
};

Итак, вход работает. Данные отправляются на сервер, и правильные данные успешно возвращаются в приложение. Двусторонняя привязка вроде как работает — каждый раз, когда происходит изменение, шаблон обращается к .getInfo() и выдает значение userInfo. Проблема в том, что значение userInfo никогда не меняется. Я не могу понять, что-то странное в том, как я устанавливаю переменную в loginInit, или есть что-то, чего я принципиально не понимаю в том, как сервисы обрабатывают такие переменные.


person Thomas    schedule 26.06.2014    source источник
comment
В вашем примере, где отношение между переменными userInfo контроллера и userInfo службы. Это не одна и та же переменная.   -  person gustavodidomenico    schedule 26.06.2014
comment
Ой... это было прокомментировано - это была просто ссылка на массив, который я хотел создать. Я удалил его для ясности.   -  person Thomas    schedule 26.06.2014


Ответы (1)


Это ваше использование ключевого слова «это». Контекст ключевого слова this, когда вы устанавливаете this.userinfo в первый раз, отличается от контекста this в методах обработки $http.

Сделайте что-то вроде этого, чтобы зафиксировать исходный контекст ключевого слова this, чтобы вы могли использовать его позже:

.service('userService', function($http) {
    var self = this;

    this.userInfo = {
        isLogged: false         
    };

    this.getInfo = function() {
        return this.userInfo;
    };

    this.loginInit = function(userName, password) {
        $http.get('http://example.com/?json=get_nonce&controller=auth&method=generate_auth_cookie').success(
        function(data, status, headers, config) {
            var nonce = data.nonce;
            $http.get('http://example.com/?json=auth/generate_auth_cookie&nonce='+nonce+'&username='+userName+'&password='+password).success(function(data, status, headers, config) {
                if (data.status == 'ok') {
                   self.userInfo = [
                        {isLogged: true},
                        {username: data.user.username},
                        {firstName: data.user.firstname},
                        {lastName: data.user.lastname},
                        {avatar: data.user.avatar}
                    ];
                    return userInfo;
                } 
               /* handle errors and stuff*/     
        }); 
    };
});

В приведенном выше коде переменная userInfo будет ограничена встроенной функцией обработчика при возврате вызова $http.

Понять ключевое слово this довольно сложно, это выглядит как хорошее введение 'http://javascriptissexy.com/understand-javascripts-this-with-clarity-and-master-it/', хотя я обычно не использую его и использую шаблон раскрывающего модуля для своих служб, который избавляется об этой путанице см. здесь для примера

person Jon    schedule 26.06.2014
comment
Вау, это получилось. Спасибо. - person Thomas; 26.06.2014
comment
Не беспокойтесь, JavaScript — сложная штука, но вы полюбите его! - person Jon; 26.06.2014