0

如何强制Google重新绘制其infoWindow或至少刷新其内容? 我注意到,在infoWindow中出现正确的数据之前,我必须在标记上单击两次 - 可能我的闭包是罪魁祸首。强制Google InfoWindow重新绘制自己或刷新其内容

var markers = new Array(); 
    var allMarkers = new Array(); 
    var infoWindow = new google.maps.InfoWindow(); 
    var infoWindows = new Array(); 

    // IE caches ajax request - need a way to clear cache with each fetch of data 
    randomize = function() { 
     var randomnumber = Math.floor(Math.random() * 100000); 
     return randomnumber; 
    } 

    function getBeachLocations() { 
     // construct query 
     var queryURL = "https://www.googleapis.com/fusiontables/v1/query?sql="; 
     var queryTail = "&key=apiKey&callback=?"; 
     var query = "SELECT * FROM BeachTable"; // beach locations tbl 
     var queryText = encodeURI(query); 

     $.ajax({ 
      type: "GET", 
      url: queryURL + queryText + queryTail, 
      cache: false, 
      dataType: 'jsonp', 
      success: createMarkers, 
      error: function() { 
       alert("Sorry, no spatial data is available at this time, please check back on a later date."); 
      } 

     }); 
    } //end getBeachLocations 


    function createMarkers(data) { // =====================create markers 

     url = "http://swim.jpg"; 
     var rows = data['rows']; 
     var ecoli_rows; 
     var algae_rows; 



     for (var m in rows) { 

      var ecoli_array = new Array(); 
      var marker = new google.maps.Marker({ 
       map: map, 
       icon: new google.maps.MarkerImage(url), 
       beach_id: rows[m][0], 
       beach_name: rows[m][1], 
       beach_region: rows[m][2], 
       position: new google.maps.LatLng(rows[m][4], rows[m][5]), 
       idx: m, 
       getHeader: function() { 
        var str = [ 
         '<div style="width:650px;">', 
          '<div class="tabs">', 
           '<ul>', 
            '<li><a href="#tab-1" class="ecoli_tab"><span>E. Coli Data</span></a></li>', 
            '<li><a href="#tab-2" class="algae_data"><span>Algae Data</span></a></li>', 
           '</ul>', 
           '<div id="tab-1">', 
           '<h1>' + this.beach_name + '</h1>', 
           '<h3>' + this.beach_region + '</h3>' 

        ].join(''); 
        return str; 
       }, // end getHeader method 

       getEcoliData: function() { // begin getEcoliData 
        var obj; 
        obj = getEcoliData(this.beach_id); 
        return obj; 
       }, // end getEcoliData method 

       afterGetEcoliData: function (data) { 

        var ecoli_rows; 
        var ecoli_rows_str; 

        ecoli_rows = data['rows']; 

        var ecoli_rows_str = [ 
         '<table id="ecoli_table " class="data" style="width:500px;">', 
         '<tr>', 
          '<th>Sample Date</th>', 
          '<th>Average E. coli Density <br/> (200 cfu/100 ml)</th>', 
          '<th>Recreational Water Quality Guideline</th>', 
         '</tr>' 
        ].join(''); 

        if (typeof ecoli_rows == 'undefined') { 
         ecoli_rows_str = '<p>Sorry no ecoli data currently exists for this beach.</p></div>' 
        } else { 

         for (var i = 0; i < ecoli_rows.length; i++) { 
          //console.log(rows[i]); 
          ecoli_rows_str += '<tr><td>' + formatDate(ecoli_rows[i][2]) + '</td><td>' + checkEcoliCount(ecoli_rows[i][3]) + '</td><td>' + ecoli_rows[i][4] + '</td></tr>'; 
         } 
         ecoli_rows_str += '</table>' 
         ecoli_rows_str += '</div>'; 

         // remove after test 
         ecoli_rows_str += '<div id="tab-2"><h1>nothing loaded</h1></div></div></div>'; 
        } //end if 
        return ecoli_rows_str; 
       }, // end outPutEcoliData method 

       getAlgaeData: function() { // begin getAlgaeData 
        var obj; 

        var algae_rows_str = [ 
          '<div id="tab-2">', 
         '<h1>' + this.beach_name + '</h1>', 
         '<h3>' + this.beach_region + '</h3>', 
         '<table id="algae_table " class="data" style="width:500px;">', 
         '<tr>', 
          '<th>Sample Date</th>', 
          '<th>Algal Toxin Microcystin <br/> (20 ug/L)</th>', 
          '<th>Recreational Water Quality Guideline</th>', 
          '<th>Blue Green Algae Cells <br/>(100,000 cells/ml)</th>', 
          '<th>Recreational Water Quality Guideline</th>', 
         '</tr>' 
        ].join(''); 

        obj = getAlgaeData(this.beach_id); 
        return obj; 


       }, // end getAlgaeData method 

       outPutAlgaeData: function (data) { 
        obj.done(function (data) { 
         algae_rows = data['rows']; 
        }); // end success 


        //console.log(algae_rows); 

        if (typeof algae_rows === 'undefined') { 
         algae_rows_str = [ 
          '<div id="tab-2">', 
           '<h1>' + this.beach_name + '</h1>', 
           '<h3>' + this.beach_region + '</h3>', 
           '<p>Sorry no algae data exists for this beach.</p>', 
          '</div>', 
          '</div>', 
          '</div>', 
          '</div>' 
         ].join(''); 
        } else { 

         for (var i = 0; i < algae_rows.length; i++) { 
          //console.log(rows[i]); 
          algae_rows_str += '<tr><td>' + formatDate(algae_rows[i][2]) + '</td><td>' + checkAlgaeToxinCount(algae_rows[i][3]) + '</td><td>' + algae_rows[i][4] + '</td><td>' + checkAlgaeCount(algae_rows[i][5]) + '</td><td>' + algae_rows[i][6] + '</td></tr>'; 
         } 
         algae_rows_str += '</table>' 
         algae_rows_str += '</div></div></div>'; 
         //return algae_rows_str; 

        } //end if 
        return algae_rows_str; 
       } // end outPutAlgaeData 

      });  // ====================end marker 

      allMarkers.push(marker); //required for drop down menu 

      console.log(marker.beach_id + " " + marker.beach_name); 



      // click event handler 
      google.maps.event.addListener(marker, 'click', function() { 
       var ajaxObj = this.getEcoliData(); 
       var marker = this; 
       var str; 

       // add loading gif 
       //infoWindow.setContent('<img src="../img/loading.gif" alt="loading data"/>'); 

       ajaxObj.done(function (data) { 

        /* 
        str = marker.getHeader() + marker.afterGetEcoliData(data); 
        console.log(str); 
        */ 

        infoWindow.setContent(marker.getHeader() + '' + marker.afterGetEcoliData(data)); 
        infoWindow.open(map, this); 

        $(".tabs").tabs({ selected: 0 }); 
       }); // End done 
      }); // End click event handler 



     } // end for loop foreach marker 

     checkAdvisory(); // determine where this needs to be called from. 
    } //end function createMarkers 

    // format date as January 1, 2013 
    function formatDate(num) { 
     var d = Date.parse(num).toString('MMMM d, yyyy'); 
     return d; 

    } 

    // check ecoli count - anything greater than or equal to 200 cfu/100ml is flagged 
    function checkEcoliCount(num) { 
     var str; 
     num = parseFloat(num); 
     if (num >= 200) { 
      str = '<span class="ecoliCount_on" style="color:orange"><b>' + num + '</b></span>'; 
     } else { 
      return num; 
     } 
     return str; 
    } 

    // check blue green algae count - anything greater than or equal to 100,000 cells/ml is flagged 
    function checkAlgaeCount(num) { 
     var str; 
     num = parseFloat(num); 

     if (num >= 100000) { 
      str = '<span class="algaeCount_on" style="color:orange"><b>' + num + '</b></span>'; 
     } else { 
      return num; 
     } 
     return str; 
    } 

    // check algae toxin microcystin - anything greater than or equal to 20 ug/L is flagged 
    function checkAlgaeToxinCount(num) { 
     // why include < ? - ask Cassie 
     var str; 
     var idx; 

     idx = num.indexOf("<"); 

     num = num.substring(idx + 1); 

     num = parseFloat(num); 

     if (num >= 20) { 
      str = '<span class="algaeToxinCountOn" style="color:orange"><br>' + num + '</b></span>'; 
     } else { 
      return num; 
     } 
     return str; 
    } 

    function checkAdvisory() { 
     /* add advisory images 
     ecoliCount_on 
     algaeCount_on 
     algaeToxinCountOn 
     */ 
     $(".ecoliCount_on").each(function (i, v) { 
      console.log(i, v); 
      $(this).css("color", "green"); 
     }); 
     $(".algaeCount_on").each(function (i, v) { 
      console.log(i, v); 
      $(this).css("color", "green"); 
     }); 
     $(".algaeToxinCountOn").each(function (i, v) { 
      console.log(i, v); 
      $(this).css("color", "green"); 
     }); 
    } 

    function getEcoliData(beach_id) { 
     //console.log(beach_id); 
     var rows; 

     var queryURL = "https://www.googleapis.com/fusiontables/v1/query?sql="; 
     var queryTail = '&key=apiKey&callback=?'; 
     var whereClause = "WHERE 'Beach_ID' = " + beach_id; 
     var query = "SELECT * FROM EcoliTable " 
     + whereClause + " ORDER BY 'Sample_Date' DESC"; 


     var queryText = encodeURI(query); 

     var ecoli_array = new Array(); 

     return $.ajax({ 
      type: "GET", 
      url: queryURL + queryText + queryTail, 
      cache: false, 
      dataType: 'jsonp' 
     }); 
    } 

    function getAlgaeData(beach_id) { 

     var queryURL = "https://www.googleapis.com/fusiontables/v1/query?sql="; 
     var queryTail = '&key=apiKey&callback=?'; 
     var whereClause = " WHERE 'Beach_ID' = " + beach_id; 
     var query = "SELECT * FROM algaeTable " 
     + whereClause + " ORDER BY 'Sample_Date' DESC"; 

     var queryText = encodeURI(query); 

     // ecoli request 
     return $.ajax({ 
      type: "GET", 
      url: queryURL + queryText + queryTail, 
      cache: false, 
      dataType: 'jsonp'  
     }); 
    } 


    // create beach locations dropdown 
    function createDropDownMenu() { 

     var query = 'SELECT Beach_Location, Beach_ID FROM  beachTable ORDER BY Beach_Location ASC'; 

     var queryText = encodeURIComponent(query); 
     var gvizQuery = new google.visualization.Query(
             'http://www.google.com/fusiontables/gvizdata?tq=' + queryText); 

     //Send query and draw table with data in response 
     gvizQuery.send(function (response) { 
      var numRows = response.getDataTable().getNumberOfRows(); 
      var numCols = response.getDataTable().getNumberOfColumns(); 

      var name = ['<label style="font-weight:bolder;font-size:16px"> Select a Beach:</label><select id="beach_menu" style="font-size:16px;" onchange="select_beach(this.options[this.selectedIndex].value);"><option class="defaultopt" value="">--All--</option>']; 

      for (var i = 0; i < numRows; i++) { 

       var nameValue = response.getDataTable().getValue(i, 0); 
       var idValue = response.getDataTable().getValue(i, 1); 




       name.push("<option value=" + "'" + idValue + "'" + ">" + nameValue + "</option>"); 

      } 
      name.push('</select>'); 

      document.getElementById('beach_location_dropdown').innerHTML = name.join(''); 
     }); 

    } // end createDropDownMenu Function 

    function select_beach(val) { 
     $("#beach_menu option[value='" + val + "']").attr('selected', 'selected'); 
     if (val === "") { 
      resetMapExtent(); 
      displayAllBeaches(); 
     } 
     else { 
      update_layer(val) 
     } 
    } // end select_beach function 

    function resetMapExtent() { 
     google.maps.event.trigger(map, "resize"); 
     map.setCenter(new google.maps.LatLng(53.760861, -98.813876)); 
     map.setZoom(5); 
    } // end resetMapExtent function 

    // implement update_layer function 
    function update_layer(beach) { 
     infoWindow.close(); 
     for (var z = 0; z < allMarkers.length; z++) { 
      if (beach === allMarkers[z].beach_id) { 
       allMarkers[z].setVisible(true); 
      } else { 
       // hide all other markers 
       allMarkers[z].setVisible(false); 
      } 
     } 
    } // end update_layer function 

    function displayAllBeaches() { 
     infoWindow.close(); 
     // show all markers 
     for (var z = 0; z < allMarkers.length; z++) { 
      // hide all markers 
      allMarkers[z].setVisible(true); 
     } 
    } // end displayAllBeaches 


    /* start map initialization */ 
    function initialize() { 


     // map 
     latlng = new google.maps.LatLng(49.894634, -97.119141); 
     var myOptions = { 
      center: latlng, 
      zoom: 7, 
      mapTypeId: google.maps.MapTypeId.ROADMAP, 
      zoomControlOptions: { 
       style: google.maps.ZoomControlStyle.SMALL 
      }, 
      mapTypeControl: true, 
      mapTypeControlOptions: { 
       mapTypeIds: [ 
               google.maps.MapTypeId.ROADMAP, 
               google.maps.MapTypeId.SATELLITE, 
               google.maps.MapTypeId.HYBRID, 
               google.maps.MapTypeId.TERRAIN 
              ], 

       style: google.maps.MapTypeControlStyle.DROPDOWN_MENU 
      }, 
      overviewMapControl: true, 
      overviewMapControlOptions: { 
       opened: true 
      } 
     }; 

     map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); 


     // invocation begins here 
     createDropDownMenu(); // not working now. 
     getBeachLocations(); 




     // legend 
     map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(
      document.getElementById('legend')); 

     var legend = document.getElementById('legend'); 
     var swim_icon = "swim.jpg"; 


     var div = document.createElement('div'); 
     div.innerHTML = '<h4>Features</h4>' + 
             '<br/><img src="' + swim_icon + '"> ' + "Beaches"; 
     legend.appendChild(div); 

    } // end initialization function 

    $(function() { 
     $('.view_normal').live('click', function() { 
      $(".container").css("width", "930px").css("margin", "auto"); 
      $(".onewidecenter").css("width", "930px").css("margin", "auto"); 
      $("#map_canvas").css("width", "930px").css("margin", "auto"); 
      google.maps.event.trigger(map, "resize"); 
      map.setCenter(new google.maps.LatLng(53.760861, -98.813876)); 
      map.setZoom(5); 

     }); 
     $('.view_full_screen').live('click', function() { 
      $(".container").css("width", "100%").css("margin", "auto"); 
      $(".onewidecenter").css("width", "100%").css("margin", "auto"); 
      $("#map_canvas").css("width", "100%").css("margin", "auto"); 
      $(" #dropdown_container").css("width", "100%").css("margin", "auto"); 
      google.maps.event.trigger(map, "resize"); 
      map.setCenter(new google.maps.LatLng(53.760861, -98.813876)); 
      map.setZoom(5); 
     }); 
    }); // end page load 

