我正在尝试使用子元素初始化AngularJS指令中的一些数据。在这种情况下,<map>
元素将替换为使用传单连接的<div>
。我试图弄清楚指令compile
或link
函数中是否有某种方法可以从声明的子元素中填充markers
集合,如下所示:
<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 :(得分: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;
}
};
});
答案 1 :(得分:0)
实际上你可以使用templateUrl的derective。 只需将ng-transclude包含在那里的任何元素上,它就会将所有原始子元素都作为自己的元素。 然后在链接函数中,您可以读取这些DOM元素,执行任何操作并清理它们。