14

views/infowindow.htmlGoogle マップ API を開始するために作成したサービスから、InfoWindow のコンテンツとしてテンプレート ファイルを含めようとしています。

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

ただし、contentInfoWindow に挿入すると Angular が処理していないようです (Dev Tools でコードを調べると、挿入されるコードは です<div ng-include src="'views/infowindow.html'"></div>)。

InfoWindow に挿入される前に Angular がインクルードを前処理することを望んでいましたが、残念ながら違います。

私がやろうとしていることは可能ですか?

テンプレートを に渡す前に、どうにかしてテンプレートをキャッシュする必要があると考えていますが、infowindow.setContent()その方法がわかりません (または、それが私がすべきことでさえあるかどうか)。マーカーごとにテンプレートをキャッシュして注入するのではなく、イベントにテンプレートをロードすることをお勧めします。

編集$templateCache と関連する SO questionを見てください。

EDIT 2これは、使用しようとするプランクです( InfoWindow$compileコンテンツはまだです<div id="infowindow_content" ng-include src="'infowindow.html'"></div>


解決

この根拠は、以下のマークの回答から来ました。彼のソリューションでは、InfoWindow のコンテンツは (任意のマーカーの) 最初のクリックでコンパイルされますが、おそらく GoogleMaps がせっかちなため、InfoWindow はマーカーをもう一度クリックするまで実際には開きません。

$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

プランカーを更新しました。

4

3 に答える 3

13

DOM に追加した後content、それを見つけて (おそらく jQquery セレクターで?)、$compile() それを適切なスコープに適用する必要があります。これにより、Angular はコンテンツを解析し、見つかったディレクティブ (ng-include など) に基づいて動作します。

例えば、$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 )

$compile できるのは DOM 要素だけだという印象を受けました。つまり、最初にコンテンツを DOM に追加してからコンパイルする必要があるということです。それは真実ではないことがわかりました。content上記では、最初にに対してコンパイルしてscopeから、それを DOM に追加しています。(これがデータバインディング、つまり $compile によってセットアップされた $watch() es を壊すかどうかはわかりません。) scope.latLngng に含まれるテンプレートは、{{latLng[0]}}および{{latLng[1]}}. innerHTML代わりにouterHTML、infowindow.html のコンテンツのみが挿入されるように使用しました。

プランカー

Update2: クリックしても最初は機能しません。'infowindow.html' は 2 回目のクリックまで読み込まれないようです (scope.$apply() をもう一度呼び出してみましたが、役に立ちませんでした)。プランカーを機能させたとき、infowindow.html の内容を index.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>';

インライン テンプレートを使用するようにプランカーを変更しました。

于 2013-01-09T05:08:00.037 に答える
8

上記の答えはしっかりしていますが、次のものに対する拘束力が失われます。

infowindow.setContent( compiled[0].innerHTML );

代わりにこれを行います:

infowindow.setContent( compiled[0] );

それ以外の場合、 のようなものがある場合、アプリで が更新されても更新され<div>{{myVar}}</div>ません。myVar

于 2014-10-28T20:18:51.100 に答える
1

コンパイル機能を試しましたか?http://docs.angularjs.org/api/ng.$compile

まだAngularについてはあまり調べていませんが、これでうまくいくと思います。

または、ブートストラップを試すこともできます。しかし、それが正しい方法だとは思わない... http://docs.angularjs.org/guide/bootstrap

于 2013-01-09T01:43:06.510 に答える