2012-04-16 18 views
55

L'aggiornamento della proprietà del modello non ha alcun effetto sulla vista durante l'aggiornamento del modello nella richiamata dell'evento, eventuali idee per risolvere questo problema?La vista non è aggiornata in AngularJS

Questo è il mio servizio:

angular.service('Channel', function() {   
    var channel = null; 

    return {   
     init: function(channelId, clientId) { 
      var that = this;   

      channel = new goog.appengine.Channel(channelId); 
      var socket = channel.open(); 

      socket.onmessage = function(msg) { 
       var args = eval(msg.data);    
       that.publish(args[0], args[1]); 
      }; 
     }  
    }; 
}); 

publish() funzione è stata aggiunta in modo dinamico nel controller.

Controller:

App.Controllers.ParticipantsController = function($xhr, $channel) { 
    var self = this; 

    self.participants = [];  

    // here publish function is added to service 
    mediator.installTo($channel); 

    // subscribe was also added with publish   
    $channel.subscribe('+p', function(name) { 
     self.add(name);  
    });     

    self.add = function(name) {  
     self.participants.push({ name: name });  
    } 
}; 

App.Controllers.ParticipantsController.$inject = ['$xhr', 'Channel']; 

Vista:

<div ng:controller="App.Controllers.ParticipantsController">  
    <ul> 
     <li ng:repeat="participant in participants"><label ng:bind="participant.name"></label></li> 
    </ul> 

    <button ng:click="add('test')">add</button> 
</div> 

Quindi il problema è che facendo clic sul pulsante aggiorna la visualizzazione correttamente, ma quando ricevo il messaggio dalle paroline Canale accade, anche il add() la funzione si chiama

risposta

126

Manca $scope.$apply().

Ogni volta che si tocca qualcosa dall'esterno del mondo Angolare, è necessario chiamare $apply, per notificare Angular. Questo potrebbe essere da:

  • XHR callback (gestita dal servizio di $ http)
  • setTimeout callback (gestito da $defer servizio)
  • DOM evento di callback (gestito dalle direttive)

Nella tua caso, fare qualcosa di simile:

// inject $rootScope and do $apply on it 
angular.service('Channel', function($rootScope) { 
    // ... 
    return { 
    init: function(channelId, clientId) { 
     // ... 
     socket.onmessage = function(msg) { 
     $rootScope.$apply(function() { 
      that.publish(args[0], args[1]); 
     }); 
     }; 
    } 
    }; 
}); 
+1

Questo è stato utile, e una volta ho pensato al motivo per cui ho d per fare questo nel caso degli eventi DOM/jQuery, aveva senso per me e io ero in grado di accettarlo. – duma

+0

Freddo. Non sapevo che potessi iniettare lo scope di root. – heneryville

+4

Per i callback 'setTimeout', utilizzare invece il servizio' $ timeout': https://coderwall.com/p/udpmtq – itghisi

Problemi correlati