我从工厂的websocket获取数据。每次收到消息时我都会更新。
在我的控制器中,我在$ scope中绑定了相同的内容。但是,当websocket消息出现时,UI不会更新。
经过大量搜索后,我发现我需要调用$ scope。$ apply如果我需要更新UI(如果没有使用任何角度方法保存更改)。
我使用setInterval设置一个计时器来调用$ scope。每秒都应用$。但这是一个黑客。我想删除它。有没有办法告诉角度从工厂内部刷新,而不使用这个黑客?
厂:
app.factory('StocksFactory', function() {
...
factory.stocksCurrentPrices = {};
// Subscribe to the websocket for stock prices
const stocksSocket = new WebSocket('ws://...');
stocksSocket.onmessage = function(event) {
// Adding to current prices
factory.stocksCurrentPrices[..] = ...;
};
return factory;
});
控制器:
app.controller('StocksController', function($scope, StocksFactory) {
$scope.stocks = StocksFactory.stocksCurrentPrices;
// HACK This is used to force the digest every second as the changes in $scope.stocks
// was not reflected in the UI
setInterval(function() {
$scope.$apply();
}, 1000);
});
答案 0 :(得分:2)
您不能在AngularJS服务中使用$scope
,因为服务不属于任何范围,但它们在应用程序中是单例。
但您可以将$rootScope
注入服务并通过整个应用程序进行通知,如下所示:
app.factory('StocksFactory', function($rootScope, $timeout) {
...
factory.stocksCurrentPrices = {};
// Subscribe to the websocket for stock prices
const stocksSocket = new WebSocket('ws://...');
stocksSocket.onmessage = function(event) {
// Adding to current prices
factory.stocksCurrentPrices[..] = ...;
// notify of changes
$timeout(function() {
$rootScope.$apply();
})
};
return factory;
});
请注意:
$rootScope.$apply();
包裹在$timeout
内以便Prevent error $digest already in progress $rootScope.$broadcast
答案 1 :(得分:1)
您可以在工厂中注入$rootScope
并在其中使用$broacast
来发出已更改的内容。
答案 2 :(得分:0)
在工厂中添加$rootScope
,并在股票市场发生变化时广播消息。
app.factory('StocksFactory', ['$rootScope', function($rootScope) {
var factory = {}
factory.stocksCurrentPrices = {};
const stocksSocket = new WebSocket('ws://...');
stocksSocket.onmessage = function(event) {
factory.stocksCurrentPrices[..] = ...;
$rootScope.$broadcast('stocks-just-change')
};
return factory;
}])
然后在您的控制器中,只需听取广播消息并更新您的$scope.stocks
app.controller('StocksController', function($scope, StocksFactory) {
$scope.stocks = StocksFactory.stocksCurrentPrices;
$scope.$on('stocks-just-change', function(){
$scope.stocks = StocksFactory.stocksCurrentPrices;
//$scope.$apply() //use this if you'll receive updates very very fast
}
})