0

我用 JSON 数据填充了谷歌地图,我有一些复选框来选择要在地图上显示的数据类别。当我单击复选框时,它通过 Ajax 调用新的 JSON 数据,当我取消选中一个框时,它会在所有标记的数组上循环并删除所有未选中类别的标记。

它在大多数情况下都有效,但有时标记会消失并再次出现。看来他们还是在数组里什么的……

$( "input[type=checkbox]" ).change(function() {
        var data ='';
        var checkbox = $(this);
        var checkboxVal = $(this).val();
        console.log('click');

        if (checkbox.is(':checked')) {
            $('.loader').show();

            $("input:checkbox[name=poi_categories]:checked").each(function() {
                data = data + checkboxVal + ',';
                $.ajax({
                    type: "POST",
                    url: window.location.pathname,
                    data: "categorie=" + data,
                    success:function(response){

                        json = JSON.parse(response);

                        for (var i = 0; i < json.length; i++) {
                            createMarker(json[i], data);
                        }
                        $('.loader').hide();
                    }
                });
            });
        } else {

            for (var i in markersArray) {
                if ( markersArray[i] != undefined) {
                    if( null == markersArray[i].cat || markersArray[i].cat == checkboxVal) {
                        markersArray[i].setMap(null);
                        delete(markersArray[i]);
                    }
                }
            }
        } 
    });

我很确定最后一个 for 循环中有一个错误,但我看不出是什么......

编辑 :

这是整个 Js 代码:http: //jsfiddle.net/5bMQm/

4

3 回答 3

1

编辑:我明白你现在想要做什么。

for (var i = 0, l = markersArray.length; i < l; i++) {
  if ( markersArray[i] != undefined) {
    if( null == markersArray[i].cat || markersArray[i].cat == checkboxVal) {
      markersArray[i].setMap(null);
      markersArray.splice(i, 1);
      i--; l--;
    }
  }
}
于 2013-09-30T13:20:58.583 回答
1

完全被误解了。您多次执行此操作,每次用户单击复选框时 - 这就是为什么您还想从标记数组中删除从地图中删除的标记。

认为我找到了根本问题。

你有

createMarker(json[i], data);

但只有

function createMarker(marker) {

你设置

cat : marker.img

但与

markersArray[i].cat == checkboxVal

你假设(我猜)应该包含

var checkboxVal = $(this).val();
..
data = data + checkboxVal + ',';

但从来没有!data / checkboxval 永远不会分配给您的标记!


for (var i in markersArray) {
    if ( markersArray[i] != undefined) {
        if( null == markersArray[i].cat || markersArray[i].cat == checkboxVal) {
            markersArray[i].setMap(null);
            markersArray[i] = undefined; // <---
        }
    }
}
//cleanup
for (var i=markersArray.length;i>0;i--) {
    if (markersArray[i]==undefined]) {
        markersArray.splice(i, 1);
    }
}
于 2013-09-30T13:51:43.530 回答
0

它在大多数情况下都有效,但有时标记会消失并再次出现。看来他们还是在数组什么的

当一切都按预期工作时,您的代码按预期对我有用。

但是问题(假设您的服务器端脚本的返回响应始终正确):

您不能期望 AJAX 响应的到达顺序与它们发送的顺序相同(有时单个请求可能会有很大的延迟)。例如,您可能会发生

  1. 单击一个框以检查它
  2. 再次单击该框以取消选中它

当响应以相反的顺序到达时,您将创建标记,尽管当前未选中该框。

可能的解决方案:(但有一个更好的,见下文)

在开头添加一个额外的检查createMarker

if(!$('input[type="checkbox"][name="poi_categories"][value="'+marker.img+'"]').is(':checked'))return;

另一个问题:您的脚本中似乎有一个多余的部分,

$("input:checkbox[name=poi_categories]:checked").each(function() {
  /*ajax-code*/
});

这对我来说没有任何意义,假设您已经检查了 5 个复选框并且最后点击的复选框的值为例如“hotel”,您将发送categories=hotel,hotel,hotel,hotel,hotel,我认为您的服务器端脚本不会为此返回任何标记。您根本不需要遍历选中的标记。

这应该足够了:

if (checkbox.is(':checked')) {
                $('.loader').show();

                    $.ajax({
                        type: "POST",
                        url: window.location.pathname,
                        data: "categorie=" + checkboxVal,
                        success:function(response){

                            json = JSON.parse(response);

                            for (var i = 0; i < json.length; i++) {
                                createMarker(json[i], data);
                            }

                            $('.loader').hide();
                        }
                    });

            }

这是避免主要问题的更好解决方案的好点。与其在创建标记之前检查复选框的选中属性,不如中止最近的请求:

    var checkbox = $(this);
    var checkboxVal = $(this).val();
    console.log('click');
    //if there has been a recent request, abort it
    if(checkbox.data('xhr')){
        checkbox.data('xhr').abort();console.log('recent request aborted');
    }
    if (checkbox.is(':checked')) {
        $('.loader').show();

            data = data + checkboxVal + ',';
            //store the jqXhr within the checkbox-data
            //to be able to abort it later
            checkbox.data('xhr',$.ajax({
                type: "POST",
                url: window.location.pathname,
                data: "categorie=" + checkboxVal,
                success:function(response){

                    json = JSON.parse(response);

                    for (var i = 0; i < json.length; i++) {
                        createMarker(json[i], data);
                    }

                    $('.loader').hide();
                }
            }));

    } else {/* your code*/}
于 2013-09-30T17:26:17.017 回答