2013-07-25 161 views
3

我對使用Primefaces 3.5的Gmap組件的項目有問題我使用的是JSF2.0。 我有做的標記和最重要的更新過濾此命令按鈕mapForm如何使用新標記更新gmap後在primefaces p:gmap中刷新gmap標記

<h:form id="epsFilterForm"> 
     <p:commandButton action="#{mapMB.filterProjects}" value="#{bundle['filter'] }" update=":mapForm" /> 
</h:form> 

mapForm:

<h:form id="mapForm"> 
<p:gmap id="googleMap" center="48.849988,2.3805715" zoom="11" type="TERRAIN" fitBounds="false" model="#{mapMB.advancedModel}" 
    widgetVar="wmap" style="width:1000px;height:700px;display: inline-block;" > 

    <p:ajax event="overlaySelect" listener="#{mapMB.onMarkerSelect}" /> 
    <p:gmapInfoWindow> 
     <p:outputPanel style="text-align:center;display:block;margin:auto:"> 
      <p:panelGrid columns="2" styleClass="InfoTable" > 

       <p:outputLabel value="#{bundle['ep.operation.name'] }" /> 
       <p:outputLabel value="#{mapMB.selectedEp.opName}" /> 
      </p:panelGrid> 
     </p:outputPanel> 
    </p:gmapInfoWindow> 
</p:gmap> 

MapMB - 範圍 - 會話範圍 populateAdvancedModel()

public void populateAdvancedModel(List<EP> eps) { 
    advancedModel = new DefaultMapModel(); 
    int count = 0; 
    Marker marker; 
    for (EP ep :eps) { 
     //advancedModel.addOverlay(new Marker(coord1, "Konyaalti", "konyaalti.png", "http://maps.google.com/mapfiles/ms/micons/blue-dot.png")); 
     System.out.println("Integer.toString(ep.getId()):"+Integer.toString(ep.getId())); 
     marker = new Marker(new LatLng( Double.parseDouble(ep.getLatitude()) , Double.parseDouble(ep.getLongitude()))); 
     marker.setTitle(Integer.toString(count)); 
     advancedModel.addOverlay(marker); 
     count++; 
    } 
} 

filterProjects()

public String filterProjects() { 
    //FilterMB filterMB = (FilterMB) JSFUtil.getManagedObject("filterMB"); 
    eps = EPDAO.filterEPs(client, architect, realizationType, state, selectedCert); 
    populateAdvancedModel(eps); 
    return null; 
} 

onMarkerSelect()

public void onMarkerSelect(OverlaySelectEvent event) { 
    Marker marker = (Marker) event.getOverlay(); 
    String markerTitle = marker.getTitle(); 
    selectedEp = eps.get(Integer.parseInt(markerTitle)); 
} 

當我加載首次一切頁確定。信息(p:gmapInfoWindow)窗口正在加載,EP變量的信息存在。但是,當我點擊epsFilterForm(有一些輸入字段,我沒有發佈在這裏)的命令按鈕時,地圖更新,過濾的標記在那裏,他們顯然有標題,當我懸停在他們,但overlaySelect事件不起作用以同樣的方式。我第一次加載頁面時有一些初始腳本將該行爲放在標記上,但是當我刷新地圖時,這個初始腳本不再運行,這就是爲什麼當我點擊標記並且overlaySelect事件是已解決我在onMarkerSelect()方法中有空指針異常(標記爲空)。 重要 - 這是工作沒有在本地服務器上的問題,但是當我部署到谷歌應用程序引擎它的工作正如我上面所述。

回答

1

與其他Model對象不同,gmap的DefaultMapModel(從p:gmap元素中的'model'屬性引用)沒有適當的功能來清除。 p:schedule的EventModel。

如果您從SessionScoped控制器提供該對象,即使您從頭開始重新創建該對象,由於某種原因,p:gmap仍會引用所提供的第一個mapModel。實際上,這意味着除第一個之外,所有新的/更新的mapmodel對象都沒有被使用。

因此,要更新的gmap(添加/刪除標記,覆蓋等)的一個棘手的問題是應該從RequestScoped對象中檢索mapmodel對象。

現在,另一種選擇是迭代所有標記。你可以找到類似的帖子here。通過這種方式,您可以將後臺bean保留爲SessionScoped,但同樣,您不應創建新的mapModel。

編輯:我得到的印象是視圖無法更新標記,而不是mapModel本身。無論如何,解決方案是一樣的。只是有時候你不能刪除Bean Scope請求(例如在overlaySelect上獲取信息窗口),所以你最終刷新了標記

+0

是的,這正是我解決它的方式。對不起,我沒有更新它。我只是忘了。所以豆: @ ManagedBean @ RequestScoped 公共類MapMB ... 和每次過濾後,我再次使用populateAdvancedModel()方法填充模型。謝謝你的回答 – makkasi

+0

不客氣。如果你認爲這是正確的解決方案,你應該接受答案。 – yannicuLar

0

我使用onGeocode事件,在支持bean中檢查是否有任何加載標記。添加新標記之前刪除這些標記。希望這可以幫助。

public void onGeocode(GeocodeEvent event) { 

    try { 

     List<GeocodeResult> results = event.getResults(); 

     if (results != null && !results.isEmpty()) { 
      LatLng center = results.get(0).getLatLng(); 
      centerGeoMap = center.getLat() + "," + center.getLng(); 

      List<Marker> markers = geoModel.getMarkers(); 

      if (markers != null && markers.size() > 0) { 

       geoModel.getMarkers().removeAll(markers); 
      } 

      for (int i = 0; i < results.size(); i++) { 
       GeocodeResult result = results.get(i); 
       geoModel.addOverlay(new Marker(result.getLatLng(), result.getAddress())); 

      } 
     } 
    } catch (Exception e) { 
     logger.error("Could not update GMap from geoCode", e); 
    } 
} 
0

我也有類似的情況。實際上我想要做的是在gmap渲染後更新gmap中的標記。正如@yannicuLar所說,mapModel在渲染地圖時會在開始時被檢索一次。以後mapModel的更新不會反映在地圖上。

我的解決方案是使用primefaces功能從服務器端觸發執行javascript。

在XHTML:

  var markers = []; 
      function clearMarkers() { 
       for (var i = 0; i &lt; markers.length; i++) { 
         markers[i].setMap(null); 
       } 
       markers=[]; 
      } 
      function addMarkers() { 
       for (var i = 0; i &lt; markers.length; i++) { 
        PF('yourMap').addOverlay(markers[i]); 
        } 
      } 

在java中/服務器端,在那裏你應該更新與緯度/經度您mapModel的地方,您可以添加代碼如下:

要清除標記:

RequestContext.getCurrentInstance().execute("clearMarkers()"); 

假設你有多個標記,所有標記反覆添加到標誌器陣列:

RequestContext.getCurrentInstance().execute("var currentMarker = new google.maps.Marker({ position:new google.maps.LatLng(" 
        + latitude + ", " + longitude 
        + "), map:PF('yourMap').getMap()});" 
        + "markers.push(currentMarker);"); 

要添加標記填充標記陣列後映射:

RequestContext.getCurrentInstance().execute("addMarkers()"); 

據測試,併爲我工作。