我听说,该服务不应该链接到控制器中的范围变量,因为视图可以直接访问服务.但我想将我的范围变量绑定到存储在服务中的数据,我希望该变量反映服务的所有更改.我已经阅读了很多解决方法,并且大多数人被告知要使用$scope.$watch,如果我想从控制器观看服务数据.我写了一个简单的例子,没有使用$scope.$watch,它的工作方式与我想要的完全一样,但我绝对不确定,我可以使用这样的东西,或者这是一个不好的做法.我正在学习角度大约2-3天,非常需要你的建议:
HTML:
<div ng-controller="TestController">
<p>Current value = {{ serviceData.getValue() }}</p>
<input type="text" ng-model="newValue">
<button ng-click="changeServiceData(newValue)">Change</button>
</div>
module.js
var app = angular.module('app', []);
controller.js
app.controller('TestController', function($scope, testService){
$scope.serviceData = testService.getPublicData();
$scope.changeServiceData = function(newValue){
testService.setValue(newValue);
}
});
service.js
app.factory('testService', function(){
var value = null;
return {
setValue: function(newValue){
value = newValue;
},
getPublicData: function(){
return {
getValue: function(){
return value;
}
}
}
}
});
总而言之,视图只能访问getter.要更新数据,我正在使用服务,我可以在任何控制器中注入,服务中的所有更改都会反映在控制器和视图上.
更新:
我试图改变我的工厂:
app.factory('testService', function(){
var value = null;
return {
setValue: function(newValue){
value = newValue;
},
getValue: function(){
return value;
}
}
});
并将getter分配给范围:
app.controller('TestController', function($scope, testService){
$scope.value = testService.getValue();
$scope.changeServiceData = function(newValue){
testService.setValue(newValue);
}
});
在这种情况下,如果我使用setter从视图中更改服务中的值,则值不会在视图中隐含地更改,它不会反映实际的服务数据.也许你能解释一下这种行为?
最佳答案 您的更新几乎是正确的,如果您决定使用包含变量的服务,则该模块和控制器将共享该服务.
你需要做的只是现在使用这个getter和setter:
app.controller('TestController', function($scope, testService){
$scope.testService = testService;
$scope.newValue = 'initial-value';
});
在你的HTML中:
<div ng-controller="TestController">
<p>Current value = {{ testService.getValue() }}</p>
<input type="text" ng-model="newValue">
<button ng-click="testService.setValue(newValue)">Change</button>
</div>
现在我们仍然将值放入范围,因为显然您只想在单击时更新服务值,因此需要从服务本身取消同步.
如果要将服务值直接绑定到该输入的ngModel中,则不能使用getter,但必须直接使用该变量:
<input ng-model="testService.value">
或者最后一个选项是使用ngChange指令传播对newValue所做的任何更改:
<input ng-model="newValue" ng-change="testService.setValue(newValue)">