在服务中使用$ http时,视图未更新

时间:2014-08-15 14:46:04

标签: angularjs angularjs-scope angularjs-service

我有一个带有2个控制器和一个服务的angularJS应用程序,用于在控制器之间交换数据。

  1. 控制器1“控制”一个angluarjs-map,为视图提供地图元数据。

  2. 提供应在地图中显示的与用户当前位置相关的数据sharedProperty的服务

  3. 控制器2,监视用户的更改,如果发生更改,请更新sharedProperty以更新地图/视图

  4. 原始控制器很复杂,所以我想发布一些“伪”/示例代码。

    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

1 个答案:

答案 0 :(得分:2)

控制器在实例化时获取属性一次:

markers: myService.getSharedProperty()

所以它得到一个空数组。

但该服务在其http回调中更改了该属性:

.success(function(value){
    property = [];

因此,服务的属性变量现在引用一个新的空数组,但控制器的属性变量仍引用旧的初始空数组。

如果您希望控制器查看数组中的更改,则不应为该属性分配新数组。你应该清除它,并用新值填充它:

.success(function(value){
    property.splice(0, property.length);

另一种方法是始终从视图中的服务获取属性。在控制器中:

$scope.getProperty = myService.getSharedProperty

在视图中:

{{ getProperty() }}
相关问题