谷歌地图/jQuery - 从json文件创建对象



这是谷歌地图的一个笨蛋,它正在工作,但在我度假回来后它不再工作了。但是您仍然可以更多地查看代码 - https://plnkr.co/edit/jHCuVVhGDLwgjNw4bcLr

这是谷歌地图代码:

var map;
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(52.4357808, 4.991315699999973),
zoom: 2,
mapTypeId: google.maps.MapTypeId.TERRAIN
};
map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
}
var seg = {
1: 'investment_cast',
2: 'forged_Prod',
3: 'air_Prod',
5: 'worldwide',
6: 'structurals'
}
var comp = {
1: 'structurals',
2: 'airfoils',
3: 'wyman',
4: 'energy',
5: 'fasteners',
6: 'struc_comp',
7: 'mech_hard',
8: 'engine_prod',
9: 'corp',
10: 'aero',
12: 'timet',
13: 'spec_metals'
}
var myJSON = {};
var myMarkers=[];
$.getJSON("locations.json", function(json1) {
myJSON=json1;
$.each(json1, function(key, data) {
var latLng = new google.maps.LatLng(data.latitude, data.longitude); 
// Creating a marker and putting it on the map
var marker = new google.maps.Marker({
position: latLng
});
myMarkers[key]=marker;
marker.setMap(map);
var infoWindow = new google.maps.InfoWindow();
google.maps.event.addListener(marker, 'click', function() {
if (infoWindow) {infoWindow.close();}
infoWindow = new google.maps.InfoWindow({
content: "<h5>" + data.display_name + "</h5>" +
"<div>" + data.street+ "</div>" +
"<div>" + data.city + ", " + data.state + " &nbsp; " + data.postal_code + "</div>" +
"<div class='mapPhoneNum'>" + data.telephone + "</div>" +
"<a href=" + data.web_url + ">Website</a>"
});
infoWindow.open(map, marker);
map.setZoom(15);
map.panTo(this.getPosition());
google.maps.event.addListener(infoWindow,'closeclick',function(){
resetMapOrigin();
});
});
filterMarkers = function(category){
var component = category.data("component_id");
var segment = category.data("segment_id")
setMapOnAll(null);
resetMapOrigin();
var filteredMarkers=[];
$.each(myJSON, function(key, data) {

if( typeof(component)!="undefined" ){
if( (myJSON[key].component_id == component) && (myJSON[key].segment_id == segment) ){ 
filteredMarkers.push(key);
}
}else{
if( myJSON[key].segment_id == segment ){
filteredMarkers.push(key);
}
}
});
for(i=0;i<filteredMarkers.length;i++){
myMarkers[filteredMarkers[i]].setMap(map);
}
}
function setMapOnAll(map) {
for (var i = 0; i < myMarkers.length; i++) {
myMarkers[i].setMap(map);
}
}
function resetMapOrigin(){
map.setZoom(2);
map.setCenter({lat:52.4357808,lng:4.991315699999973});
}
});
});

所以问题是var seg ={...}var comp ={...}被硬编码到一个对象中。我需要做的是使用$.getJSON(或其他任何可行的方法)从 json 文件中提取该数据(就像我对 locations.json 所做的那样)并像当前1: 'structurals', 2: 'airfoils', and so on的对象一样对其进行格式化(我需要保持这种结构)。

json 文件的格式是这样的 -

组件:

[
{
"id": "1",
"display_name": "structurals"
},
{
"id": "2",
"display_name": "airfoils"
},
{
"id": "3",
"display_name": "wyman"
},
{
"id": "4",
"display_name": "energy"
},
{
"id": "5",
"display_name": "fasteners"
},
{
"id": "6",
"display_name": "struc_comp"
},
{
"id": "7",
"display_name": "mech_hard"
},
{
"id": "8",
"display_name": "engine_prod"
},
{
"id": "9",
"display_name": "corp"
},
{
"id": "10",
"display_name": "aero"
},
{
"id": "12",
"display_name": "timet"
},
{
"id": "13",
"display_name": "spec_metals"
}
]

段:

[
{
"id": "1",
"display_name": "investment_cast"
},
{
"id": "2",
"display_name": "forged_Prod"
},
{
"id": "3",
"display_name": "air_Prod"
},
{
"id": "5",
"display_name": "worldwide"
},
{
"id": "6",
"display_name": "structurals"
}
]

那么,我如何从上面获取这些 JSON 数据并按照与当前格式化"seg 和 comp"对象相同的方式对其进行格式化?(文件名是 components.json 和 segments.json)

提前谢谢。

一种解决方案是循环访问对象数组,并使用每个 id 命名的属性创建另一个对象。这显示了我的意思,假设您已经将 json 获取并解析为一个对象:

