我有一个带有2个控制器和一个服务的angularJS应用程序,用于在控制器之间交换数据。
控制器1“控制”一个angluarjs-map,为视图提供地图元数据。
提供应在地图中显示的与用户当前位置相关的数据sharedProperty
的服务
控制器2,监视用户的更改,如果发生更改,请更新sharedProperty
以更新地图/视图
原始控制器很复杂,所以我想发布一些“伪”/示例代码。
MyCtrl.controller('ctrl1',
function($scope, myService) {
$scope.map = {
center:[..],
zoom: [..],
markers: myService.getSharedProperty(),
};
});
MyCtrl.service('myService', function ($http) {
if (property === undefined)
{
//Default Marker
var property = [];
}
return {
getSharedProperty: function () {
return property;
},
setSharedProperty: function(location) {
$http.jsonp('[..myURL...]')
.success(function(value){
property = [];
angular.forEach(value.data, function(val,key){
property.push({
prop:val;
});
});
});
}
};
});
MyCtrl.controller('ctrl2',
function($scope,myService) {
$scope.watchMyPositionChangesID =
navigator.geolocation
.watchPosition(
function(data) {
myService.setSharedProperty(data);
},
[...]
);
}
});
这种结构在不同的情况下工作,只要服务不使用http请求。回调可能就是为什么angularJS没有注意到sharedProperty
的变化。
所以问题:如何使用新值触发视图更新?
如果我撕开目的地地图范围并“手动”应用新属性,该服务有效,如:
mapScope=angular.element(document.getElementById('id_map'))
.scope();
mapScope.map.circles = property;
(此代码应添加到$ http的成功回调中)
但我想。这是一种肮脏的?
因为,如果我在视图端更改HTML元素的ID
,我必须抓取所有源代码,将ID
从旧更改为新。
我知道,有一些与“查看未更新”相关的问题,如下所示:The view is not updated in AngularJS
但我无法为我找到合适的解决方案。其中大部分都会产生:使用$scope.$apply()
,但服务无法使用$scope
。
答案 0 :(得分:2)
控制器在实例化时获取属性一次:
markers: myService.getSharedProperty()
所以它得到一个空数组。
但该服务在其http回调中更改了该属性:
.success(function(value){
property = [];
因此,服务的属性变量现在引用一个新的空数组,但控制器的属性变量仍引用旧的初始空数组。
如果您希望控制器查看数组中的更改,则不应为该属性分配新数组。你应该清除它,并用新值填充它:
.success(function(value){
property.splice(0, property.length);
另一种方法是始终从视图中的服务获取属性。在控制器中:
$scope.getProperty = myService.getSharedProperty
在视图中:
{{ getProperty() }}