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