1. 程式人生 > >AngularJS指令封裝高德地圖元件

AngularJS指令封裝高德地圖元件

1 概述

      公司移動門戶原來是基於AngularJS指令封裝的百度地圖元件,用於簽到、簽退、定位等功能,在使用過程中發現百度地圖頻繁的彈出廣告,所以打算重新引用其它地圖元件,最後決定基於AngularJS指令來封裝高德地圖元件,本文主要與大家分享我的學習思路及開發具體過程。

注意:本文假定讀者基本掌握html、css、js以及angularjs,瞭解百度、高德或者騰訊地圖JS API的基本概念。

2 開發思路

       由於之前沒有開發過地圖元件,所以在開發之前需要做好學習計劃,預想下開發元件時可能會遇到的技術點與難題,之後有針對性的進行學習。首先學習高德地圖api,把簡單的基本功能實現出來,再做一個帶按鈕的,保證在本地可以執行,然後學習angularjs的指令,參考公司基於百度地圖樣例定位指令,基於angularjs封裝高德地圖元件,先基本顯示出地圖及標註,最後學習$watch監聽功能的用法,當地圖座標發生改變,使用angularjs裡$watch監聽屬性,在地圖對經度、維度進行動態標記。下面是被分解後的學習步驟供大家參考。

3 具體步驟

3.1 高德地圖JavaScriptAPI學習

1 執行下面的連結進入高德地圖網站

http://id.amap.com/?ref=http%3A%2F%2Flbs.amap.com%2Fdev%2Fkey#/account/info

2 註冊一個帳號,並建立一個key,如下圖選擇一個web端


 

3 點選下面的連結開始高德地圖的入門學習

http://lbs.amap.com/api/javascript-api/example/map/asynchronous-loading-map/

從左側選單目錄看出可以由深至淺的學習,中間有程式碼編輯區,右邊可以直接看到結果,非常方便


3.2 在本地html頁面顯示地圖樣例

1 本地建立html檔案,與相關的css檔案,將下面的程式碼考貝到該檔案內

建立css檔案,下面是css程式碼

html, body {

      margin: 0;

      height: 100%;

      width: 100%;

      position: absolute;

}

#container {

      position: absolute;

      top: 0;

      left: 0;

      right: 0;

      bottom: 0;

      width: 100%;

      height: 100%;

}

.button-group {

      position: absolute;

      bottom: 20px;

      right: 20px;

      font-size: 12px;

      padding: 10px;

}

.button-group .button {

      height: 28px;

      line-height: 28px;

      background-color: #0D9BF2;

      color: #FFF;

      border: 0;

      outline: none;

      padding-left: 5px;

      padding-right: 5px;

      border-radius: 3px;

      margin-bottom: 4px;

      cursor: pointer;

}

.button-group .inputtext {

      height: 26px;

      line-height: 26px;

      border: 1px;

      outline: none;

      padding-left: 5px;

      padding-right: 5px;

      border-radius: 3px;

      margin-bottom: 4px;

      cursor: pointer;

}

#tip {

      background-color: #fff;

      padding-left: 10px;

      padding-right: 10px;

      position: absolute;

      font-size: 12px;

      right: 10px;

      top: 20px;

      border-radius: 3px;

      border: 1px solid #ccc;

      line-height: 30px;

}

.amap-info-content {

      font-size: 12px;

}

#myPageTop {

      position: absolute;

      top: 5px;

      right: 10px;

      background: #fff none repeat scroll 0 0;

      border: 1px solid #ccc;

      margin: 10px auto;

      padding:6px;

      font-family: "Microsoft Yahei", "微軟雅黑", "Pinghei";

      font-size: 14px;

}

#myPageTop label {

      margin: 0 20px 0 0;

      color: #666666;

      font-weight: normal;

}

#myPageTop input {

      width: 170px;

}

#myPageTop .column2{

      padding-left: 25px;

}

#container {

      height: 50%;

      position: initial;

}

建立html檔案,將下面的程式碼拷貝到html檔案中

注意:key的值填寫你自己的

<link rel="stylesheet"      href="../org/css/gaodeMap.css" />

