我有两个看起来像这样的指令:
<g-map centerlong="{{myLocation.long}}" centerlat="{{myLocation.lat}}" zoom="12" id="map" class="map">
<g-marker poslong="{{myLocation.long}}" poslat="{{myLocation.lat}}" title="g-marker"></g-marker>
</g-map>
g-map创建了一个谷歌地图,现在我希望将g-marker应用于它。
因此,g-marker需要访问在g-map中创建的对象。我怎么能通过呢
directive('gMap', function(googleMaps){
return{
restrict: 'E',
replace: true,
transclude: true,
template: "<div ng-transclude></div>",
scope: true,
link: function(scope, element, attrs){
scope.$on('location', function(){
//här ska den recentreras
})
//create the map
var center = googleMaps.makePosition(attrs.centerlat, attrs.centerlong)
//update map on load
var options = googleMaps.setMapOptions(center, attrs.zoom);
scope.map = googleMaps.createMap(options, attrs.id)
}
}]
};
}).
directive('gMarker', function(googleMaps, $timeout){
return{
//require: "^gMap",
restrict: 'E',
scope: true,
link: function(scope, element, attrs, controller){
var location = googleMaps.makePosition(attrs.poslat, attrs.poslong)
$timeout(function(){
//this is where I want to access the scope.map variable
googleMaps.addMarker(map, location,attrs.title)
}, 0);
}
}
})
答案 0 :(得分:2)
正如您所说,googlempas会替换html标记,因此您使用transclude,这会使父范围无法访问子范围。
以下是一些选项:
最简单的解决方案是使父范围不隔离,因此只需在父指令中删除scope : true
,在父指令的控制器中和设置scope.map
。这确保了属性在子链接功能中立即可用(不需要$ timeout)。但是,如果你正在进行dom操作,你必须在链接功能中进行操作)
或者您可以在父指令和子指令之间设置双向数据绑定:
scope : {map : '=map'}
或者,如果您不想将整个地图对象暴露给子项,则可以公开子项可以调用的父作用域的方法:
在gMap中,创建一个控制器:
controller : [function() {
this.addMarker(location, title)
}];
在gMarker中,需要gMap:
require: "^gMap"
这会将gMap控制器注入到link指令中:
link: function(scope, element, attrs, gMapController){
gMapController.addMarker(location, attrs,title)
}
我为这个plunker中的每个选项做了一个例子:
http://plnkr.co/edit/1UyNVhFZl4HtFdqeYhie?p=preview
我更喜欢第三种选择,因为孩子无需访问整个地图对象。
请注意,其他因素可能会导致任何选项失败。如果它不起作用,请报告。