I'm using AngularJS 1.2.0 to create a simple messaging app over a websocket. The HTML is using ng-repeat on a list to generate the total output (an array of messages I'm inputting). I'm using a factory to host 'private' data and methods and exposing only the view model and functions to manipulate the data in the controller:
<form class="form-search">
<input type="text" ng-model="model.input" class="input-large"
placeholder="Enter your message:">
<button type="submit" class="btn" ng-click="sendMessage()">Send</button>
</form>
<ul>
<li ng-repeat="message in model.output track by $index" ng-bind="message"></li>
</ul>
application.controller('MessageCtrl', ['$scope', 'MessageService', function($scope, Service) {
$scope['model'] = Service.view;
$scope.sendMessage = function() {
Service.sendMessage();
};
$scope.$watchCollection(function() {
return Service['view'];
}, function(data) {
$scope['model'] = data;
});
}])
.factory('MessageService', function('Restangular') {
var Service = {
// other private properties
view: {
input: null,
output: []
}
};
openConnection();
function openConnection() {
// retrieves websocket URL over Restangular
// opens websocket
}
function sendMessage() {
// sends input over socket
// promises are resolved and unshifted onto Service['view']['output'].
}
return {
view: Service['view'],
sendMessage: function() {
sendMessage();
}
}
});
Everything is working properly except that the DOM's ng-repeat is not updating when the output array in Service['view'] gets a new message. I've tried using $watchCollection as a solution in this thread: AngularJS : The correct way of binding to a service properties, but this doesn't work either. The only way I can get the DOM to re-render is by forcing it to re-render by changing the input text or triggering hover states in CSS.
Given this setup, what would be the best way to trigger a digest so the DOM renders as soon as a promise is resolved with new message data and unshifted onto the output array? I want to avoid using $rootScope and firing events as that can get very unclean when other Controllers use the factory.