Как смотреть примитивную служебную переменную в контроллере с помощью AngularJS?

Я пытаюсь использовать $watch для него. Тело $watch срабатывает при инициализации страницы (с помощью undefined в newValue), а не стреляет в "btnChangeIsLoggedIn".

<!DOCTYPE html>
<html data-ng-app="myApp">
<head><title>title</title></head>
<body>
    <script src="lib/angular/angular.js"></script>

    <div ng-controller="ctrl1">
        <input type="text" ng-model="isLoggedIn" />
        <input type="button" id="btnChangeIsLoggedIn" 
            value="change logged in" ng-click="change()" />
    </div>

    <script>
        var myApp = angular.module('myApp', []);

        myApp.service('authService', function () {
            this.isLoggedIn = false;
        });

        myApp.controller('ctrl1', function ($scope, authService) {
            $scope.isLoggedIn = authService.isLoggedIn;

            $scope.$watch("authService.isLoggedIn", function (newValue) {
                alert("isLoggedIn changed to " + newValue);
            }, true);

            $scope.change = function() {
                authService.isLoggedIn = true;
            };
        });
    </script>
</body>
</html>

Что я делаю неправильно?

Мой код в JSFiddle: http://jsfiddle.net/googman/RA2j7/

Ответ 1

Вы можете передать функцию, которая вернет значение метода службы. Angular затем сравнит его с предыдущим значением.

$scope.$watch(function(){
    return authService.isLoggedIn;
}, function (newValue) {
    alert("isLoggedIn changed to " + newValue);
});

Демо: http://jsfiddle.net/TheSharpieOne/RA2j7/2/

Примечание: причина, по которой значение текстового поля не обновляется, заключается в том, что кнопка изменяет только служебное значение, а не $scope. Вы также можете избавиться от этого начального предупреждения (запуск функции изменения), но сравнивая newValue в oldValue и выполнять только инструкции, если они разные.