<script        src="http://webapi.amap.com/maps?v=1.3&key=837a9bdb426d81b6862135983d1d715c"></script>

<div id="container"></div>

      <div style="height:100px; text-align: center; margin: 50px;">

</div>

<script type="text/javascript">

                    var map = new AMap.Map("container", {

                           resizeEnable : true,

                           zoom : 17

                    });

                    var cpoint=map.getCenter( );

                    var marker = new AMap.Marker({

                           map : map,

                           draggable: true,  //是否可拖動

                           bubble : true

                    })

</script>

下面是這兩個檔案的路徑關係,為同級關係


2 雙擊gaodeMap.html檔案,檢視執行結果


3.3 為頁面新增按鈕設定地圖示記

修改html檔案的程式碼,將下面的程式碼拷貝到你的html檔案中

<link rel="stylesheet"       href="../org/css/gaodeMap.css" />

<script src="http://webapi.amap.com/maps?v=1.3&key=837a9bdb426d81b6862135983d1d715c"></script>

<div id="container"></div>

<div style="height:100px; text-align: center; margin: 50px;">

       <div id="tip"></div>

       <input type="button"   onclick="setMarkerA()" value="設定markerA">

       <input type="button"   onclick="setMarkerB()" value="設定markerB">

 </div>

<script type="text/javascript">

           var map = new AMap.Map("container", {

                     resizeEnable : true,

                     zoom : 17

              });

              var cpoint=map.getCenter( );

              var marker = new AMap.Marker({

                  map : map,

                     draggable: true,  //是否可拖動

                     bubble : true

         })

              setMarkerA=function(){ 

                     var mapOptions={"lng":123.427476,"lat":41.797287};

                     map.setCenter([mapOptions.lng ,mapOptions.lat]);

                     marker.setPosition([mapOptions.lng ,mapOptions.lat]);

              }

              setMarkerB=function(){

                     var mapOptions={"lng":123.42405344705162,"lat":41.798870569210926};

                     map.setCenter([mapOptions.lng ,mapOptions.lat]);

                     marker.setPosition([mapOptions.lng ,mapOptions.lat]);

              }

</script>

最終效果如下

3.4 學習AngularJS指令用法

1 在AngularJS菜鳥教程中學習關於directive的相關知識

點選下面的連結進入學習頁面

http://www.runoob.com/try/try.php?filename=try_ng_directive_comment

 

 2 瞭解AngularJS菜鳥教程中的directive的相關知識後上搜尋引擎學習directive的相關知識,進一步瞭解directive的用法


3 可以參考下面程式碼,配合搜尋引擎學習繼續瞭解directive中的相關屬性的知識:restrict,replace,template,link

.directive("appMap", function () {

        return {

          restrict: "E",

          replace: true,

          template: "<div id='allMap'></div>",

        scope:{

             'options': '='

        },

          link: function ($scope, element, attrs) {

             var map = new BMap.Map("allMap");

             $scope.$watch("options", function (newValue, oldValue) {

                   var allOverlay = map.getOverlays();

                   if (allOverlay && allOverlay.length > 0){

                          for (var i=0;i < allOverlay.length;i++){

                                 map.removeOverlay(allOverlay[i]);                                  

                          }

                       }

                    if ($scope.options && $scope.options.longitude && $scope.options.latitude){

                          var longitude = $scope.options.longitude;

                          var latitude = $scope.options.latitude;

                           var point = new BMap.Point(longitude,latitude); 

                        map.centerAndZoom(point,17); 

                          var mk = new BMap.Marker(point); 

                          var label = new BMap.Label("我在這裡",{offset:new BMap.Size(20,-10)});

                          label.setStyle({

                               "color":"green",

                               "fontSize":"14px",

                               "border":"1",

                               "textAlign":"center"

                          });

                          mk.setLabel(label);

                          map.addOverlay(mk);

                    };

             },true);

       }           

        };

})

3.5 封裝AngularJS指令顯示地圖

參考公司網站的定義功能,用angularjs的方式將一個簡單的地圖顯示出來,可以先不考慮$watch的用法

1.檢視公司定位的方法在什麼地方



