【问题标题】:updating controller over service not updating view通过服务更新控制器而不更新视图
【发布时间】:2014-04-28 12:26:08
【问题描述】:

在我的应用程序中,我有一个“地图”来显示和处理地图上的内容。 CtrlMap 控制器显示地图并显示标记。 watchPosMap 监视位置变化。第三有一个名为markerService 的服务,它保存标记的属性(位置)。

结构看起来是这样的。

[CtrlMap] <-> [MarkerService] <- [watchPosMap]

这是服务:

MyMapApp.service('MarkerService', function () {
    //set initial marker if no one exists
    if (property == undefined)
    {
        var property = {
            latitude: 44.49,
            longitude: -108.42};
    }
    return {
        getP: function () {
            return property;
        },
        setP: function(lat,lng) {
            consolie.info('Have new marker properties:', lat,lng);
            property = {
                latitude: lat,
                longitude: lng};
        }
    };
});

在启动时,CtrlMap 控制器以这种方式获取默认标记设置:$scope.marker = MarkerService.getP()。效果很好。

如果设备的位置发生变化,watchPosMap 包含一个带有回调的navigator.geolocation.watchPosition 方法,该方法调用服务MarkerService 以设置新的标记参数。

这是我的watchPosMap 控制器:

MyMapApp.controller('watchPosMap', ['$scope', 'MarkerService', function($scope) {            
$scope.watchMyPositionChangesID = 
          navigator.geolocation
                    .watchPosition(function(data) {
                        mapScope=angular.element(document.getElementById('id_map'))
                                .scope();
                        angular.element(document.getElementById('id_map'))
                                .injector().get("MarkerService")
                                .setP(data.coords.latitude,data.coords.longitude);
                        mapScope.$apply();
                       },
                       function(e){$scope.errorMsg=e;},
                       { timeout: 30000 }
                      );

}]);

设置标记属性有效,但视图未更新。有什么事情可以触发视图更新吗?

【问题讨论】:

    标签: javascript angularjs google-maps-api-3 angularjs-service angularjs-controller


    【解决方案1】:

    如果您在适当的范围内,那么您必须在修改 Angular 之外的内容时更新范围。

    angular.element(document.getElementById('id_map')).scope().$apply();
    

    评论后编辑:

    虽然您的范围标记已投入使用,但它并未更新事件。它必须在你使用 $apply() 之前更新

    mapScope.marker = angular.element(document.getElementById('id_map'))
                                .injector().get("MarkerService")
                                .getP();
    

    编辑 2:更清洁的方式 $apply 的作用域有一个回调函数,你可以用它来实现同样的目的

    navigator.geolocation
                    .watchPosition(function(data) {
                         mapscope = angular.element(document.getElementById('id_map')).scope()
                         mapscope.$apply(function(scope){
                           MarkerService.setP(data.coords.latitude,data.coords.longitude); 
                           scope.marker = MarkerService.getP();
                         });
                       },
                       function(e){$scope.errorMsg=e;},
                       { timeout: 30000 }
                      );
    

    【讨论】:

    • 我仍然使用 $apply()。我编辑我的问题:请查看watchPosMapcontroller。
    • 服务属性已更新,但恐怕标记未更新。您需要更新 mapScope.marker = angular.element(document.getElementById('id_map')) .injector().get("MarkerService") .getP();在你使用 $apply() 之前
    • 是的!而已! :-) 我想知道,如果我的解决方案是结合 angularjs 和遗留 JS 的正确方法?!
    • @TheBndr 更新了我的答案,请验证。
    • I hope,angular.element(document.getElementById('id_map')).scope() is the same scope of watchPosMap controller 这是一个不同的控制器,但相同的应用程序/模块。我不确定:这是同一个范围吗?我不这么认为,对吧?
    猜你喜欢
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 2014-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-13
    • 1970-01-01
    相关资源
    最近更新 更多