我已经包含上面的示例代码。请特别注意我的点击事件处理程序。与往常一样,建议如何最好地解决这个问题将不胜感激。

由于提前, 迈克尔

回答

2

的jQuery AJAX方法是异步的。这意味着:立即

obj.success(function (data) { 
    ecoli_rows = data['rows']; 
}); // end sucess 

回报,但回调函数不运行,直到AJAX请求完成。

这意味着:

infoWindow.setContent(this.getHeader() + '' + 
    this.getEcoliData() + '' + this.getAlgaeData()); 
infoWindow.open(map, this); //ajax callback hasn't fired here 

打开信息窗口的内容之前的AJAX请求完成。

要纠正,你可能会做这样的事情:

在marker.getEcoliData:

obj = getEcoliData(this.beach_id); 
return obj; 
// move processing below this point to new method 

并且在Click事件处理程序:

google.maps.event.addListener(marker, 'click', function() { 
    var ajaxObj = this.getEcoliData(); 
    var marker = this; 
    ajaxObj.done(function() { 
    infoWindow.setContent(marker.getHeader() + '' + 
     marker.afterGetEcoliData() + '' + 
     this.getAlgaeData()); 
    infoWindow.open(map, this); 
    $(".tabs").tabs({ selected: 0 }); 
    }); 

这不是一个完整的解决方案因为你有两个异步调用发生。你可以链接它们,或者设置某种计数器来确保只有在两者都完成时才执行回调。

更好的方法是立即打开信息窗口,告诉用户数据正在被加载。然后,请求完成后,您只需再次更新infowindow内容(使用内容元素的句柄)以显示返回的数据。

+0

我认为,因为我在变量名称空间内包装了ajax调用,所以我推迟了内容的渲染。有没有简单的方法来纠正?我不确定如何最好地实现这一点?欢迎任何建议。在此先感谢, – Michael

+0

会设置超时做诀窍?例如,google.maps.event.addListener(marker,'click',function(){this.getHeader()+''+ this.getEcoliData()+''+ this.getAlgaeData()) ; //破解 - 延迟开盘的信息窗口,直到所有的Ajax数据加载 的setTimeout(函数(){ infoWindow.open(地图,这一点);} ,2000); $( “标签”)的标签( {selected:0}); }); – Michael

+0

超时将不可靠。我已经用一些指导更新了我的答案。 –

0

感谢您的帮助。我设法让这个按预期工作。事实证明,我不得不重新构造标记类,以便两个Ajax请求不会被返回额外的时间。