基本上,我有两个指令:
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
是获取JSON文件的$resource
实现。
我的问题是指令功能在控制器调用之前执行。也就是说,我在指令中调用mapData
的几个属性,并且它们都在控制台中返回未定义的相应错误消息。但是,在错误打印输出后不久,执行$resource
实现的数据提取并打印到控制台。
请注意,如果我替换$promise
并完全依赖
$scope.mapData = Map.mapData()
.query();
然后我在$scope.mapData
指令中看到了<donut-chart>
,但没有<ng-map>
。
鉴于这种结构,如何在控制器加载数据之前延迟指令功能?
答案 0 :(得分:0)
执行顺序:
<div ng-controller="controller">
<outer>
<inner></inner>
<inner></inner>
</outer>
</div>
将是:
因此,控制器在指令链接发生之前明确设置范围。当然,除非在异步函数中设置范围。但是你的指令应该能够处理undefined
范围值,因为指令不会(可能不应该)关心它在哪个控制器下操作,除非requires
它。
答案 1 :(得分:0)
我使用joakimbi's解决方案来解决这个问题。具体来说,我添加了ngRoute
依赖项并使用resolve
属性来确保所包含的promise将在显示视图之前执行数据提取。
更新服务:
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()
变量中。由于我计划针对多个视图扩展此应用程序,因此ngRoute
结合resolve
承诺是合适的解决方案。