我正在使用AngularJS 1.2.0在websocket上创建一个简单的消息传递应用程序。 HTML在列表上使用ng-repeat来生成总输出(我正在输入的消息数组)。我正在使用工厂来托管“私有”数据和方法,并且只暴露视图模型和函数来操纵控制器中的数据:
<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();
}
}
});
除了在Service ['view']中的输出数组获得新消息时DOM的ng-repeat没有更新时,一切都正常工作。我已尝试使用$ watchCollection作为此线程中的解决方案:AngularJS : The correct way of binding to a service properties,但这也不起作用。我可以让DOM重新渲染的唯一方法是通过改变输入文本或触发CSS中的悬停状态来强制重新渲染。
鉴于这种设置,触发摘要的最佳方式是什么,以便在使用新消息数据解析承诺并且未移位到输出数组时DOM呈现?我想避免使用$ rootScope和触发事件,因为当其他控制器使用工厂时,它会变得非常不干净。
答案 0 :(得分:1)
在服务中,我添加了$ rootScope依赖项并使用了$ rootScope。$ apply()来解析promise并更新模型。
$rootScope.$apply(function() {
Service['view']['output'].unshift(newMessage)
});
这似乎解决了摘要问题,虽然我不确定副作用是什么。