【问题标题】:How to watch a primitive service variable in controller with AngularJS?如何使用 AngularJS 在控制器中观察原始服务变量?
【发布时间】:2026-01-21 03:30:02
【问题描述】:

我正在尝试使用 $watch 。 $watch 主体在页面初始化时触发(在 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/

【问题讨论】:

    标签: angularjs


    【解决方案1】:

    您可以传递一个函数,该函数将返回服务方法的值。然后 Angular 会将其与之前的值进行比较。

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

    演示:http://jsfiddle.net/TheSharpieOne/RA2j7/2/

    注意:文本字段值不更新的原因是按钮仅更改服务的值,而不是 $scope 的您也可以摆脱初始警报(运行更改功能)但比较newValue 到 oldValue 并且仅在它们不同时执行语句。

    【讨论】:

    • 谢谢!我是否正确,如果我想更改文本字段,那么我应该这样做:$scope.$watch(function(){ return authService.isLoggedIn; }, function (newValue, oldValue) { if (newValue == oldValue) return; $scope.isLoggedIn = newValue; alert("isLoggedIn changed from " + oldValue + " to " + newValue); }, true); (jsfiddle.net/googman/RA2j7/5)
    • 谢谢!为什么我在真/假 val 上的 $watch 总是返回未定义,这让我很生气。我之前在服务变量上使用过 $watch,但这是第一次使用布尔类型而不是 JSON 对象。