gpt4 book ai didi

javascript - 有 promise 的服务和 $watchCollection 不更新值

转载 作者:行者123 更新时间:2023-11-28 08:38:15 26 4
gpt4 key购买 nike

我正在尝试使用 MongoDB 和 AngularJS 构建实时服务消息传递。由于某种原因,当我的“消息传递”集合中有新数据时,不会触发 Messaging.getAllMessages() 服务,并且不会使用 $watchCollection 在 View 中更新我的数据。

这是在我的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>

如您所见,当服务器返回的数组中有新数据时, watch 不会更新 $scope.newMessages。我错过了一些东西,是否需要 socket.io 或 Pusher/Pubnub 来实现所需的行为?预先感谢您的帮助。

最佳答案

感谢@Sunil 指出这一点。我最初认为 $watch() 和 $watchCollection() 将自动拉取并根据 $digest() 周期提供的特定间隔检查服务是否有新数据。

我发布了我的解决方案需要某种触发器,以便在可用时从服务中提取新数据。因此,我使用 socket.io 实现了私有(private)消息 channel ,以触发对方发送的消息的更新。

这是更新后的指令:

更新了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);

}
};
}]);

关于javascript - 有 promise 的服务和 $watchCollection 不更新值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20821083/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com