与承诺,$ watchCollection更新不及时的服务价值 [英] Service with promise and $watchCollection not updating the values

查看:173
本文介绍了与承诺,$ watchCollection更新不及时的服务价值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图构建的MongoDB和AngularJS实时服务的消息。出于某种原因,当出现在我的'消息'收集新数据时,Messaging.getAllMessages()服务则不会触发和我的数据不会更新视图,使用$ watchCollection。

I'm trying to build real time service messaging with MongoDB and AngularJS. For some reason, when there is new data in my 'messaging' collection, the Messaging.getAllMessages() service is not triggered and my data is not updated in the view, using $watchCollection.

这是我的 services.js ,最重要的功能就是 getAllMessages()

This is in my services.js, the important function is 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';
       });
    }
  };
}]);

这是模板,消息-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>

正如所看到的$ scope.newMessages不受手表更新,当存在由serive返回的数组中的新数据。我失去了一些东西,有没有需要socket.io或推/ Pubnub达到预期的行为?感谢您事先的任何帮助。

As you see the $scope.newMessages is not updated by the watch, when there is new data in the array returned by the serive. I'm missing something, is there need for socket.io or Pusher/Pubnub to achieve the desired behaviour? Thanks in advance for any help.

推荐答案

感谢@Sunil指出了这一点。我本来以为,那手表$()和$ watchCollection(),会自动拉和检查的基础上由$摘要()循环提供了具体的时间间隔为新的数据服务。

Thanks @Sunil for pointing that out. I originally thought, that $watch() and $watchCollection(), will pull automatically and check the service for new data based on specific interval provided by the $digest() cycle.

我发布了我的解决方案需要某种触发的,这样,新的数据从服务被拉出时可用。所以,我实现了使用socket.io私人信息渠道触发从对方发送消息更新。

I released that my solution needs some kind of trigger, so that the new data to be pulled from the service when available. So I implemented private messaging channels using socket.io for triggering updates on message sent from the other party.

下面是更新指令:

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

    }
  };
}]);

这篇关于与承诺,$ watchCollection更新不及时的服务价值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