2013-03-28 43 views
0

我想用子元素初始化AngularJS指令中的一些數據。在這種情況下,<map>元素將被替換爲<div>,該元素將使用小冊子進行關聯。我試圖找出是否有該指令compilelink功能某種方式從聲明的子元素填充markers集合,這樣的事情:如何從子元素初始化AngularJS指令模型?

<div ng-app="dashboard"> 
<div ng-controller="DashboardCtrl"> 
    <map id="devicemap" tile-handle="test.map-fy18v14h" min-zoom="3" max-zoom="9" markers="markers"> 
     <marker lat="44" lng="-88.5" description="From the Server (Razor)" /> 
     <marker lat="44.1" lng="-88.6" description="From the Server 2 (Razor)" /> 
    </map> 
</div> 

在指令中,我想遍歷<marker>元素以填充集合。這應該發生在編譯?或者,我錯誤地指出,在插入實際模板之前,我可以訪問我的「假DOM」。

module.directive('map', function() { 
return { 
    restrict: "E", 
    replace: true, 
    scope: { 
     markers: "=markers" 
    }, 
    template: '<div class="map"></div>', 
    link: function link(scope, elm, attributes) { 
     var map = L.map(attributes.id, { 
      dragging: true, 
      zoomAnimation: true 
     }).setView([45.505, -88.09], 6); 
     L.tileLayer('http://{s}.tiles.mapbox.com/v3/' + attributes.tileHandle + '/{z}/{x}/{y}.png', { 
      attribution: "<a href='http://mapbox.com/about/maps' target='_blank'>Terms & Feedback</a>", 
     }).addTo(map); 

     // This is where I am stuck... is there a way to get the "marker" elements? 
     // the following does not work... 
     var markerElements = elm.children('marker'); 

     // now would like to loop over markerElements, grab the attributes and add them 
     // to the map (and/or the markers collection). 

    }; 
}); 

我能夠填充使用Ajax調用的標記,但是,這種技術可以讓我預先填充服務器上的數據時,第一次請求的頁面。

+0

由於您正在使用'template'(和'replace:true'),所以在鏈接函數運行時,''標籤已被刪除。這就是鏈接功能找不到它們的原因。 –

+0

這很有道理。有沒有辦法在更換之前訪問原始DOM? –

+1

您可以在編譯函數中做到這一點,但不能使用'template'(或'replace:true'),否則編譯函數將看到應用的模板而不是原始的DOM。在編譯函數內部,當完成修改DOM時,可以使用'replaceWith()'。示例:http://stackoverflow.com/a/10646761/215945 –

回答

0

好的,從Mark Rajcok的提示中,我想出了一個解決方案。這使我可以使用服務器上生成的自定義HTML元素在地圖上設置標記。我需要使用list變量來存儲compile函數中收集的數據。不知道是否有更清晰的方式來與Angular做到這一點。

HTML /剃刀

<div ng-app="dashboard"> 
    <div ng-controller="DashboardCtrl"> 
     <map id="devicemap" tile-handle="example.map-fy18v14h" min-zoom="3" max-zoom="9" markers="markers"> 
     @foreach (var location in Model.Locations) 
     { 
      <marker lat="@location.Lat" lng="@location.Lng" description="@location.Description" ></marker>         
     } 
     </map> 
    </div> 
</div> 

控制器

var module = angular.module('dashboard', ['map-directive']); 
module.controller("DashboardCtrl", function ($scope, $http) { 
    $scope.markers = []; 
}); 

指令

var mapDirective = angular.module("map-directive", []); 

mapDirective.directive('map', function() { 

    var list = []; 

    function link (scope, elm, attributes) { 
     var map = L.map(attributes.id, { 
      dragging: true, 
      zoomAnimation: true 
     }).setView([45.505, -88.09], 6); 

     scope.markers = list; 

     L.tileLayer('http://{s}.tiles.mapbox.com/v3/' + attributes.tileHandle + '/{z}/{x}/{y}.png', { 
      attribution: "<a href='http://mapbox.com/about/maps' target='_blank'>Terms & Feedback</a>", 
     }).addTo(map); 

     scope.$watch('markers', function (newValue, oldValue) { 
      if (newValue) 
       angular.forEach(scope.markers, function (marker) { 
        L.marker([marker.lat, marker.lng], { draggable: marker.draggable }).addTo(map).bindPopup(marker.description); 
       }); 
     }); 
    } 

    return { 
     restrict: "E", 
     scope: { 
      markers: "=markers" 
     }, 

     compile: function(tElement, tAttrs, transclude) { 

      console.log(tElement); 
      console.log(tElement.find("marker")); 

      var markers = tElement.find("marker"); 


      angular.forEach(markers, function (marker) { 
       list.push({ lat: marker.attributes.lat.value, lng: marker.attributes.lng.value, description: marker.attributes.description.value}); 
      }); 

      var htmlText = '<div class="map" id="' + tAttrs.id + '" ></div>'; 
      tElement.replaceWith(htmlText); 
      return link; 
     } 
    }; 

}); 
+0

'list'將被應用中的所有'map'指令共享。如果你打算使用多個'map',那麼你需要有多個列表,或者將'list'從一個數組轉換爲一個對象,其中每個屬性都是'map'的id,每個屬性值是一個數組。 –

0

其實你可以使用derective與templateUrl。 只要把ng-transclude放在那裏的任何元素上,它就會擁有所有的原始子元素。 然後在鏈接函數中,您可以閱讀這些DOM元素,做任何你螞蟻並清理它們。