我正在尝试将模板文件views/infowindow.html
作为我的InfoWindow内容包含在我写的服务中,以启动Google地图API:
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插入InfoWindow时,似乎没有处理content
(当通过Dev Tools检查代码时,插入的代码是<div ng-include src="'views/infowindow.html'"></div>
)。
我希望Angular在插入InfoWindow之前预先处理我的include,但是没有。
我正在尝试做什么?
我想我必须以某种方式缓存模板,然后再将其传递给infowindow.setContent()
,但我不知道该怎么做(或者如果那是我应该>他们正在做。我宁愿在事件上加载模板而不是缓存并为每个标记注入它。
编辑查看$ templateCache和related SO question。
编辑2 以下是尝试使用$compile
的{{3}}(InfoWindow的内容仍为<div id="infowindow_content" ng-include src="'infowindow.html'"></div>
)
此基础来自plunk。在他的解决方案中,InfoWindow的内容是在第一次点击(任何标记)时编译的,但InfoWindow实际上不会打开,直到再次点击任何标记,可能是因为GoogleMaps不耐烦。
将$compile
移到外面然后将已编译的模板传递到.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
答案 0 :(得分:13)
将content
添加到DOM后,您需要找到它(可能使用jQquery选择器?),然后$compile
()它并将其应用到适当的范围。这将导致Angular解析您的内容并对其找到的任何指令(如ng-include)执行操作。
,例如$compile(foundElement)(scope)
如果没有更多代码,很难给出更准确的答案。但是,您可以查看similar question and answer。
更新:好吧,我终于让它工作了,我学到了一些东西。
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的模板需要插入{{ 1}}和{{latLng[0]}}
。我使用了{{latLng[1]}}
代替innerHTML
,因此只插入了infowindow.html的内容。
Update2:第一次点击无效。似乎'infowindow.html'直到第二次点击才加载(我试着调用范围。$ apply()第二次......没有帮助)。当我让plunker工作时,我在index.html中列出了infowindow.html的内容:
outerHTML
我在addListener()中使用它:
<script type="text/ng-template" id="/test.html">
<h4>{{latLng[0]}},{{latLng[1]}}</h4>
</script>
我更改了plunker以使用内联模板。
答案 1 :(得分:8)
以上答案是可靠的,但你失去了约束力:
infowindow.setContent( compiled[0].innerHTML );
请改为:
infowindow.setContent( compiled[0] );
否则,如果你有类似<div>{{myVar}}</div>
的内容,那么在你的应用中更新myVar
时,它就不会更新。
答案 2 :(得分:1)
您是否尝试过编译功能? http://docs.angularjs.org/api/ng.$compile
我还没有调整角度,但我认为这可行。
或者你可以尝试引导这些东西。但我不相信这是正确的方式...... http://docs.angularjs.org/guide/bootstrap