带有服务器发送事件的 AngularJS
Posted
技术标签:
【中文标题】带有服务器发送事件的 AngularJS【英文标题】:AngularJS with Server-Sent Events 【发布时间】:2014-09-29 18:22:15 【问题描述】:我有一个带有以下控制器的 AngularJS 应用程序。它与常规 JSON 资源上的 GET 和手动更新请求一起工作得很好,但我不能让它与服务器发送的事件一起工作。我面临的问题是,在我收到 SSE 事件并设置/更新 openListingsReport 变量后,我的视图没有得到更新。我显然错过了一个非常基本的概念。请帮我解决这个问题。
var rpCtrl = angular.module('rpCtrl', ['rpSvc']);
rpCtrl.controller('rpOpenListingsCtrl', ['$scope', 'rpOpenListingsSvc',
function ($scope, rpOpenListingsSvc)
$scope.updating = false;
if (typeof(EventSource) !== "undefined")
// Yes! Server-sent events support!
var source = new EventSource('/listings/events');
source.onmessage = function (event)
$scope.openListingsReport = event.data;
$scope.$apply();
console.log($scope.openListingsReport);
;
else
// Sorry! No server-sent events support..
alert('SSE not supported by browser.');
$scope.update = function ()
$scope.updateTime = Date.now();
$scope.updating = true;
rpOpenListingsSvc.update();
$scope.reset = function ()
$scope.updating = false;
]);
【问题讨论】:
EventSource 是否绑定到某种网络套接字(signalr 等)?您不能只将作用域函数放在角度控制器上,并期望服务器自动向它发送请求。 EventSource 是 html SSE 规范的一部分:developer.mozilla.org/en-US/docs/Web/API/EventSource 服务器不是问题。我在客户端 JS 中更新了 openListingsReport 的值。我只是无法让 AngularJS 在 HTML 中显示 openListingsReport 的更新值。console.log($scope.openListingsReport)
undefined
或 null
的输出是空白还是空白?尝试像这样附加消息事件:source.addEventListener('message', function(e) console.log(e.data); , false);
我发现这篇文章很有帮助:html5rocks.com/en/tutorials/eventsource/basics
我明白了,对不起。尝试将您的 $scope
声明放在 $apply()
中:$scope.$apply(function() $scope.openListingsReport = event.data;);
看看:smartjava.org/content/…
请注意,您很少需要调用$scope.$apply();
脏检查应该可以处理绝大多数情况,包括这个
【参考方案1】:
问题出在下面一行:
$scope.openListingsReport = event.data;
应该是:
$scope.openListingsReport = JSON.parse(event.data);
【讨论】:
【参考方案2】:只是一个建议,以防有人将 SSE 与 AngularJs 一起使用。
如果你想使用服务器端事件,我建议使用 AngularJS 内置的 $interval 服务,而不是 SSE。
以下是基本示例。
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<p>Randome no:</p>
<h1>myWelcome</h1>
</div>
<p>The $interval service runs a function every specified millisecond.</p>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function ($scope, $interval, $http)
$scope.myWelcome = new Date().toLocaleTimeString();
$interval(function ()
$scope.myWelcome = $http.get("test1.php").then(function (response)
$scope.myWelcome = response.data;
);
, 3000);
);
</script>
</body>
</html>
test1.php
<?php
echo rand(0,100000);
【讨论】:
您的建议是轮询,对于许多应用程序而言,这远不如基于服务器的推送架构。 甚至每个人都已经知道,如果它可能有帮助,它只是一种替代方案。以上是关于带有服务器发送事件的 AngularJS的主要内容,如果未能解决你的问题,请参考以下文章
如何使用带有Rust的Actix Web和WebSockets发送服务器事件?
如何使用 _csrf 在 angularjs 中发送 POST 请求?