2.建立一個html檔案,將下面的程式碼考入,注意這裡匯入的css檔案,與angular.min.js檔案

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <title>Title</title>

      <link rel="stylesheet"

      href="../css/gaodeMap.css" />

      <script src="http://webapi.amap.com/maps?v=1.3&key=837a9bdb426d81b6862135983d1d715c"></script>

    <script src="../js/angular.min.js"></script>

    </head>

<body>

<div ng-app="hd" ng-controller="ctrlA">

<gaode-map options="mapOptions" style="height:400px"></gaode-map>

</div>

<script>

    var m = angular.module('hd', []);

    m.directive('gaodeMap', [function () {

        return {

            restrict: 'E',

                    replace:true,

            template: '<div id="container"></div>',

                    scope: {

                options:'='

            },

                    link: function ($scope, elem, attr) {

                           var map = new AMap.Map("container", {

                                  resizeEnable : true,

                                  zoom : 17

                           });

                           var marker = new AMap.Marker({

                                         map : map,

                                         bubble : true ,

                                         content: '<div class="marker-route marker-marker-bus-from"></div>'  //自定義點標記覆蓋物內容,

                           })

                           marker.setLabel({

                                  offset: new AMap.Pixel(20, 0),

                                  content: "我在這裡"

                           });

                           $scope.$watch("options", function (newValue, oldValue) {    

                                  if ($scope.options && $scope.options.lng && $scope.options.lat){

                                         map.setCenter([$scope.options.lng ,$scope.options.lat]);

                                         marker.setPosition([$scope.options.lng ,$scope.options.lat]);

                                  }     

                           },true);

                    }

        }

    }]);

      m.controller("ctrlA",function($scope){

      });

</script>

</body>

</html>

3.匯入相應的css檔案與AngularJS檔案

下面是css檔案的程式碼

html, body {

       margin: 0;

       height: 100%;

       width: 100%;

       position: absolute;

}

#container {

       position: absolute;

       top: 0;

       left: 0;

       right: 0;

       bottom: 0;

       width: 100%;

       height: 100%;

}

.button-group {

       position: absolute;

       bottom: 20px;

       right: 20px;

       font-size: 12px;

       padding: 10px;

}

.button-group .button {

       height: 28px;

       line-height: 28px;

       background-color: #0D9BF2;

       color: #FFF;

       border: 0;

       outline: none;

       padding-left: 5px;

       padding-right: 5px;

       border-radius: 3px;

       margin-bottom: 4px;

       cursor: pointer;

}

.button-group .inputtext {

       height: 26px;

       line-height: 26px;

       border: 1px;

       outline: none;

       padding-left: 5px;

       padding-right: 5px;

       border-radius: 3px;

       margin-bottom: 4px;

       cursor: pointer;

}

 #tip {

       background-color: #fff;

       padding-left: 10px;

       padding-right: 10px;

       position: absolute;

       font-size: 12px;

       right: 10px;

       top: 20px;

       border-radius: 3px;

       border: 1px solid #ccc;

       line-height: 30px;

}

.amap-info-content {

       font-size: 12px;

}

#myPageTop {

       position: absolute;

       top: 5px;

       right: 10px;

       background: #fff none repeat scroll 0 0;

       border: 1px solid #ccc;

       margin: 10px auto;

       padding:6px;

       font-family: "Microsoft Yahei", "微軟雅黑", "Pinghei";

       font-size: 14px;

}

#myPageTop label {

       margin: 0 20px 0 0;

       color: #666666;

       font-weight: normal;

}

#myPageTop input {

       width: 170px;

}

#myPageTop .column2{

       padding-left: 25px;

}

#container {

       height: 1000px;

       position: initial;

}

.amap-marker-label {

                     border: 0px;

                     color: #0bc00f;

                     background: rgba(255, 255, 255, 0);

              }

