Angularjs 服务/控制器与服务属性上定义的$watch的交互。这块表不亮;别开枪,有人能澄清一下吗

Angularjs 服务/控制器与服务属性上定义的$watch的交互。这块表不亮;别开枪,有人能澄清一下吗,angularjs,Angularjs,我创建了一个服务,它基本上创建了一个间隔,最终将向webapi发送$http post以检索消息。现在我只是将一个新的消息对象添加到一个数组中进行测试 在控制器端,我初始化服务并在其中一个服务属性上放置一个监视,其思想是当服务添加新消息时,我将监视以向用户显示通知。显然,这不会在每次调用时向displayedNotifications数组添加新消息,但这只是测试原型 以下是我的服务 (function () { 'use strict'; var serviceId = "no

我创建了一个服务,它基本上创建了一个间隔,最终将向webapi发送$http post以检索消息。现在我只是将一个新的消息对象添加到一个数组中进行测试

在控制器端,我初始化服务并在其中一个服务属性上放置一个监视,其思想是当服务添加新消息时,我将监视以向用户显示通知。显然,这不会在每次调用时向displayedNotifications数组添加新消息,但这只是测试原型

以下是我的服务

(function () {
    'use strict';

    var serviceId = "notificationService";

    //angular.module('app').factory(serviceId, ['helpersService', '$interval', function (helpersService, $interval) {
    angular.module('app').factory(serviceId, ['helpersService', '$interval', function (helpersService, $interval) {
        var defaultOptions = {
            url: undefined,
            interval: 1000
        };

        var myIntervalPromise = undefined;
        var displayedNotifications = [];

        //function onNotificationSuccess(response) {
        //    alert("in success");
        //    return response.data;
        //}

        //function onNotificationFailed(response) {
        //    alert("in Failure");
        //    throw response.data || 'An error occurred while attempting to process request';
        //}


        function initializeNotificationService(configOptions) {

            var passedOptions = $.extend({}, defaultOptions, configOptions);

            if (passedOptions.url) {

                myIntervalPromise = $interval(
                    function() {
                        console.log(passedOptions.url);
                        // eventually this push will accept a string/object returned from a webapi call
                        displayedNotifications.push({ messageobject: "this is new message" });
                    }, passedOptions.interval);

                //alert("in initializeNotificationService");
                return myIntervalPromise;
            }
            return myIntervalPromise;
        }

        //$scope.$on('$destroy', function() {
        //    if (angular.isDefined(myIntervalPromise)) {
        //        $interval.cancel(myIntervalPromise);
        //        myIntervalPromise = undefined;
        //    }
        //});

        return {
            // methods
            initializeNotificationService: initializeNotificationService,
            //properties
            displayedNotifications : displayedNotifications
        };
    }]);

})();
下面是我的控制器

(function () {
'use strict';

var controllerId = 'MessageCtrl';

angular.module('app').controller(controllerId, ['notificationService', '$scope', 

function (notificationService, $scope) {
        var vm = this;
        //vm.notifications = [];

        vm.initialize = function () {
            // initialize tyhe notification service here
            notificationService.initializeNotificationService({url:'this is a test url', interval: 5000})
                .then(
                    function (response) {
                        vm.notifications.push(response);
                         alert("successful call");
                    },
                    function(response) {
                         alert("failure to call");
                    },
                    function(iteration) {
                        // **a break point here clearly shows this property being changed**
                        console.log(notificationService.displayedNotifications);
                        //NEW EDIT HERE
                        $scope.notifications = notificationService.displayedNotifications;
                    }
                );

            $scope.$watch('notifications ', function (newValues, oldValues) {
                alert("watcher notified that notifications have changed");
            }, true);
        };

        vm.alertClicked = function (alert) {
            alert.status = 'old';
        };

        // call to init the notification service here so when the controller is loaded the service is initialized
        vm.initialize();

    }]);
})();
我希望每5秒钟,当一个新的消息对象被添加到services displayedNotifications属性时,watch函数中的警报就会触发一次。然而,它只有在所有东西都初始化时才会触发一个,然后它就不会再次触发。我做错了什么

新编辑


更改了控制器中“.then”的通知功能,以分配
displayNotifications
的值,以设置
$scope.notifications
,并将手表设置为该变量且该变量有效。但是,尽管如此,在$scope级别设置一个变量似乎很糟糕。。。是否有办法监视控制器上的变量,例如
vm.notifications=[]的注释行???

通知服务。显示的通知不在范围内。您毕竟调用了
**$scope**.$watch

您可以将服务或仅将属性添加到范围:

$scope.displayedNotifications = notificationService.displayedNotifications;
$scope.watch('displayedNotifications', ...
在您的情况下,作用域上没有notificationService.displayedNotifications,因此无法更改。这就是函数只运行一次的原因

另一种选择是使用函数作为监视表达式:

$scope.$watch(function() {
    return notificationService.displayedNotifications.length;
  }, function (newValues, oldValues) {
角度检查函数的返回值是否已更改

作为@ShawnC。您还可以使用事件。在您的服务中,您通过
$rootScope.$broadcast
发送一个,在控制器中,您通过
$scope.$on
接收它(我不会在控制器中使用
$rootScope


我能想到的最后一个选择是在回调中处理它。它们无论如何都会被调用,因此手表是一种开销。

那么$watch或$watchCollection是否只监视$scope上的变量,或者是否有更好的设置方法?您可以在服务上使用$rootScope。$emit,而不是让您的控制器使用$rootScope进行侦听$on@denas可以将函数用作监视表达式:
$scope.$watch(function()){return notificationService.displayedNotifications.length;},…
。Angular检查函数的返回值是否更改。是否可以在控制器的属性上放置一个手表,例如行
vm.notifications=[];
并设置
vm.notifications=notificationService.displayedNotifications
以某种方式?@denas恐怕不行。我更新了答案,列出了所有可能的备选方案。