我试图将模板文件views/infowindow.html作为我为启动googlemapsapi而编写的服务中InfoWindow的内容包括在内:
views/infowindow.html
for ( var count = locations.length, i = 0; i < count; i++ ) { var latLng = locations[i], marker = new google.maps.Marker({ … }), infowindow = new google.maps.InfoWindow(); google.maps.event.addListener( marker, 'click', (function( marker , latLng ){ return function(){ var content = '<div ng-include src="\'infowindow.html\'"></div>'; infowindow.setContent( content ); infowindow.open( Map , marker ); }//return fn() })( marker , latLng ) );//addListener }//for
但是,将Angular content插入InfoWindow时似乎没有处理(通过DevTools检查代码时,插入的代码是<div ng-include src="'views/infowindow.html'"></div>)。
content
<div ng-include src="'views/infowindow.html'"></div>
我希望Angular在将include插入到InfoWindow中之前对其进行预处理,但是可惜没有。
我想做的事可能吗?
我在想,在将模板传递给之前,必须以某种方式对其进行缓存infowindow.setContent(),但是我不知道该怎么做(或者即使那是我 应该 做的事情)。我宁愿在事件上加载模板,而不是为每个标记缓存和注入模板。
infowindow.setContent()
编辑 看$templateCache和一个相关的SO问题。
编辑2 这是一个尝试使用的插件$compile(InfoWindow的内容仍然是<div id="infowindow_content" ng-include src="'infowindow.html'"></div>)
$compile
<div id="infowindow_content" ng-include src="'infowindow.html'"></div>
这是基于马克的以下回答。在他的解决方案中,InfoWindow的内容是在第一次单击(任何标记)时编译的,但是直到再次单击任何Marker时,InfoWindow才真正打开,这可能是因为GoogleMaps不耐烦。
移动$compile外部,然后将已编译的模板传递到其中 .addListener可以解决此问题:
.addListener
for ( … ) { … infowindow = new google.maps.InfoWindow(); scope.markers … var content = '<div id="infowindow_content" ng-include src="\'infowindow.html\'"></div>'; var compiled = $compile(content)(scope); google.maps.event.addListener( marker, 'click', (function( marker , scope, compiled , localLatLng ){ return function(){ scope.latLng = localLatLng;//to make data available to template scope.$apply();//must be inside write new values for each marker infowindow.setContent( compiled[0].innerHTML ); infowindow.open( Map , marker ); };//return fn() })( marker , scope, compiled , scope.markers[i].locations ) );//addListener }//for
更新了Plunker。
content将DOM添加到DOM之后,您需要找到它(也许使用jQquery选择器?),然后$compile()将其应用于适当的范围。这将导致Angular解析您的内容并对其找到的任何指令(例如ng-include)采取行动。
例如, $compile(foundElement)(scope)
$compile(foundElement)(scope)
没有更多的代码,很难给出更精确的答案。但是,您可以查看以下类似的问答。
更新: 好的,我终于可以使用它了,我学到了一些东西。
google.maps.event.addListener( marker, 'click', (function( marker , scope, localLatLng ){ return function(){ var content = '<div id="infowindow_content" ng-include src="\'infowindow.html\'"></div>'; scope.latLng = localLatLng; var compiled = $compile(content)(scope); scope.$apply(); infowindow.setContent( compiled[0].innerHTML ); infowindow.open( Map , marker ); };//return fn() })( marker , scope, scope.markers[i].locations )
我的印象是仅可以对DOM元素进行$编译-即,我首先必须将内容添加到DOM中,然后进行编译。事实证明这是不正确的。在上面,我首先content针对进行编译scope,然后将其添加到DOM中。(我不知道这是否会破坏数据绑定-即$compile设置的$watch()es。)我必须设置,scope.latLng因为包含ng的模板需要插值{{latLng[0]}}和{{latLng[1]}}。我使用innerHTML代替,outerHTML以便仅插入infowindow.html的内容。
scope
scope.latLng
{{latLng[0]}}
{{latLng[1]}}
innerHTML
outerHTML
柱塞。
Update2: 第一次单击不起作用。看来“infowindow.html”要等到第二次单击才能加载(我试图第二次调用scope。$apply()…没有帮助)。当我工作时,我已经在index.html中内联了infowindow.html的内容:
<script type="text/ng-template" id="/test.html"> <h4>{{latLng[0]}},{{latLng[1]}}</h4> </script>
我在addListener()中使用了它:
var content = '<div id="infowindow_content" ng-include src="\'/test.html\'"></div>';
我更改了插件,以使用内联模板。