我创建了一个plunker来测试服务上的绑定$scope
。我发现我只能绑定到原始值,但引用服务的值。
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.7/angular.min.js"></script>
<body ng-app="BindToService">
<div ng-controller="BindToServiceCtrl as ctrl">
// I wonder why I could only bind on reference but primitive values of a service.
counterFactoryObj: {{counterFactoryObj}}<br/>
counterFactoryVal: {{counterFactoryVal}}<br/>
counterFactoryFun(): {{counterFactoryFun()}}<br/>
</div>
<script type="text/javascript">
var app = angular.module("BindToService", []);
app.controller("BindToServiceCtrl", function ($scope, CounterFactory) {
$scope.counterFactoryObj = CounterFactory.obj;
$scope.counterFactoryVal = CounterFactory.val;
$scope.counterFactoryFun = CounterFactory.fun;
});
app.factory("CounterFactory", function ($interval) {
var obj = [0];
var val = 0;
var fun = function () { return val; };
var addCounter = function () {
obj[0] += 1;
val += 1;
};
$interval(addCounter, 1000);
return {
obj: obj,
val: val,
fun: fun
};
});
</script>
</body>
在此演示中,只有counterFactoryObj
和counterFactoryFun()
会随时间变化。我想知道AngularJS是如何绑定价值的。
答案 0 :(得分:1)
我认为这里有一些事情会造成混乱。
首先,当您返回一个带有:
的对象时return {
val: someVal
}
对象的属性val
在您将其返回到someVal
的值时设置。因此,当您返回CounterFactory
服务时,CounterFactory.val === 0
- 始终 - 并且它与Angular的绑定无关。
其次,使用CounterService
服务,您的CounterService
实例有this.val
,实际上它正在使用$ interval更新(尝试使用console.log
)。问题在于,您将其在特定时间点(例如,当控制器函数运行时)的值分配给$scope.counterServiceVal
变量。在此处,虽然CounterService.val
发生了变化,但仍然如下:$scope.counterServiceVal === 0
。
顺便说一句,.service
和.factory
就Angular而言都返回一个单例服务实例,除了一个返回一个新的函数而另一个 - 实际的实例,但是与Angular获取实际服务实例的内容有关 - 在注入服务之后它的行为方式相同。
最后,如果你想绑定一个值 - 你可以,但是你需要实际改变那个值并绑定到那个变化的变量。以下是您使用CounterFactory
执行此操作的方法,例如:
app.factory("CounterService", function ($interval) {
var svc = { val: 0 };
function addCounter() {
svc.val += 1;
};
$interval(addCounter, 1000);
return svc;
});
// in controller
$scope.counterService = CounterService;
<!-- in the view -->
<span>{{counterService.val}}</span>