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

Forcing DOM to render upon changes to $scope model reference to factory model

本文关键字:模型 引用 DOM scope 工厂 强制      更新时间:2023-09-26

我正在使用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:绑定到服务属性的正确方式,但这也不起作用。我可以让DOM重新渲染的唯一方法是通过更改输入文本或触发CSS中的悬停状态来强制它重新渲染。

考虑到这种设置,触发摘要的最佳方式是什么,以便在使用新的消息数据解析promise并将其取消转移到输出数组后立即呈现DOM?我想避免使用$rootScope和触发事件,因为当其他控制器使用工厂时,这可能会变得非常不干净。

在服务中,我添加了$rootScope依赖项并使用了$rootScope$apply(),其中正在解析promise并更新模型。

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

这似乎解决了消化问题,尽管我不确定副作用是什么。