2012-04-16 36 views
55

Việc cập nhật thuộc tính mô hình không ảnh hưởng đến chế độ xem khi cập nhật mô hình trong gọi lại sự kiện, bất kỳ ý tưởng nào để sửa lỗi này?Chế độ xem không được cập nhật trong AngularJS

Đây là dịch vụ của tôi:

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() chức năng được bổ sung động trong bộ điều khiển.

Bộ điều khiển:

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']; 

Xem:

<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> 

Vì vậy, vấn đề là cách nhấn vào nút cập nhật xem đúng, nhưng khi tôi nhận được thông báo từ nothings Kênh xảy ra, ngay cả những add() chức năng được gọi là

Trả lời

126

Bạn đang thiếu $scope.$apply().

Bất cứ khi nào bạn chạm vào bất kỳ thứ gì từ bên ngoài thế giới góc, bạn cần gọi số $apply để thông báo cho Angular. Đó có thể là từ:

  • XHR callback (xử lý bởi dịch vụ $ http)
  • setTimeout callback (xử lý bởi $defer dịch vụ)
  • DOM tổ chức sự kiện callback (xử lý bởi chỉ thị)

Trong của bạn trường hợp, hãy làm như sau:

// 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

Điều này hữu ích và một khi tôi nghĩ về lý do tại sao tôi ha d để làm điều này trong trường hợp các sự kiện DOM/jQuery, nó có ý nghĩa với tôi và tôi đã có thể chấp nhận nó. – duma

+0

Tuyệt. Tôi không biết bạn có thể tiêm vào phạm vi gốc. – heneryville

+4

Đối với các cuộc gọi lại 'setTimeout', sử dụng dịch vụ' $ timeout' thay vào đó: https://coderwall.com/p/udpmtq – itghisi

Các vấn đề liên quan