ArcGIS API for JavaScript 4.2學習筆記[16] 彈窗自定義功能按鈕及為要素自定義按鈕(第五章完結)


這節對Popups這一章的最后兩個例子進行介紹和解析。

第一個【Popup Actions】介紹了彈窗中如何自定義工具按鈕(名為actions),以PopupTemplate+FeatureLayer的形式測量要素的長度為例子進行介紹。

第二個【Custom popup actions per feature】則是上一個的升級,如果說上一個例子的功能是寫死的,那么這個例子就把這個功能寫活了。什么意思呢?上個例子的測距僅僅能測距,沒有什么別的特別的。而這個例子以啤酒店的分布(點要素圖層)為例,在自定義的按鈕中彈出在谷歌搜索的結果甚至彈出這個啤酒店的網站。

actions是什么?

actions是Popup類的一個屬性,類型是Collection,即同類型AJS對象或原生JS對象的數組容器。

它能裝什么?

能裝一些“動作”,這些動作在點擊彈窗左下角按鈕時,會觸發這個容器中的“動作”。每個彈窗都有一個默認的“動作”,就是“Zoom-To”縮放功能,就是一個小放大鏡。

看第一個例子的結果:

按下彈窗中的小測距尺子按鈕后,灰色文字條中就出現了這個紅色線要素的長度:11.82miles。

看第二個例子的結果:

按下按鈕后就會彈出谷歌搜索的結果。

來看代碼解析吧!


【Part I 簡單action:測距】

給出引用

require( [ "esri/Map", "esri/layers/FeatureLayer", "esri/views/MapView", "esri/geometry/geometryEngine", "dojo/domReady!" ], function(...){...} );

多了個geometryEngine,暫時不管它是干啥用的,繼續往下看。

事先說明一下,CDN的引用又多了一行:

  <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>

函數參數骨架

function(Map, FeatureLayer, MapView, geometryEngine){ var map = new Map({...}); var view = new MapView({...}); var measureThisAction = {...}; var template = {...}; featureLayer =new FeatureLayer({...}); map.add(featureLayer); function measureThis(){...}; view.popup.on("trigger-action", function(event){...}); }

套路依舊,map和view實例化。var的template是PopupTemplate對象賦給了featureLayer的popupTemplate屬性,再把featureLayer丟進map中。

好了,其余陌生的是什么?measureThisAction這個對象、measureThis這個方法、和view.popup.on方法?

別急,一個一個來。

measureThisAction出現的地方一一揪出來:

 

var measureThisAction = { title: "Measure Length", id: "measure-this", image: "Measure_Distance16.png" };

 

var template = { title: "Trail run", content: "{name}", actions: [measureThisAction] };

OK了,很明顯,measureThisAction是一個Object,有title、id和image,分別對應標題、ID和按鈕上的圖案。這個png文件在html的同級別目錄下。

下面這個template是featureLayer的PopupTemplate屬性所需的對象,有title、content,第三個actions屬性就將上方的measureThisAction賦給了它(數組形式,因為是Collection類型)。

可以理解如下:

measureThisAction是一個“動作”的聲明,本身無功能,可以說是一個UI層上的描述。

————

那么measureThis()這個方法呢?

function measureThis() { var geom = view.popup.selectedFeature.geometry; var distance = geometryEngine.geodesicLength(geom, "miles"); distance = parseFloat(Math.round(distance * 100) / 100).toFixed(2); view.popup.content = view.popup.selectedFeature.attributes.name +
    "<div style='background-color:DarkGray;color:white'>" + distance +
    " miles.</div>"; }

這里出現了新玩意兒:popup類的selectedFeature屬性以及其子屬性geometry/attributes,geometryEngine類的geodesicLength方法。

查詢API,解讀一下:

selectedFeature屬性類別:Graphic類,當前選擇的要素。

所以Graphic的geometry和attributes屬性就容易查到:

geometry:幾何體,沒什么好說的。類型:Geometry類。

attributes:要素的字段名和字段值的成對集合。

————

geodesicLength():計算傳入幾何體(Geometry)的長度。

