我正在尝试使用MongoDB和AngularJS构建实时服务消息。出于某种原因,当我的“messaging”集合中有新数据时,不会触发Messaging.getAllMessages()服务,并且使用$ watchCollection不会在视图中更新我的数据。
这是在我的 services.js 中,重要的功能是 getAllMessages():
angular.module('myApp')
.factory('Messaging', function($resource, $http, $q, $rootScope){
var myData = {};
return {
sendMessage: function(message, success, error) {
$http.post('/api/v1/users/' + message.to.id + '/messages', message).success(function(res) {
toastr.success('Message sent');
}).error(function(error) {
toastr.error("Error on save");
});
},
getAllMessages: function(userId) {
var deferred = $q.defer();
if(!myData) {
deferred.resolve(myData);
} else if (userId && userId !== '') {
$http.get('/api/v1/users/' + userId+ '/messages').success(function(data) {
myData = data;
deferred.resolve(myData);
// update angular's scopes
$rootScope.$$phase || $rootScope.$apply();
});
} else {
deferred.reject();
}
return deferred.promise;
},
markAsRead: function(ids, success, error) {
var deferred = $q.defer();
if(!myData) {
deferred.resolve(myData);
} else if (ids && ids !== '') {
$http.put('/api/v1/users/' + ids.userId + '/messages/' + ids.messageId).success(function(data) {
myData = data;
deferred.resolve(myData);
// update angular's scopes
$rootScope.$$phase || $rootScope.$apply();
});
} else {
deferred.reject();
}
return deferred.promise;
},
getMessage: function(ids, success, error) {
return $http.get('/api/v1/users/' + ids.userId + '/messages/' + ids.messageId);
},
deleteMessage: function(ids, success, error) {
return $http.delete('/api/v1/users/' + ids.userId + '/messages/' + ids.messageId);
}
}
});
这是在 directive.js :
中angular.module('myApp').directive('messaging', ['$log', 'Messaging', function($log, Messaging){
return {
scope: true,
restrict: 'A', // E = Element, A = Attribute, C = Class, M = Comment
templateUrl: '/views/templates/messaging-dropdown.html',
replace: true,
link: function($scope, iElm, iAttrs, controller) {
Messaging.getAllMessages($scope.user.id).then(function(myData) {
$scope.allMessages = myData;
$scope.newMessages = 0;
$scope.$watchCollection('allMessages', function(newVal, oldVal){
if(newVal !== oldVal) {
$scope.newMessages = 0;
// Count the number of unread messages
for (var i = myData.length - 1; i >= 0; i--) {
if(myData[i].read === false) {
$scope.newMessages++;
}
};
}
}, true);
}, function() {
// request failed (same as 'return false')
$scope.allMessages = 'i got the error';
});
}
};
}]);
这是模板, messaging-dropdown.html :
<div>
<a ng-click="showMessages()" ng-class="{clicked: messagesToggled}">
<i class="fa fa-envelope"></i>
<span class="badge" ng-show="newMessages > 0">{{newMessages}}</span>
</a>
<ul class="dropdown-menu" ng-show="messagesToggled">
<li ng-repeat="message in allMessages | limitTo: 5 | orderBy:'sent'">
<a ng-href="/users/{{message.to.id}}/messages/{{message._id}}" ng-class="{unread: !message.read}">
<img ng-src="{{message.from.image}}" alt="" class="img-circle">
<span class="body">
<span class="from">{{message.from.name}}</span>
<span class="message">
{{message.text}}
</span>
<span class="time">
<span>{{message.sent}}</span>
</span>
</span>
</a>
</li>
<li class="footer">
<a ng-href="/users/{{user.id}}/messages">See all <b>{{allMessages.length}}</b> messages</a>
</li>
</div>
如您所见,当watchve返回的数组中有新数据时,监视器未更新$ scope.newMessages。我缺少一些东西,是否需要socket.io或Pusher / Pubnub来实现所需的行为?提前感谢您的帮助。
答案 0 :(得分:0)
感谢@Sunil指出这一点。我原本以为,$ watch()和$ watchCollection()会根据$ digest()循环提供的特定时间间隔自动拉取并检查服务中的新数据。
我发布了我的解决方案需要某种触发器,以便在可用时从服务中提取新数据。因此,我使用socket.io实现了私有消息传递通道,以触发对方发送的消息更新。
这是更新的指令:
更新了 directive.js :
angular.module('myApp').directive('messaging', ['$log', 'Messaging', 'messagingSocket', function($log, Messaging, messagingSocket){
// Runs during compile
return {
scope: true,
restrict: 'A', // E = Element, A = Attribute, C = Class, M = Comment
templateUrl: '/views/templates/messaging-dropdown.html',
replace: true,
link: function($scope, iElm, iAttrs, controller) {
messagingSocket.emit('setUser', {id: $scope.user.id});
$scope.allMessages = function(){
Messaging.getAllMessages($scope.user.id).then(function(myData) {
$scope.allMessages.messages = myData;
}, function() {
// request failed (same as your 'return false')
$scope.allMessages = 'i got the error';
});
};
$scope.allMessages();
messagingSocket.forward('new message', $scope);
$scope.$on('socket:new message', function (event, data) {
$scope.allMessages();
});
$scope.$watchCollection('allMessages.messages', function(newVal, oldVal){
if(newVal !== oldVal) {
$scope.newMessages = 0;
// Count the number of unread messages
for (var i = $scope.allMessages.messages.length - 1; i >= 0; i--) {
if($scope.allMessages.messages[i].read === false) {
$scope.newMessages++;
}
};
}
}, true);
}
};
}]);