我正在寻找如何在 AngularJS 中绑定到服务属性的最佳实践。
我已经通过多个示例来了解如何绑定到使用 AngularJS 创建的服务中的属性。
下面我有两个示例说明如何绑定到服务中的属性;他们都工作。第一个示例使用基本绑定,第二个示例使用 $scope.$watch 绑定到服务属性
在绑定到服务中的属性时是否首选这些示例中的任何一个,或者是否有另一个我不知道的选项会被推荐?
这些示例的前提是服务应每 5 秒更新其属性“lastUpdated”和“calls”。更新服务属性后,视图应反映这些更改。这两个例子都成功地工作了;我想知道是否有更好的方法来做到这一点。
基本绑定
可以在此处查看和运行以下代码:http: //plnkr.co/edit/d3c16z
<html>
<body ng-app="ServiceNotification" >
<div ng-controller="TimerCtrl1" style="border-style:dotted">
TimerCtrl1 <br/>
Last Updated: {{timerData.lastUpdated}}<br/>
Last Updated: {{timerData.calls}}<br/>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.js"></script>
<script type="text/javascript">
var app = angular.module("ServiceNotification", []);
function TimerCtrl1($scope, Timer) {
$scope.timerData = Timer.data;
};
app.factory("Timer", function ($timeout) {
var data = { lastUpdated: new Date(), calls: 0 };
var updateTimer = function () {
data.lastUpdated = new Date();
data.calls += 1;
console.log("updateTimer: " + data.lastUpdated);
$timeout(updateTimer, 5000);
};
updateTimer();
return {
data: data
};
});
</script>
</body>
</html>
我解决绑定到服务属性的另一种方法是在控制器中使用 $scope.$watch。
$scope.$watch
可以在此处查看和运行以下代码:http: //plnkr.co/edit/dSBlC9
<html>
<body ng-app="ServiceNotification">
<div style="border-style:dotted" ng-controller="TimerCtrl1">
TimerCtrl1<br/>
Last Updated: {{lastUpdated}}<br/>
Last Updated: {{calls}}<br/>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.js"></script>
<script type="text/javascript">
var app = angular.module("ServiceNotification", []);
function TimerCtrl1($scope, Timer) {
$scope.$watch(function () { return Timer.data.lastUpdated; },
function (value) {
console.log("In $watch - lastUpdated:" + value);
$scope.lastUpdated = value;
}
);
$scope.$watch(function () { return Timer.data.calls; },
function (value) {
console.log("In $watch - calls:" + value);
$scope.calls = value;
}
);
};
app.factory("Timer", function ($timeout) {
var data = { lastUpdated: new Date(), calls: 0 };
var updateTimer = function () {
data.lastUpdated = new Date();
data.calls += 1;
console.log("updateTimer: " + data.lastUpdated);
$timeout(updateTimer, 5000);
};
updateTimer();
return {
data: data
};
});
</script>
</body>
</html>
我知道我可以在服务中使用 $rootscope.$broadcast 并在控制器中使用 $root.$on ,但是在我创建的其他示例中,在第一次广播中使用 $broadcast/$ 不会被控制器,但在控制器中触发了广播的其他调用。如果您知道解决 $rootscope.$broadcast 问题的方法,请提供答案。
但是为了重申我之前提到的内容,我想知道如何绑定到服务属性的最佳实践。
更新
这个问题最初是在 2013 年 4 月提出并回答的。2014 年 5 月,Gil Birman 提供了一个新答案,我将其更改为正确答案。由于 Gil Birman 的回答几乎没有赞成票,我担心阅读这个问题的人会无视他的回答,转而支持更多投票的其他答案。在您决定最佳答案之前,我强烈推荐 Gil Birman 的答案。