.amap-marker .marker-route {

            position: absolute;

            width: 40px;

            height: 44px;

            color: #e90000;

            background: url(http://webapi.amap.com/theme/v1.3/images/newpc/poi-1.png) no-repeat;

            cursor: pointer;

}

.amap-marker .marker-marker-bus-from {

            background-position: -334px -18px;

}

4.下面是匯入的angularjs的庫檔案,拷貝出去放到自己的電腦裡,放入相應目錄


5.下面是我的路徑供參考


6.用瀏覽器開啟該檔案檢視,f12開啟控制檯切換到手機模式檢視預覽效果


3.6 擴充套件$watch監聽動態顯示位置

學習$watch的用法,監聽座標資料變化狀態,新增一個按鈕為地圖設定marker標記,完善上面功能。

1.上網學習關於$watch的相關用法


2.繼續參考公司的方法,完善上面的功能,為上面的功能新增按鈕為地圖設定座標下面為修改後的程式碼

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <title>Title</title>

       <link rel="stylesheet"

       href="../css/gaodeMap.css" />

       <script src="http://webapi.amap.com/maps?v=1.3&key=837a9bdb426d81b6862135983d1d715c"></script>

    <script src="../js/angular.min.js"></script>

    <script src="../js/jsjquery1.7.1.js"></script>

</head>

<body>

<div ng-app="hd" ng-controller="ctrlA">

<gaode-map options="mapOptions" style="height:400px"></gaode-map>

<input type="button"  ng-click="setMarkerA()" value="設定markerA">

<input type="button"  ng-click="setMarkerB()" value="設定markerB">

</div>

<script>

    var m = angular.module('hd', []);

    m.directive('gaodeMap', [function () {

        return {

            restrict: 'E',

                     replace:true,

            template: '<div id="container"></div>',

                     scope: {

                options:'='

            },

                     link: function ($scope, elem, attr) {

                            var map = new AMap.Map("container", {

                                   resizeEnable : true,

                                   zoom : 17

                            });

                            var marker = new AMap.Marker({

                                          map : map,

                                          bubble : true ,

                                          content: '<div class="marker-route marker-marker-bus-from"></div>'  //自定義點標記覆蓋物內容,

                            })

                            marker.setLabel({

                                   offset: new AMap.Pixel(20, 0),

                                   content: "我在這裡"

                            });

                            $scope.$watch("options", function (newValue, oldValue) {    

                                   if ($scope.options && $scope.options.lng && $scope.options.lat){

                                          map.setCenter([$scope.options.lng ,$scope.options.lat]);

                                          marker.setPosition([$scope.options.lng ,$scope.options.lat]);

                                   }     

                            },true);

                     }

        }

    }]);

       m.controller("ctrlA",function($scope){

              $scope.mapOptions={"lng":123.42678393582929,"lat":41.79739087943974};              $scope.setMarkerA=function(){

                     $scope.mapOptions={"lng":123.43223420561884,"lat":41.7987619126648};

              }

              $scope.setMarkerB=function(){

                     $scope.mapOptions={"lng":123.42405344705162,"lat":41.798870569210926};

              }

       });

</script>

</body>

</html>

3.下面為瀏覽器中執行後的效果


4 個人總結

學習任何新東西,甚至做任何事情之前,首先要明確目標,然後制定計劃、分解計劃、明確重點、攻克難點。計劃要先總後分,先全域性再區域性,對粗分過的步驟再細分,把不明白的知識點重點標註,儘可能細化的分解,讓過程可操作、易落地。

在學習研究過程中要做好筆記,把相關學習資料、參考檔案存放在一個目錄,過程檔案需要備份。

遇到不能解決的難點一定要努力嘗試思考過以後,再去詢問,在詢問之前要明確自己的問題、要能闡述清楚自己的問題,有時候明確問題怎麼闡述之後,還沒有去諮詢別人,可能問題就自己解決了。只有思考過的東西、有了實踐、有了交付物、有了筆記、能夠簡單明瞭闡述清楚,才能算是真正認知。

5 附件說明

下列附件為學習過程中整理的4個樣例檔案,由淺入深,逼近最終目標。4個檔案都一樣,解壓至本地,瀏覽器執行gaodeMap.html檔案即可

5.1 附件1,基礎演示高德地圖


附件說明:解壓至本地,瀏覽器執行gaodeMap.html檔案即可

執行效果:


5.2 附件2,支援標註動態設定



5.3 附件3,AngularJS指令封裝地圖


 

5.4 附件4,擴充套件監聽指令動態顯示位置


執行效果:


文件及附件下載地址:http://pan.baidu.com/s/1mi7F8yG