這一節我們來看看彈窗的位置和彈窗上能放什么。
先一句話總結:
位置:可以隨便(點擊時出現或者一直固定在某個位置),也可以指定位置
能放什么:四種,文字、媒體(圖片等)、表格、附件。
【Part I 位置】
這一例子和下一個例子中,CDN的引用多了一行
<link rel="stylesheet" href="https://js.arcgis.com/4.2/esri/css/main.css"> <link rel="stylesheet" href="https://js.arcgis.com/4.2/dijit/themes/claro/claro.css"> <script src="https://js.arcgis.com/4.2/"></script>
我也不知道多出來這個claro.css是干嘛的,不過還是注意的好。
這個例子官方給的很復雜,盡管實現上很簡單。從html代碼開始看看吧!
<body> <div id="viewDiv"> <div class="docking-control"> <label for="dockPositionControl">Popup Dock Position</label> <select id="dockPositionControl"> <option selected value="auto">Auto</option> <option value="top-left">Top Left</option> <option value="top-center">Top Center</option> <option value="top-right">Top Right</option> <option value="bottom-left">Bottom Left</option> <option value="bottom-center">Bottom Center</option> <option value="bottom-right">Bottom Right</option> </select> </div> </div> </body>
可以看到有一個select選擇表單,內含7個可選項,第一個被定義為默認選中的項目。每個option標簽的value對應PopupTemplate的position的值。
引用
照常,給出引用。
require(
[
"esri/Map","esri/views/MapView","esri/WebMap",
"dojo/dom", "dojo/on", "dojo/domReady!"
],
function(Map,MapView,WebMap,dom,on){
}
);
好的,沒有疑問。下一個。
函數參數骨架
function(Map,MapView,WebMap,dom,on){ var webmap = new WebMap({...}); var view = new MapView({...}); popup = view.popup; view.then(function(){...}); }
好的,沒有疑問,下——好吧,有疑問,這個popup是什么?就是view實例化后的內置默認彈窗對象啊!(看我上一篇隨筆)
——既然說到這個就貼多一部分代碼。
var view = new MapView({ map: webmap, popup: { dockEnabled: true, dockOptions: { buttonEnabled: false, breakpoint: false } }, container: "viewDiv" });
對,就是MapView的實例化代碼。
其他的地方沒什么不同,就popup這個不同,與上一節方法略微不同,上一節說的是先聲明一個匿名對象,而這里直接把匿名對象在構造函數里寫上了。
dockEnabled就是是否能停靠在頁面旁邊。
dockOptions是Object類型,這里寫了buttonEnabled和breakpoint兩個屬性。意義分別為“停靠按鈕是否隱藏”、“是否在點擊的地方顯示”(后一個參數不確定是什么意思,我猜的,英文水平不是很好哈哈)
view.then()這個方法見我第七篇隨筆。
總之,數據(用的是WebMap)和視圖都准備好后,就要在then()方法里設置相關的操作了。
then()方法回調函數
view.then(function(){ var centerPoint = view.center.clone(); popup.open({}); popup.watch("currentDockPosition", function(value){...}); var selectNode = dom.byId("dockPositionControl"); on(selectNode,"change",funcion(e){}); });
整體大概是上面的樣子。
解讀如下:
首先,獲取view的中央位置。
然后,打開view的默認彈窗。
之后,默認彈窗監聽自己的currentDockPosition屬性,如果currentDockPosition屬性發生更改,就重新打開一次彈窗。
最后獲取下拉可選框里的值,把popup的position屬性更改。
——————
是不是很亂?
我也覺得很亂。
實際在頁面操作的結果如下:
剛打開的頁面是這樣的:

中間的下拉框選擇控件是html組織的,並不是AJS的widget;右上角是“buttonEnabled: false,breakpoint: false”+默認position的結果。
當我切換中間下拉框的選項時,如:

默認的彈窗的位置就發生了變化。這里,是觸發了上面代碼中“on(selectNode,"change",function(e){...});”這段代碼。
而點擊視圖任意位置時,如:

view的彈窗的內容(content)就發生了變化(至於popup的content屬性是怎么更改的,不知道,代碼里沒有,可能是WebMap的特殊性吧)
好了,官方繞了這么大一圈就是想說:
要想改popup的位置,只需更改dockOptions這個屬性下的position屬性即可。
目前只支持上下×左中右配對的6個位置。
所以各位看官看到這里知道原理就行啦,給出on(selectNode,"change",function(e){...});這段完整的代碼,就更加清晰了。
on(selectNode, "change", function (e) { popup.set("dockOptions", { breakpoint: false, buttonEnabled: false, position: e.target.value }); });
源代碼也給完:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"> <title>Dock Positions with Popup - 4.2</title> <style> html, body, #viewDiv { padding: 0; margin: 0; height: 100%; width: 100%; } .docking-control { font-family: "Avenir Next", "Helvetica Neue", Helvetica, Arial, sans-serif; position: absolute; z-index: 10; top: 50%; left: 50%; width: 250px; height: 80px; padding: 10px; box-sizing: border-box; margin: -40px 0 0 -125px; background-color: #fff; color: #323232; text-align: center; -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); } .docking-control label { display: inline-block; font-weight: bold; margin: 0 0 10px 0; padding: 0; font-size: 16px; } </style> <link rel="stylesheet" href="https://js.arcgis.com/4.2/dijit/themes/claro/claro.css"> <link rel="stylesheet" href="https://js.arcgis.com/4.2/esri/css/main.css"> <script src="https://js.arcgis.com/4.2/"></script> <script> require([ "esri/Map", "esri/views/MapView", "esri/WebMap", "dojo/dom", "dojo/on", "dojo/domReady!" ], function ( Map, MapView, WebMap, dom, on ) { var webmap = new WebMap({ portalItem: { // autocasts as new PortalItem() id: "3af548bac6054938b615d08104197ba0" } }); var view = new MapView({ map: webmap, popup: { dockEnabled: true, dockOptions: { // Disables the dock button from the popup buttonEnabled: false, // Ignore the default sizes that trigger responsive docking breakpoint: false, } }, container: "viewDiv" }); popup = view.popup; view.then(function () { var centerPoint = view.center.clone(); popup.open({ title: "Popup dock positions", location: centerPoint, content: "Use the control in the center of the map to change the location where the popup will dock." }); // Watch currentDockPosition of the popup and open the // popup at the at position. popup.watch("currentDockPosition", function (value) { popup.open(); }); var selectNode = dom.byId("dockPositionControl"); // Let user change the position dockOptions.position property of the // popup at runtime from the drop-down list. on(selectNode, "change", function (e) { popup.set("dockOptions", { breakpoint: false, buttonEnabled: false, position: e.target.value }); }) }); }); </script> </head> <body> <div id="viewDiv"> <div class="docking-control"> <label for="dockPositionControl">Popup Dock Position</label> <select id="dockPositionControl"> <option selected value="auto">Auto</option> <option value="top-left">Top Left</option> <option value="top-center">Top Center</option> <option value="top-right">Top Right</option> <option value="bottom-left">Bottom Left</option> <option value="bottom-center">Bottom Center</option> <option value="bottom-right">Bottom Right</option> </select> </div> </div> </body> </html>
記住記住關鍵是popup.dockOptions的position屬性即可(規定好的6種)!
【Part II 能放什么】
這個例子數據又切換回了Map而不是上面的WebMap。
這個例子用的是PopupTemplate而不是Popup,所以數據用了featureLayer。
所以,給出預覽圖:

哇!彈出窗的內容豐富了有木有!
其實就是Popup的content的內容可以定制而已!(上一篇已經着重說過,PopupTemplate這個類的content和Popup的類有點不同,PopupTemplate這個類的content可以是string,也可以是Object[]。
這就有意思了,Object類型的數組就可以指定很多東西給它。
給出featureLayer的聲明骨架代碼:
var featureLayer = new FeatureLayer({ url: "...", popupTemplate: { title: "..." content: [{...},{...},{...},{...}] }, outFields: ["*"] });
可以看到content是Object[]類型的了,具體代碼是:
content: [ { type: "fields", fieldInfos: [ { fieldName: "Point_Count", visible: false, label: "Count of Points", format: { places: 0, digitSeparator: true } }, { fieldName: "relationships/0/Point_Count_COMMON", visible: true, label: "Sum of species tree count", format: { places: 0, digitSeparator: true }, statisticType: "sum" }, { fieldName: "relationships/0/COMMON", visible: false, label: "Common Name" }, { fieldName: "BLOCKCE10", visible: true, label: "Block" }] }, { type: "text", text: "There are {Point_Count} trees within census block {BLOCKCE10}" }, { type: "media", mediaInfos: [ { title: "<b>Count by type</b>", type: "pie-chart", caption: "", value: { theme: "Grasshopper", fields: ["relationships/0/Point_Count_COMMON"], normalizeField: null, tooltipField: "relationships/0/COMMON" } }, { title: "<b>Welcome to Beverly Hills</b>", type: "image", value: { sourceURL: "https://www.beverlyhills.org/cbhfiles/storage/files/13203374121770673849/122707_039r_final.jpg" } }, { title: "<b>Palm tree lined street</b>", type: "image", value: { sourceURL: "https://cdn.loc.gov/service/pnp/highsm/21600/21679r.jpg" } }] }, { type: "attachments" } ]
一顆很龐大的樹,縮起來就成了:

四個紅框框,看type和對應的信息即可。
第一個是fields類型的,所以就是fieldInfos,再往下展開設置輸出文本的格式等等即可。(表格,數據源自PopupTemplate.fieldInfos屬性,如果沒有就要先進行設置,本例中featureLayer來源自ESRI的服務器,應該是有的)
第二個是text,文本類型的,格式在這截圖可以看到。
第三個是media,所以就是mediaInfos,往下還能再分pie-chart(餅圖)、image(圖片)等等。
第四個是附着物,就是附件,提供下載功能,如PDF文檔。
media的類型可以是:image | pie-chart | bar-chart | column-chart | line-chart
再往下就不細看了,需要什么就對應找到PopupTemplate的參考文檔即可。下面給出超鏈接
(發文時是4.2,如果有更新請自行尋找4.2的SDK中的API Reference)