var data = 
[
{
"id": "1",
"display_name": "investment_cast"
},
{
"id": "2",
"display_name": "forged_Prod"
},
{
"id": "3",
"display_name": "air_Prod"
},
{
"id": "5",
"display_name": "worldwide"
},
{
"id": "6",
"display_name": "structurals"
}
];

var seg = {};
data.forEach( function(o) {
var x = parseInt(o.id);
seg[x] = o.display_name;
});
console.log(seg);
/*
{ '1': 'investment_cast',
'2': 'forged_Prod',
'3': 'air_Prod',
'5': 'worldwide',
'6': 'structurals' }
*/

实际上在实践中,我可能会使用像 lodash 这样的实用程序库来做到这一点,比如使用 keyBy(): https://lodash.com/docs/4.17.2#keyBy

编辑:keyBy() 不会完全按照你想要的去做,所以忽略那部分。

编辑:此外,如果您要获取 3 个 JSON 文件,则这些是异步操作,因此您可能需要组合这些操作并等待所有 JSON 获取完成。通常,这将通过javascript(或Promise库)中的Promise来完成:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

这是一个包含所需和重构代码更改的触发器工作示例更改scripts.js文件中

解释我的代码:从JSON数据构建所需的segcomp的逻辑是循环遍历结果并从id中挑选数据,并display_namekeyvalue

function formatData(jsonData){
var obj ={};
jsonData.forEach(function(item,index){
var key = parseInt(item.id,10);
obj[key] = item.display_name;
});
return obj;
}

上述功能获取您的json数据,并在对象中返回格式化结果。

接下来,由于您希望在构建谷歌地图之前预先存在所有数据,我会说让我们一个接一个地加载数据,当我们都准备好时,让我们构建地图。

function GetAllDataSetsAndInititateMap() {
$.getJSON("segments.json", function(json) {
seg = formatData(json);
$.getJSON("components.json", function(json) {
comp = formatData(json);
$.getJSON("locations.json", function(json) {
myJSON = json;
BuildMap();
});
});
});
}

有了这些,编写一个名为BuildMap的新函数,并将所有当前存在的代码放在$.getJSON("locations.json", function(json1) {块中。

您的BuildMap函数将如下所示

function BuildMap(){
var json1 = myJSON;
$.each(json1, function(key, data) {
// all the existing code.
});
}

这已经过测试,这是Plunker 更改scripts.js文件中的工作示例。

希望这有帮助!!

对于您的问题:

如何从上面获取此 JSON 数据并按照与当前格式化"seg 和 comp"对象相同的方式对其进行格式化?

您可以将 $.getJSON() 用于其他 json 文件(即 components.json 和 segments.json),就像使用locations.json文件一样。由于这会导致三个异步请求,因此最好等到所有请求都完成。$.getJSON() 返回一个承诺,您可以等到所有承诺都完成,然后再将位置添加到地图。

你可以在所有承诺完成后使用 Promise.all() 运行代码,尽管它不支持 IE。我寻找了一个等效的jQuery函数,并在阅读了这篇提到它的博客文章后找到了$.when(与.done()一起使用)。该技术似乎有效:

$.when($.getJSON("locations.json"), $.getJSON("segments.json"),     
$.getJSON("components.json")).
done(function(locationsResponse, segResponse, compResponse) {
// Each argument is an array with the following structure: [ data, statusText, jqXHR ]
myJSON = locationsResponse[0];
var seg = segResponse[0];
var comp = compResponse[0];
//rest of code to add markers to the map
//...
});

当我查看您的 plunker 示例时,我确实注意到浏览器控制台中出现一个错误:

script.js:79 未捕获的类型错误:类别数据不是函数(...)

这似乎是由调用函数filterMarker的无线电输入并传递字符串值而不是对该输入的 jQuery 选择器的引用引起的(即$(this))。因此,您可以将输入更新为所有传递该引用的内容,并在适当的情况下设置数据component_id和/或数据segment_id。例如,以下行:

<div class="optGroup"><input onclick="filterMarkers($(this));" type="radio" name="loc" value="investment_cast" data-segment_id="2" data-component_id="3" /> Investment Cast Products</div>
<div class="optChild"><input onclick="filterMarkers(this.value);" type="radio" name="loc" value="structurals" /> PCC Structurals</div>
<div class="optChild"><input onclick="filterMarkers(this.value);" type="radio" name="loc" value="airfoils" /> PCC Airfoils</div>

应该像这样更新:

<div class="optGroup"><input onclick="filterMarkers($(this));" type="radio" name="loc" value="investment_cast" data-segment_id="2" data-component_id="3" /> Investment Cast Products</div>
<div class="optChild"><input onclick="filterMarkers($(this));" type="radio" name="loc" value="structurals" data-component_id="1" /> PCC Structurals</div>
<div class="optChild"><input onclick="filterMarkers($(this));" type="radio" name="loc" value="airfoils" data-component_id="2" /> PCC Airfoils</div>

请参阅此更新的 plunker。

最新更新