强制DOM在$scope模型引用到工厂模型的更改时进行渲染。

17 浏览
0 Comments

强制DOM在$scope模型引用到工厂模型的更改时进行渲染。

我正在使用AngularJS 1.2.0创建一个简单的通过websocket通信的消息应用程序。HTML中使用ng-repeat在列表上生成总体输出(一个我输入的消息数组)。我使用一个工厂来托管“私有”数据和方法,并仅将视图模型和操作数据的函数暴露给控制器:

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

// 其他私有属性

view: {

input: null,

output: []

}

};

openConnection();

function openConnection() {

// 通过Restangular获取websocket URL

// 打开websocket

}

function sendMessage() {

// 发送输入到socket

// promises被解析并添加到Service['view']['output']数组的开头。

}

return {

view: Service['view'],

sendMessage: function() {

sendMessage();

}

}

});

除了DOM中的ng-repeat在Service['view']的output数组获得新消息时没有更新之外,一切都正常工作。我尝试使用$watchCollection作为解决方案,参考了这个线程:AngularJS : The correct way of binding to a service properties,但这也不起作用。我唯一可以让DOM重新渲染的方法是通过更改输入文本或在CSS中触发hover状态来强制它重新渲染。

在这种设置下,如何最好地触发digest,以便在promise解析为新消息数据并添加到输出数组时DOM立即渲染?我想避免使用$rootScope和触发事件,因为当其他控制器使用工厂时,这可能会变得非常混乱。

0
0 Comments

问题的出现是因为在Service中,当promise被解析并更新模型时,我添加了$rootScope的依赖,并使用了$rootScope.$apply()。这似乎解决了digest问题,尽管我不确定副作用是什么。

解决方法是在Service中使用$rootScope.$apply()来强制DOM在$scope模型引用到factory模型的更改时进行渲染。具体代码如下:

$rootScope.$apply(function() {
    Service['view']['output'].unshift(newMessage)
});

0