【问题标题】:view not updated when using $http in service在服务中使用 $http 时视图未更新
【发布时间】:2014-10-09 07:35:56
【问题描述】:

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

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

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

  3. 控制器 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 从旧更改为新。

我知道,有一些与“视图未更新”相关的 SO 问题,例如:The view is not updated in AngularJS

但我无法为我找到正确的解决方案。其中大多数导致:使用$scope.$apply(),但$scope 在服务中不可用。

【问题讨论】:

    标签: angularjs angularjs-scope angularjs-service


    【解决方案1】:

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

    markers: myService.getSharedProperty()
    

    所以它得到一个空数组。

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

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

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

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

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

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

    $scope.getProperty = myService.getSharedProperty
    

    在视图中:

    {{ getProperty() }}
    

    【讨论】:

    • OMG - 我花了几个小时查看我的代码以找到解决方案,您在 6 分钟内给了我正确的提示:now references a new, empty array 非常感谢!顺便说一句:另一种方法是使用但没有property.splice()
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-28
    • 2017-08-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多