我在尝试使用angular& amp;中的数据填充矢量地图时遇到了麻烦。指令。
我有一个角度仪表板网页,需要显示填充了我数据库中数据的美国svg矢量地图。我正在关注this tutorial,一切正常,但教程将硬编码值传递给地图。我需要修改它以接受数据库值,&这就是我遇到麻烦的地方。如何使用指令调用我的数据库并将这些值传递回map?
我还是刚开始接触角度和角度这是我第一次使用指令,但看起来好像$http.get
调用发生在指令之后,所以我太迟了返回我的数据库数据。这是我的代码:
App.js
在这里,我正在使用这两个指令来实现此地图功能。一切正常:
var app = angular.module('dashboardApp', ['ngRoute', 'angularjs-dropdown-multiselect']);
app.controller('dashboardController', DashboardController);
app.directive('svgMap',function ($compile) {
return {
restrict: 'A',
templateUrl: '/Content/Images/Blank_US_Map.svg',
link: function (scope, element, attrs) {
var regions = element[0].querySelectorAll('path');
angular.forEach(regions, function (path, key) {
var regionElement = angular.element(path);
regionElement.attr("region", "");
regionElement.attr("dummy-data", "dummyData");
$compile(regionElement)(scope);
})
}
}
});
app.directive('region', function ($compile) {
return {
restrict: 'A',
scope: {
dummyData: "="
},
link: function (scope, element, attrs) {
scope.elementId = element.attr("id");
scope.regionClick = function () {
alert(scope.dummyData[scope.elementId].value);
};
element.attr("ng-click", "regionClick()");
element.attr("ng-attr-fill", "{{dummyData[elementId].value | map_color}}");
element.removeAttr("region");
$compile(element)(scope);
}
}
});
DashboardController.js
这就是我的问题所在。在这里,我通过$http.get
从我的数据库返回数据。我目前在此http.get&之外有我的$scope.createDummyData
功能。它工作正常。但是,如果我将该代码放在$http.get
中,则数据不会填充。这就是我的问题:
var DashboardController = function ($scope, $http) {
$http.get('/Account/GetDashboardDetails')
.success(function (result) {
//need to place my $scope.createDummyData inside here
})
.error(function (data) {
console.log(data);
});
var states = ["AL", "AK", "AS", "AZ", "AR", "CA", "CO", "CT", "DE", "DC", "FM", "FL", "GA", "GU", "HI", "ID", "IL",
"IN", "IA", "KS", "KY", "LA", "ME", "MH", "MD", "MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH", "NJ", "NM",
"NY", "NC", "ND", "MP", "OH", "OK", "OR", "PW", "PA", "PR", "RI", "SC", "SD", "TN", "TX", "UT", "VT", "VI", "VA",
"WA", "WV", "WI", "WY"];
$scope.createDummyData = function () {
var dataTemp = {};
angular.forEach(states, function (state, key) {
dataTemp[state] = { value: Math.random() }
});
$scope.dummyData = dataTemp;
};
$scope.createDummyData();
};
HTML
最后,这是我的HTML。我觉得这里没有任何关于我的问题,但无论如何我都把它包括在内,以防万一:
<div class="container">
<div svg-map class="col-md-8 col-sm-12 col-xs-12" style="height:350px;"></div>
<p>
<button ng-click="createDummyData()" class="btn btn-block btn-default">Create Dummy Data</button>
</p>
<div class="regionlist">
<div ng-repeat="(key,region) in dummyData">
<div>{{key}}</div>
<div>{{region.value | number}}</div>
</div>
</div>
</div>
如何通过数据库数据填充地图?
由于
答案 0 :(得分:0)
不确定这是否正是您正在寻找的,但可能有帮助。
我会创建一个服务来获取数据(我假设HTTP到/ Account / GetDashboardDetails返回状态列表)然后调用控制器中的服务。一旦调用完成,您就可以调用create dummyDataFunction。
// Service
angular
.module('dashboardApp')
.service('$dataService', dataService);
dataService.$inject = ['$http']
function dataService() {
var service = {
getData : getData
}
return service;
//////////
function getData() {
return $http.get('/Account/GetDashboardDetails')
.then(function (result) {
return result;
},function(error) {
return error;
})
}
}
// Controller
var DashboardController = function ($scope,$dataService) {
$scope.dummyData = [];
activate();
/////////
function activate() {
$dataService.getData()
.then(function(states){
var dataTemp = {};
angular.forEach(states, function (state, key) {
dataTemp[state] = { value: Math.random() }
});
$scope.dummyData = dataTemp;
},function(error) {
console.log(error);
});
}
};
答案 1 :(得分:0)
指令的链接功能在$http.get
XHR收到响应之前执行。一种方法是使用$watch
等待数据:
app.directive('region', function ($compile) {
return {
restrict: 'A',
scope: {
dummyData: "="
},
link: function (scope, element, attrs) {
scope.elementId = element.attr("id");
scope.regionClick = function () {
alert(scope.dummyData[scope.elementId].value);
};
element.attr("ng-click", "regionClick()");
element.attr("ng-attr-fill", "{{dummyData[elementId].value | map_color}}");
element.removeAttr("region");
//Use $watch to wait for data
scope.$watch("::dummyData", function(value) {
if (value) {
$compile(element)(scope);
};
});
}
}
});
在上面的示例中,监视表达式使用one-time binding,因此$compile
语句只执行一次。如果想要在每次数据更改时重新编译元素,它就会变得更加复杂。
有关$watch
的详情,请参阅AngularJS $rootscope.Scope API Reference - $watch
答案 2 :(得分:0)
在发出HTTP get请求之前,如果link
指令的svgMap
函数被调用,则无关紧要。
你所拥有的是svgMap
指令动态创建region
指令,这些指令从外部控制器范围绑定到dummyData
。
绑定到
dummyData
意味着Angular已经为绑定属性注册了观察者。从字面上看,这也意味着即使在其他地方(即父控制器)的范围内实际设置了属性之前,这种绑定仍然存在。
我怀疑$scope.dummyData
没有正确地从服务器分配返回的数据。
根据您问题中的代码,您在success
请求上调用get
处理程序并将响应返回到result
变量中。但是,您没有提到如何从响应中获取数据。所以,我认为您可能会将.then()
回调的响应与success()
回调混淆:
如果是.success()
回调:
$http.get('/Account/GetDashboardDetails')
.success(function (result) {
$scope.dummyData = result // data exists in the `result` itself
})
如果.then()
成功回调:
$http.get('/Account/GetDashboardDetails')
.then(function (response) {
$scope.dummyData = response.data; // data is wrapped in `data`
})
如果上述情况并非如此,并且您确定已将来自服务器的返回数据正确分配给作用域,则尝试将该部分逻辑包装在$timeout()
中。这会触发$scope.$apply()
并确保$scope.dummyData
中的更改在视图中正确反映。
var DashboardController = function ($scope, $http, $timeout) {
$http.get('/Account/GetDashboardDetails')
.success(function (result) {
$timeout(function(){
/* Do something here */
$scope.dummyData = result;
});
})