1

基本上,我有两个指令:

angular.module("maineMap")
.directive("ngMap", ["APPCONFIG", "Map", function(config, Map){
       //D3 map drawing functionality based on data from $resource call
       return {
        restrict : "E",
        transclude : true,
        scope : {
            mapData : '='
        },
        link : function(scope, el, attrs){
                   }
        };
    }])
    .directive("donutChart", function(){
    return {
        restrict : "E",
        link : function(scope, el, attrs){
                    }
            }
    });

和一个控制器

angular.module("maineMap")
.controller('MapCtrl', ['$scope','Map', function($scope, Map{
    $scope.mapData = Map.mapData()  
                        .query();

    $scope.mapData.$promise.then(function(results){
        $scope.mapData = results;
        console.log($scope.mapData);
    });

}]);

哪里Map$resource获取 JSON 文件的实现。

我的问题是指令功能在控制器调用之前执行。也就是说,我mapData在指令中调用了几个属性,它们都在控制台中返回 undefined 并带有相应的错误消息。但是,在错误打印输出后不久,从$resource实现中获取的数据会执行并打印到控制台。

请注意,如果我替换$promiseand 仅依赖于

$scope.mapData = Map.mapData()  
                        .query();

然后我在指令中$scope.mapData可见,但不是.<donut-chart><ng-map>

鉴于这种结构,我如何才能将指令功能延迟到控制器加载数据之后?

4

2 回答 2

0

我使用了 joakimbi 的解决方案来解决这个问题。具体来说,我添加了一个ngRoute依赖项并使用该resolve属性来确保包含的承诺将在显示视图之前执行数据获取。

更新服务:

angular.module("maineMap")
.factory("MapService", ["$http", "$log", "$q", "appConfig", function($http, $log, $q, appConfig){
    var mapPaths, mapPromise, 
        cityPositions, cityPromise;

    return {
        getMapPaths : function(){

            mapPromise = $http.get(appConfig.maineData)
                                .success(function(data){
                                    mapPaths = data;
                                });

            return {
                getData : function(){
                    return mapPaths;
                },
                setData : function(data){
                    mapPaths = data;
                },
                promise : mapPromise
            };
        },
        getCityPositions : function() { ... }
   };
}]);

修改了在 resolve 属性中定义 promise 的应用初始化器:

angular.module("maineMap", ["ngResource", "ngRoute", "configuration"])
.config(["$routeProvider", function($routeProvider){
    $routeProvider.when("/", {
        templateUrl : "views/main.html",
        controller : "MapCtrl",
        resolve : {
            "MapData" : function(MapService){
                return MapService.getMapPaths().promise;
            },
            "CityData" : function(MapService){
                return MapService.getCityPositions().promise;
            }
        }
    });
}]);

修改后的控制器,其中数据获取在视图之前加载:

angular.module("maineMap")
.controller('MapCtrl', ['$scope','MapService', function($scope, MapService){
    $scope.mapData = MapService.getMapPaths().getData();
    $scope.cityData = MapService.getCityPositions().getData();
    $scope.currentCounty = {};
    console.log("MapData: " + $scope.mapData);
}]);

这样做的结果是,在视图模板中处理指令的标记之前,执行数据获取并将结果保存在范围内,使其可用于指令。

Martin Atkins提出的另一种选择是将数据加载到angular.constant()变量中。由于我计划将此应用程序扩展到多个视图,因此ngRouteresolvepromises 相结合是合适的解决方案。

于 2014-10-07T12:30:09.737 回答
0

执行顺序:

<div ng-controller="controller">
    <outer>
      <inner></inner>
      <inner></inner>
    </outer>
</div>

将会:

  1. 编译(内部)
  2. 编译(内部)
  3. 编译(外)
  4. 控制器
  5. 控制器(外)
  6. 控制器(内部)
  7. 链接(内部)
  8. 控制器(内部)
  9. 链接(内部)
  10. 链接(外)

因此,控制器在指令链接发生之​​前明确设置范围。当然,除非范围是在异步函数中设置的。但是您的指令应该能够处理undefined范围值,因为该指令不(可能不应该)关心它在哪个控制器下运行,除非requires它。

于 2014-10-03T14:22:26.053 回答