过滤地图标记不一致

时间:2016-03-03 16:31:35

标签: javascript google-maps-api-3

我正在尝试通过选择框在地图上过滤标记。

在每个标记数组上,有一个类别对象,其中包含可与用户选择的内容匹配的类别数组。

选择框

<select id="type" onchange="filterMarkers(this.value);">
    <option value="">Please select category</option>
    <option value="red">Red</option>
    <option value="blue">Blue</option>
    <option value="green">Green</option>
     <option value="orange">Orange</option>
</select>

过滤功能

filterMarkers = function (category) {
    for (var i = 0; i < markers1.length; i++) {
        marker = gmarkers1[i];
        for(var j = 0; j < marker.category.length; j++) {
        console.log(marker.category[j]);
          // If is same category or category not picked
          if (marker.category[j] == category || category.length === 0) {
              marker.setVisible(true);
          }
          // Categories don't match 
          else {
              marker.setVisible(false);
          }
        }
    }
}

但在过滤后,它没有显示某些标记,例如绿色类别,而不是红色类别的所有标记都显示

然而,当我在循环中console.log标记变量时,它会返回正确的匹配,但似乎setVisible并没有在所有标记上设置它。

JS小提琴: https://jsfiddle.net/0v7yv6w8/

1 个答案:

答案 0 :(得分:0)

我建议您使用MVCObject而不是循环。 MVCObject是其他类的超类(例如Map,Marker,Polygon,Polyline ......)。 使用MVCObject的方法,您可以非常简单地编写过滤代码。

当值改变时,MVCObject将触发“(key_name)_changed”事件。

例如:

var myObj = new google.maps.MVCObject();
myObj.set("choice", "category1");  // "choice_changed" event will be occurred.
myObj.set("choice", "category2");  // "choice_changed" event will be occurred.

您可以使用addEventListener()监听事件或覆盖changed()方法。

myObj.addListener("choice_changed", function() {
  var choice = myObj.get("choice");
  ...
});

or 

myObj.changed = function(key) {
  var choice = myObj.get(key);
  ...
};
正如我在第一篇中所描述的那样,Marker类继承了这个MVCObject类,你可以做同样的事情。此外,Map类也是。

function createMarker(params) {
  var marker = new google.maps.Marker(params);
  marker.changed = function(key) {
    if (key === 'choice') {
      var choice = marker.get('choice');
      marker.setVisible(choice === params.category); // true or false
    }
  };
  return marker;
}
var marker1 = createMarker({
  position: ...,
  category: "red"
});
var marker2 = createMarker({
  position: ...,
  category: "green"
});

MVCObject有一个非常有用的方法:bindTo()。 此方法绑定指定属性的值。

例如:

var map = new google.maps.Map(...);
map.bindTo('choice', marker1); // marker1.choice = map.choice
map.bindTo('choice', marker2); // marker2.choice = map.choice

map.set('choice', 'green');
console.log(marker1.get('choice'));  // 'green'
console.log(marker2.get('choice'));  // 'green'

实际上,使用此机制,您只需将类别值放入map.choice即可。 您不需要循环所有标记。

对于更紧凑的代码,您可以在createMarker()函数中编写bindTo()方法。

function createMarker(params) {
  var marker = new google.maps.Marker(params);

  params.map.bindTo('choice', marker);

  marker.changed = function(key) {
    if (key === 'choice') {
      var choice = marker.get('choice');
      marker.setVisible(choice === params.category); // true or false
    }
  };
  return marker;
}

这是我之前写过的演示代码。 地图右边有一个侧栏。 你可以改变“Nozomi Shinkansen”,“Hikari Shinkansen”和“Kodama Shinkansen”的类别

http://googlemaps.googlermania.com/google_maps_api_v3/en/map_example_sidebar2.html