2012-09-10 94 views
1

我正在開發一個使用JSF2和Primefaces作爲WebFrameworks的Java Web應用程序。我的應用程序旨在管理相機。所有關於相機的數據都存儲在PostgreSQL數據庫中。
我有一個JSF視圖,其中使用Leaflet的JavaScript API顯示動態地圖。 您可以通過以下鏈接查看此類地圖的示例:Leaflet example。總結一下,我的地圖旨在顯示攝像機的標記。標記的位置是使用相機的屬性生成的。
我已經創建了一個複合組件和它的Backing Bean來處理地圖。下面是這個視圖的源代碼:
JSF 2.0:複合組件屬性從Backing Bean初始化問題

<h:body> 
    <!-- INTERFACE --> 
    <composite:interface componentType="mapComponent"> 
    </composite:interface> 

    <!-- IMPLEMENTATION --> 
    <composite:implementation> 
     <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 
     <link rel="stylesheet" href="#{resource['css:leaflet.css']}" /> 
     <!--[if lte IE 8]><link rel="stylesheet" href="#{resource['css:leaflet.ie.css']}" /><![endif]--> 
     <script 
      src="#{resource['js:leaflet/Leaflet-v0.4.4-0/dist/leaflet-src.js']}"></script> 
     <script 
      src="#{resource['js:leaflet/Leaflet-v0.4.4-0/src/leafclusterer.js']}"></script> 

     <div id="#{cc.mapId}" style="width: 520px; height: 580px" /> 

     <script type="text/javascript"> 
     //<![CDATA[ 
      var clusterPopup; 

      function onClustererClick(cluster, coordinates) { 
       var markers = cluster.getMarkers; 
       var popupContent = "<p>"; 
       for (var i = 0; i < cluster.getCluster().getMarkers().length; i++) { 
        var currentMarker = cluster.getCluster().getMarkers()[i]; 
        popupContent += currentMarker.marker._popup._content 
        popupContent += "<br/>"; 
       } 
       popupContent += "</p>"; 
       clusterPopup = new L.Popup(); 
       clusterPopup.setLatLng(coordinates); 
       clusterPopup.setContent(popupContent); 
       map.openPopup(clusterPopup); 
      }; 

      var cameraIcon = L.icon({ 
       iconUrl : "#{resource['img:leaflet/camera.png']}", 

       iconSize : [ 48, 48 ], 
       shadowSize : [ 48, 48 ], 
       iconAnchor : [ 30, 30 ], 
       popupAnchor : [ 0, -20 ] 
      }); 

      var marker; 
      function onMapClick(e) { 
       marker = new L.marker(e.latlng, { 
        draggable : true, 
        icon : cameraIcon 
       }); 
       map.addLayer(marker); 
       marker.bindPopup("<b>Hello world!</b><br />I am a popup."); 
       map.off('click'); 
      }; 

      var osmUrl = '#{cc.osmUrl}'; 
      var osmAttrib = '#{cc.osmAttrib}'; 

      var basic = new L.tileLayer(osmUrl, { 
       minZoom : #{cc.minZoom}, 
       maxZoom : #{cc.maxZoom}, 
       attribution : osmAttrib 
      }); 

      var map = new L.Map('#{cc.mapId}', { 
       center : new L.LatLng(#{cc.mapX}, #{cc.mapY}), 
       zoom : #{cc.mapDefaultZoom}, 
       layers : [ basic ] 
      }); 

      var baseMaps = { 
       "#{cc.mapBasicLayerName}" : basic 
      }; 

      if(#{cc.mapEnableOnClick}) { 
       map.on('click', onMapClick); 
      } 

      var clusterer = new LeafClusterer(map); 
     //]]> 
     </script> 
     <composite:insertChildren /> 
    </composite:implementation> 
</h:body> 
</html> 

這裏是我支持bean的代碼:

@FacesComponent(value = "mapComponent") 
public class MapComponent extends UINamingContainer { 

private static final String MAP_ID_PROP = "map_id"; 
private static final String OSM_URL_PROP = "osm_url"; 
private static final String OSM_ATTRIB_PROP = "osm_attrib"; 
private static final String MIN_ZOOM_PROP = "min_zoom"; 
private static final String MAX_ZOOM_PROP = "max_zoom"; 
private static final String MAP_X_PROP = "map_x"; 
private static final String MAP_Y_PROP = "map_y"; 
private static final String MAP_DEFAULT_ZOOM_PROP = "map_default_zoom"; 
private static final String MAP_BASIC_LAYER_NAME_PROP = "map_basic_layer_name"; 
private static final String MAP_ENABLE_ON_CLICK_PROP = "map_enable_on_click"; 

private String mapId; 
private String osmUrl; 
private String osmAttrib; 
private Integer minZoom; 
private Integer maxZoom; 
private Double mapX; 
private Double mapY; 
private Integer mapDefaultZoom; 
private String mapBasicLayerName; 
private Boolean mapEnableOnClick; 

/** 
* Instanties un nouveau map component. 
*/ 
public MapComponent() { 
    super(); 
    mapId = (String) AppUtil.getProperty(MAP_ID_PROP); 
    osmUrl = (String) AppUtil.getProperty(OSM_URL_PROP); 
    osmAttrib = (String) AppUtil.getProperty(OSM_ATTRIB_PROP); 
    minZoom = Integer.parseInt((String) AppUtil.getProperty(MIN_ZOOM_PROP)); 
    maxZoom = Integer.parseInt((String) AppUtil.getProperty(MAX_ZOOM_PROP)); 
    mapX = Double.parseDouble((String) AppUtil.getProperty(MAP_X_PROP)); 
    mapY = Double.parseDouble((String) AppUtil.getProperty(MAP_Y_PROP)); 
    mapDefaultZoom = Integer.parseInt((String) AppUtil.getProperty(MAP_DEFAULT_ZOOM_PROP)); 
    mapBasicLayerName = (String) AppUtil.getProperty(MAP_BASIC_LAYER_NAME_PROP); 
    setMapEnableOnClick(Boolean.parseBoolean((String) AppUtil.getProperty(MAP_ENABLE_ON_CLICK_PROP))); 
} 

/** 
* Getter : retourne le map id. 
* 
* @return le map id 
*/ 
public String getMapId() { 
    return mapId; 
} 

/** 
* Getter : retourne le osm url. 
* 
* @return le osm url 
*/ 
public String getOsmUrl() { 
    return osmUrl; 
} 

/** 
* Getter : retourne le osm attrib. 
* 
* @return le osm attrib 
*/ 
public String getOsmAttrib() { 
    return osmAttrib; 
} 

/** 
* Getter : retourne le min zoom. 
* 
* @return le min zoom 
*/ 
public Integer getMinZoom() { 
    return minZoom; 
} 

/** 
* Getter : retourne le max zoom. 
* 
* @return le max zoom 
*/ 
public Integer getMaxZoom() { 
    return maxZoom; 
} 

/** 
* Getter : retourne le map x. 
* 
* @return le map x 
*/ 
public Double getMapX() { 
    return mapX; 
} 

/** 
* Getter : retourne le map y. 
* 
* @return le map y 
*/ 
public Double getMapY() { 
    return mapY; 
} 

/** 
* Getter : retourne le map default zoom. 
* 
* @return le map default zoom 
*/ 
public Integer getMapDefaultZoom() { 
    return mapDefaultZoom; 
} 

/** 
* Getter : retourne le map basic layer name. 
* 
* @return le map basic layer name 
*/ 
public String getMapBasicLayerName() { 
    return mapBasicLayerName; 
} 

/** 
* Setter : affecte le map id. 
* 
* @param mapId le map id 
*/ 
public void setMapId(String mapId) { 
    this.mapId = mapId; 
} 

/** 
* Setter : affecte le osm url. 
* 
* @param osmUrl le osm url 
*/ 
public void setOsmUrl(String osmUrl) { 
    this.osmUrl = osmUrl; 
} 

/** 
* Setter : affecte le osm attrib. 
* 
* @param osmAttrib le osm attrib 
*/ 
public void setOsmAttrib(String osmAttrib) { 
    this.osmAttrib = osmAttrib; 
} 

/** 
* Setter : affecte le min zoom. 
* 
* @param minZoom le min zoom 
*/ 
public void setMinZoom(Integer minZoom) { 
    this.minZoom = minZoom; 
} 

/** 
* Setter : affecte le max zoom. 
* 
* @param maxZoom le max zoom 
*/ 
public void setMaxZoom(Integer maxZoom) { 
    this.maxZoom = maxZoom; 
} 

/** 
* Setter : affecte le map x. 
* 
* @param mapX le map x 
*/ 
public void setMapX(Double mapX) { 
    this.mapX = mapX; 
} 

/** 
* Setter : affecte le map y. 
* 
* @param mapY le map y 
*/ 
public void setMapY(Double mapY) { 
    this.mapY = mapY; 
} 

/** 
* Setter : affecte le map default zoom. 
* 
* @param mapDefaultZoom le map default zoom 
*/ 
public void setMapDefaultZoom(Integer mapDefaultZoom) { 
    this.mapDefaultZoom = mapDefaultZoom; 
} 

/** 
* Setter : affecte le map basic layer name. 
* 
* @param mapBasicLayerName le map basic layer name 
*/ 
public void setMapBasicLayerName(String mapBasicLayerName) { 
    this.mapBasicLayerName = mapBasicLayerName; 
} 

/** 
* Getter : retourne le map enable on click. 
* 
* @return le map enable on click 
*/ 
public Boolean getMapEnableOnClick() { 
    return mapEnableOnClick; 
} 

/** 
* Setter : affecte le map enable on click. 
* 
* @param mapEnableOnClick le map enable on click 
*/ 
public void setMapEnableOnClick(Boolean mapEnableOnClick) { 
    this.mapEnableOnClick = mapEnableOnClick; 
} 

}

來管理我的成分,我也創建了一個支持bean 。這裏是XHTML來源:

<h:body> 
    <!-- INTERFACE --> 
    <composite:interface componentType="mapMarker"> 
     <composite:attribute name="longitude" type="java.lang.Float" /> 
     <composite:attribute name="latitude" type="java.lang.Float" /> 
     <composite:attribute name="padding" type="java.lang.Integer" /> 
     <composite:attribute name="popUpContent" type="java.lang.String" /> 
     <composite:attribute name="maxZoom" type="java.lang.Integer" /> 
    </composite:interface> 

    <!-- IMPLEMENTATION --> 
    <composite:implementation> 

     <script type="text/javascript"> 
      //   
      function onPopupClick(padding, lat, lng) { 
       map.closePopup(clusterPopup); 

       if(map.getZoom() &lt; #{cc.maxZoom}) { 
        var pos = map.latLngToLayerPoint(new L.LatLng(#{cc.latitude}, #{cc.longitude})); 
        var sw = new L.point(pos.x - padding, pos.y + padding); 
        sw = map.layerPointToLatLng(sw); 
        var ne = new L.point(pos.x + padding, pos.y - padding); 
        ne = map.layerPointToLatLng(ne); 
        map.setView(new L.LatLng(lat, lng), #{cc.maxZoom}); 
       } 
      }; 

      marker = new L.marker([#{cc.latitude}, #{cc.longitude}], { 
        draggable : true, 
        icon : cameraIcon 
      }); 
      var popUpContent = '<span style="cursor:pointer;" id="#{cc.id}Link" onclick="onPopupClick(#{cc.padding},' + #{cc.latitude} + ',' + #{cc.longitude} + ')">#{cc.popUpContent}</span>'; 
      marker.bindPopup(popUpContent); 

      clusterer.addMarker(marker); 
     </script> 

    </composite:implementation> 
</h:body> 

這裏是我支持bean的源代碼:按文件包含默認值讀取性能

@FacesComponent(value = "mapMarker") 
public class MapMarker extends UINamingContainer { 

    private static final String PADDING_PROP = "padding"; 
    private static final String MAX_ZOOM_MARKER_PROP = "max_zoom_marker"; 

    private Float longitude; 
    private Float latitude; 
    private String popUpContent; 
    private Integer padding; 
    private Integer maxZoom; 

    public MapMarker() { 
     padding = Integer.parseInt((String) AppUtil.getProperty(PADDING_PROP)); 
     maxZoom = Integer.parseInt((String) AppUtil.getProperty(MAX_ZOOM_MARKER_PROP)); 
    } 

    public Float getLongitude() { 
     return longitude; 
    } 

    public void setLongitude(Float longitude) { 
     this.longitude = longitude; 
    } 

    public Float getLatitude() { 
     return latitude; 
    } 

    public void setLatitude(Float latitude) { 
     this.latitude = latitude; 
    } 

    public String getPopUpContent() { 
     return popUpContent; 
    } 

    public void setPopUpContent(String popUpContent) { 
     this.popUpContent = popUpContent; 
    } 

    public Integer getPadding() { 
     return padding; 
    } 

    public void setPadding(Integer padding) { 
     this.padding = padding; 
    } 

    public Integer getMaxZoom() { 
     return maxZoom; 
    } 

    public void setMaxZoom(Integer maxZoom) { 
     this.maxZoom = maxZoom; 
    } 

} 

組件設置其屬性。 下面是該文件的內容:

# Cartographie OpenStreetMap 
map_id=map 
osm_attrib=test 
min_zoom=1 
max_zoom=13 
map_x=48.227 
map_y=6.611 
map_default_zoom=8 
map_basic_layer_name=Basique 
map_enable_on_click=true 
# Cartographie OpenStreetMap 

# Marqueur de caméra 
padding=20 
max_zoom_marker=11 
# Marqueur de caméra 

我有一顆豆「ConsultationBean」是處理包含地圖的視圖。這個bean使用一個服務來存儲一個ArrayList,包含在數據庫中的所有相機。在視圖中,我通過prerenderView evet調用init方法,該方法使用攝像機列表創建所有MapMarker。這裏是XHTML代碼:

<ui:composition template="/xhtml/common/layout.xhtml"> 
    <ui:define name="headTitle"> 
     <h:outputText value="#Cartographie#" /> 
    </ui:define> 

    <ui:define name="header"> 
     <ui:include src="/xhtml/common/header.xhtml"> 
      <ui:param name="headerClass" value="banner-thin" /> 
     </ui:include> 
    </ui:define> 

    <ui:define name="content"> 
     <f:metadata> 
      <f:event type="preRenderView" listener="#{consultationBean.init}" 
       update="content,mapPanelGroup"></f:event> 
     </f:metadata> 
     <div id="content" class="content-home ui-corner-bottom"> 

      <h2 class="main-title content-title light-bg light-bordered-top"> 
       <h:outputText value="#Cartographie#" /> 
      </h2> 
      <h:panelGroup id="mapPanelGroup"> 
       <util:map id="mapContainer"> 
        <ui:repeat var="marker" value="#{consultationBean.markers}"> 
         <util:mapMarker/> 
        </ui:repeat> 
       </util:map> 
      </h:panelGroup> 
     </div> 
    </ui:define> 
</ui:composition> 
</html> 

這裏是支持bean的源代碼:

/** 
* Le Class ConsultationBean. 
*/ 
@Controller 
@Scope("view") 
@SuppressWarnings("serial") 
public class ConsultationBean implements Serializable { 

/** La constante LOGGER. */ 
private static final Logger LOGGER = Logger.getLogger(ConsultationBean.class); 

/** Le cameras. */ 
private List<Camera> cameras; 

/** Le map. */ 
private UINamingContainer map; 

/** Le markers. */ 
private List<MapMarker> markers; 

/** Le camera service. */ 
@Autowired 
private CameraService cameraService; 

/** 
* Initialise le. 
*/ 
public void init() { 
    cameras = cameraService.findAll(); 
    map = (UINamingContainer) FacesUtils.findComponentById(FacesContext.getCurrentInstance(), "mapContainer"); 
    initMarkers(); 
} 

/** 
* Initialise le markers. 
*/ 
public void initMarkers() { 
    markers = new ArrayList<MapMarker>(); 

    for (Camera camera : cameras) { 
     MapMarker mapMarker = new MapMarker(); 
     mapMarker.setLatitude(camera.getY()); 
     mapMarker.setLongitude(camera.getX()); 
     mapMarker.setPopUpContent(camera.toString()); 
     markers.add(mapMarker); 
     map.getChildren().add(mapMarker); 
     map.getChildren().add(new HtmlInputText()); 
    } 
} 

/** 
* Getter : retourne le markers. 
* 
* @return le markers 
*/ 
public List<MapMarker> getMarkers() { 
    return markers; 
} 

/** 
* Setter : affecte le markers. 
* 
* @param markers le markers 
*/ 
public void setMarkers(List<MapMarker> markers) { 
    this.markers = markers; 
} 

}

我的問題是,我需要爲我設置屬性到MapMarker的默認構造函數。例如,通過使用follogwing默認的構造函數,我的標記會在完全相同的點在地圖上顯示:

public MapMarker() { 
     padding = Integer.parseInt((String) AppUtil.getProperty(PADDING_PROP)); 
     maxZoom = Integer.parseInt((String) AppUtil.getProperty(MAX_ZOOM_MARKER_PROP)); 
     latitude = (float) 47.67876; 
     longitude = (float) 6.97061; 
    } 

我想要做的就是讓我的「初始化」方法從「ConsultationBean」高效的感覺它像默認構造函數一樣初始化標記的屬性。我必須使用「init」方法,因爲它是我使用我的相機列表的地方。
也許我應該重新渲染視圖,這就是爲什麼我使用preRender事件的更新屬性的原因,但它不起作用。

如果有人有一個想法來解決這個問題...

在此先感謝。

更新1:

的 「初始化」 由 「ConsultationBean」 的方法是效率不高。事實上,我創建了「MapMarker」並將它們添加到地圖中,但它們從未出現在視圖中。然而,這些由視圖生成包含在視圖中的標誌和VI的「UI:重複」標籤:

   <ui:repeat var="marker" value="#{consultationBean.markers}"> 
        <util:mapMarker/> 
       </ui:repeat> 

我發現我的MapMarkers是在「ConsultationBean」之前建造的。因此,我的相機列表和標記列表是空的,但生成的標記數量與存儲在數據庫中的相機數量相同。

我試圖把一個ID標記以「#{camera.code}#作爲一個值,用下面的代碼:

   <ui:repeat var="camera" value="#{consultationBean.cameras}"> 
        <util:mapMarker id="#{camera.code}"/> 
       </ui:repeat> 

不幸的是它失敗了,因爲列表是空的。我真的堅持我的生成標記的方式

+2

請不要發佈完整的課程和完整的代碼頁。 Ommit getter/setters,包聲明,導入等。這會影響可讀性,並且完全不相關。請發佈代碼**的簡短**示例,以說明您的問題,這也在常見問題解答中說明。 – siebz0r

回答

0

試試這個:

@Override 
public void encodeBegin(FacesContext context) throws IOException{ 
    padding = Integer.parseInt((String) AppUtil.getProperty(PADDING_PROP)); 
    maxZoom = Integer.parseInt((String) AppUtil.getProperty(MAX_ZOOM_MARKER_PROP)); 
    latitude = (float) 47.67876; 
    longitude = (float) 6.97061; 
    super.encodeBegin(context); 
} 
+0

作爲示例,在構造函數中設置了緯度和經度值。我已經通過將「padding」屬性設置爲「55」來嘗試你的方法,當我用Firebug查看視圖的源代碼時,它的值是55。因此,「encodeBegin」方法適用於更新已經構建的組件,但我想要做的是使用我在init方法中傳遞給組件的值執行相同的操作。 從「ConsultationBean」我的「init」方法也是錯誤的,因爲我創建了視圖從不顯示的其他「MarkerComponent」。 – user1194442

1

我終於找到了解決辦法 我所做的是,我已經添加了其它附加。組件添加到名爲「MapMarkersContainer」的視圖中。該組件包含攝像機列表,該列表在MapMarker的「encodeBegin」被調用之前填充。 我修改了「MapMarker」的「encodeBegin」,以便通過「MapMarkersContainer」列表獲取所有相機信息。

<h:body> 
    <!-- INTERFACE --> 
    <composite:interface componentType="mapMarkersContainer"> 
     <composite:attribute name="cameras" type="java.util.List" /> 
    </composite:interface> 

    <!-- IMPLEMENTATION --> 
    <composite:implementation> 

    </composite:implementation> 
</h:body> 
</html> 

下面是支持bean的源代碼:

@FacesComponent(value = "mapMarkersContainer") 
public class MapMarkersContainer extends UINamingContainer { 
    private List<Camera> cameras; 

    private Integer currentIndex = 0; 

    public List<Camera> getCameras() { 
     currentIndex++; 
     return cameras; 
    } 

    public void setCameras(List<Camera> cameras) { 
     this.cameras = cameras; 
    } 

    public Integer getCurrentIndex() { 
     return currentIndex; 
    } 

    public void setCurrentIndex(Integer currentIndex) { 
     this.currentIndex = currentIndex; 
    } 
} 

這是發生在 「MapMarker」 的修改:

@FacesComponent(value = "mapMarker") 
public class MapMarker extends UINamingContainer { 

    private static final String PADDING_PROP = "padding"; 
    private static final String MAX_ZOOM_MARKER_PROP = "max_zoom_marker"; 

    private Float longitude; 
    private Float latitude; 
    private String popUpContent; 
    private Integer padding; 
    private Integer maxZoom; 
    private Camera camera; 

    public MapMarker() { 
     padding = Integer.parseInt((String) AppUtil.getProperty(PADDING_PROP)); 
     maxZoom = Integer.parseInt((String) AppUtil.getProperty(MAX_ZOOM_MARKER_PROP)); 
    } 

    @Override 
    public void encodeBegin(FacesContext context) throws IOException { 
     padding = Integer.parseInt((String) AppUtil.getProperty(PADDING_PROP)); 
     maxZoom = Integer.parseInt((String) AppUtil.getProperty(MAX_ZOOM_MARKER_PROP)); 
     MapMarkersContainer mapMarkersContainer = (MapMarkersContainer) FacesUtils.findComponentById(context, 
       "mapMarkersContainer"); 
     Integer cameraIndex = mapMarkersContainer.getCurrentIndex(); 
     Camera camera = mapMarkersContainer.getCameras().get(cameraIndex); 
     latitude = camera.getY(); 
     longitude = camera.getX(); 
     popUpContent = camera.toString(); 
     setId(camera.getNom()); 
     super.encodeBegin(context); 
    } 

    public Float getLongitude() { 
     return longitude; 
    } 

    public void setLongitude(Float longitude) { 
     this.longitude = longitude; 
    } 

    public Float getLatitude() { 
     return latitude; 
    } 

    public void setLatitude(Float latitude) { 
     this.latitude = latitude; 
    } 

    public String getPopUpContent() { 
     return popUpContent; 
    } 

    public void setPopUpContent(String popUpContent) { 
     this.popUpContent = popUpContent; 
    } 

    public Integer getPadding() { 
     return padding; 
    } 

    public void setPadding(Integer padding) { 
     this.padding = padding; 
    } 

    public Integer getMaxZoom() { 
     return maxZoom; 
    } 

    public void setMaxZoom(Integer maxZoom) { 
     this.maxZoom = maxZoom; 
    } 

    public Camera getCamera() { 
     return camera; 
    } 

    public void setCamera(Camera camera) { 
     this.camera = camera; 
    } 

} 

,這裏是在「ConsultationBean發生了什麼變化「查看:

<ui:composition template="/xhtml/common/layout.xhtml"> 
    <ui:define name="headTitle"> 
     <h:outputText value="#Cartographie#" /> 
    </ui:define> 

    <ui:define name="header"> 
     <ui:include src="/xhtml/common/header.xhtml"> 
      <ui:param name="headerClass" value="banner-thin" /> 
     </ui:include> 
    </ui:define> 

    <ui:define name="content"> 

     <util:mapMarkersContainer id="mapMarkersContainer"/> 
     <div id="content" class="content-home ui-corner-bottom"> 

      <h2 class="main-title content-title light-bg light-bordered-top"> 
       <h:outputText value="#Cartographie#" /> 
      </h2> 
      <h:panelGroup id="mapPanelGroup"> 
       <util:map id="mapContainer"> 
        <ui:repeat id="repeat" var="camera" value="#{consultationBean.cameras}"> 
         <util:mapMarker/> 
        </ui:repeat> 
       </util:map> 
      </h:panelGroup> 
     </div> 
    </ui:define> 
</ui:composition> 
</html> 

這裏是「ConsultationBean」的Java源代碼:

/** 
* Le Class ConsultationBean. 
*/ 
@Controller 
@Scope("view") 
@SuppressWarnings("serial") 
public class ConsultationBean implements Serializable { 

    /** Le cameras. */ 
    private List<Camera> cameras; 

    /** Le markers. */ 
    private List<MapMarker> markers; 

    private MapMarkersContainer mapMarkersContainer; 

    /** Le camera service. */ 
    @Autowired 
    private CameraService cameraService; 

    /** 
    * Initialise le. 
    * 
    * @throws IOException 
    */ 
    @PostConstruct 
    public void init() throws IOException { 
     cameras = cameraService.findAll(); 
     mapMarkersContainer = (MapMarkersContainer) FacesUtils.findComponentById(FacesContext.getCurrentInstance(), 
       "mapMarkersContainer"); 
     mapMarkersContainer.setCameras(cameras); 
    } 

    /** 
    * Getter : retourne le markers. 
    * 
    * @return le markers 
    */ 
    public List<MapMarker> getMarkers() { 
     return markers; 
    } 

    /** 
    * Setter : affecte le markers. 
    * 
    * @param markers le markers 
    */ 
    public void setMarkers(List<MapMarker> markers) { 
     this.markers = markers; 
    } 

    public List<Camera> getCameras() { 
     return cameras; 
    } 

    public void setCameras(List<Camera> cameras) { 
     this.cameras = cameras; 
    } 
} 

現在,每個標記已經是自己的ID和自己的正確的值。每次使用攝像機列表的getter方法時,計數器都會更新,以便您可以在正確的索引處訪問正確的攝像機。

感謝Guilherme Torres Castro提供的答案和「encodeBegin」方法的發現。