於是這個方法就是:獲取幾何體,然后把長度用geodesicLength()計算出來,單位是miles。然后設定popup的content動態設置為獲取的要素長度值。

————

那么view.popup.on()這個方法呢?

看看完整的方法體:

view.popup.on("trigger-action", function(event) { if (event.action.id === "measure-this") { measureThis(); } });

已經灰常、灰常灰常明顯了,在popup這個類的“trigger-action”事件上,綁定一個事件方法體:如果“觸發”的“動作(action)”的id是“measure-this”,那么執行measureThis()方法執行測距並輸出到popup的content上。

於是,這個trigger-action是什么?

trigger-action是popup的事件的一種,和普通的click事件是一樣的,意義就是popup的“當動作(action)被觸發時”。click即“當鼠標點擊時”。

而Popup的triggerAction()方法則接受一個索引,去觸發trigger-action這個事件,然后執行索引對應的action。

現在明白了吧!

總結一下。

想要自己弄個按鈕在彈窗上,就要:告訴AJS我要創建一個按鈕,這個按鈕能做什么事情。

第一步,創建一個按鈕,使用Object對象measureThisAction來創建,並添加到PopupTemplate的actions屬性中(數組形式)。

第二步,寫出這個按鈕的事件方法measureThis,然后把它綁定到trigger-action事件上。


 

【Part II 為按鈕定制更高級的獨特的功能】

節約篇幅,引用和函參骨架一起給出

 

require( [ "esri/Map","esri/views/MapView","esri/layers/FeatureLayer","dojo/domReady!" ], function(Map,MapView,FeatureLayer){ var map = new Map({}); var view = new MapView({}); var featureLayer = new FeatureLayer({ ... definitionExpression: "country = 'United States'", popupTemplate: { ... actions: [{ id: "find-brewery", image: "beer.png",title: "Brewery Info"}] } }); map.add(featureLayer); view.then(function(){ var popup = view.popup; popup.viewModel.on("trigger-action", function(event){...}) }); } )

 

鑒於JavaScript的語法特性及面向對象的特性,Part I的很多對象、方法參數都直接用{}賦值了。

可以看到仍然是map和view的實例化,用的也是featureLayer和actions,actions不是[對象名]而是[{}]這種寫法給定,不過並沒有什么實質性的區別。

然后把featureLayer添加到map中去。

最后和Part I就有所不同了,Part I是view.popup.on("trigger-action", function(event){...})

而這里Part II,則是在view的回調函數中先獲取popup,然后使用popup.viewModel.on("trigger-action", function(event){...})

我們暫時不看這有什么區別,先看看這個function(event){...}做了什么:

popup.viewModel.on("trigger-action", function(event) { if (event.action.id === "find-brewery") { var attributes = popup.viewModel.selectedFeature.attributes; var info = attributes.website; if (info !== null) { window.open(info.trim()); } else { window.open("https://www.google.com/search?q=" + attributes.name); } } });

仍和Part I沒有什么區別,同樣是獲取一些信息,若info存在則直接打開,若不存在則到Google上搜索這個關鍵詞,即如果選擇的啤酒店有網站鏈接,那么就跳轉到這個網站;如果啤酒店沒有網站,就給出谷歌的搜索頁面。

所以我覺得,popup.viewModel.on()的寫法和view.popup.on()的寫法沒什么不同,多一層引用而已。

我們最后到官方的例子中看看有什么遺漏的信息:

沒有。說明這兩個寫法應該是通用的?留個標記,以后測試。

 

至此,第五章也結束了學習,這一章是我比較忙的時候寫的,可能讀起來比較費勁,各位看官還請見諒。

在下一章"Searching"即空間查詢中,我將轉換一下心情,寫出更好的筆記來學習AJS 4.2。

空間查詢的代碼量會激增,而AJS 4.3發布也快了,所以學習AJS 4.2的時間也不多了,新版本出來必定有新特性,我也會保持跟進繼續更新4.3的新特性,並予以解讀、測試。

 

下一章再見!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM