2016-04-06 12 views
0

Google Maps Javascript APIからGoogleマップをレンダリングしているReactJSコンポーネントに取り組んでいます。マップ上では、私は異なるディストリビューターの場所を示すマーカーを動的に配置しています。現在、模擬データは異なる情報を持つディストリビューターの配列から来ており、ループによって反復されています。マーカーがクリックされると、InfoWindowにディストリビューターの詳細が表示されます。このInfoWindowでは、顧客がこのディストリビューターを選択できるようにするボタンがあります。ReactJSコンポーネントが親コンポーネントにデータを渡していない

GoogleMapコンポーネントはChooseDistributorコンポーネントが所有します。ボタンをクリックすると、コールバック関数によってChooseDistributorコンポーネントに返されるID(ディストリビュータの名前を持つ文字列)が欲しいです。

ボタンをクリックすると、問題はUncaught TypeError: Cannot read property 'callbackParent' of undefinedになります。これはスコープの問題かもしれません。thisは私がループ(?)中にGoogleMapコンポーネント自体を参照していないためです。

これで、は、ループの外側にあるcallbackParentという変数を作成しようとしました。この変数には、ChooseDistributorコンポーネントの受信関数にリンクする必要があります。this.props.callbackParentが含まれています。私はボタンonclickでこの変数を呼び出しています。これは私がUncaught ReferenceError: callbackParent is not definedを取得しているときにも機能しません。

誰かがこの問題の可能な解決策を持っていると私は感謝します。私は何かを見逃しているのか、それとも普通の文法上の誤りですか?前もって感謝します。

以下は私のコードです。

ChooseDistributorコンポーネント

var ChooseDistributor = React.createClass({ 
    getSelectedDistributor: function(company){ 
     alert(company); 
    }, 

    render: function(){ 
     return(
      <div> 
       <Header headerClass="title" title="Choose distributor"/> 
       <div className="fillViewPort"> 
        <GoogleMap enableIwSelectButton={true} callbackParent={this.getSelectedDistributor}/> 
       </div> 
       <NavBar /> 
      </div> 

     ); 
    } 
}) 
module.exports = ChooseDistributor; 

Googleマップコンポーネント:

var GoogleMap = React.createClass({ 
    getInitialState: function(){ 
     return { 
      // LOCATIONS STATE SHOULD GET DATA FROM STORE 
      locations: [ 
       // ARRAY VALUES: [0]=LAT, [1]=LNG, [2]=COMPANY, [3]=ADDRESS, [4]=CITY, [5]=WEBSITE, [6]=PHONE, [7]=EMAIL 
       [55.628353, 12.388910, 'Distributor One', 'First street 11', '1111 Copenhagen', 'www.company.com', '+4512345678', '[email protected]'], 
       [55.623321, 12.388438, 'Distributor Two', 'Second street 22', '2222 Copenhagen', 'www.company.com', '+4512345678', '[email protected]'], 
       [55.670710, 12.389256, 'Distributor Three', 'Third street 33', '3333 Copenhagen', 'www.company.com', '+4512345678', '[email protected]'], 
       [55.581179, 12.295583, 'Distributor Four', 'Fourth street 44', '4444 Copenhagen', 'www.company.com', '+4512345678', '[email protected]'], 
       [55.647296, 12.284211, 'Distributor Five', 'Fifth street 55', '5555 Copenhagen', 'www.company.com', '+4512345678', '[email protected]'] 
      ] 
     } 
    }, 
    componentDidMount: function(){ 
     var locations = this.state.locations; 
     var enableIwSelectButton = this.props.enableIwSelectButton; 
     var callbackParent = this.props.callbackParent; 
     var map = new google.maps.Map(document.getElementById('googleMap'), { 
      zoom: 11, 
      center: new google.maps.LatLng(locations[0][0], locations[0][1]), // CENTER PROPERTY SHOULD GET COORDINATES OF THE DEVICE CURRENT LOCATION IF PERMITTED. 
      mapTypeControlOptions: { 
       mapTypeIds: [google.maps.MapTypeId.ROADMAP] 
      }, 
      mapTypeId: google.maps.MapTypeId.ROADMAP, 
      disableDefaultUI: true 
     }); 
     var infoWindow = new google.maps.InfoWindow(); 

     var marker, i; 

     // PLACE MARKER ON MAP FOR EACH DISTRIBUTOR POSITION IN ARRAY. 
     for (i = 0; i < locations.length; i++) { 
      marker = new google.maps.Marker({ 
       position: new google.maps.LatLng(locations[i][0], locations[i][1]), 
       map: map 
      }); 
      // ADD INFOWINDOW WITH DISTRIBUTOR DETAILS TO EACH MARKER. 
      google.maps.event.addListener(marker, 'click', (function(marker, i) { 
       return function() { 

        infoWindow.setContent('<p class="iwTitle">' + locations[i][2] + '</p>'+ 
         '<p class="iwText">' + locations[i][3] + '<br>' + 
         locations[i][4] + '<br>' + 
         '<a href="http://' + locations[i][5] + '">' + locations[i][5] + '</a></p>' + 
         '<p class="iwText"><i class="fa fa-phone iwIcons"></i>' + locations[i][6] + '<br>' + 
         '<i class="fa fa-envelope iwIcons"></i><a href="mailto:"' + locations[i][7] + '>' + locations[i][7] + '</a></p>' + 
         (enableIwSelectButton ? '<button type="button" class="iwButton" onclick={this.props.callbackParent(locations[i][3])}><p>Select Distributor</p></button>' : '')); 
        infoWindow.open(map, marker); 
       } 
      })(marker, i)); 
     } 
    }, 
    render: function(){ 
     return(
      <div id="googleMap" className="size-100-pct" /> 
     ); 
    } 
}) 

module.exports = GoogleMap; 

UPDATE:私の問題は、@放射性へ おかげで解決しました。溶液は、各ボタンにイドを与え、その後、そのIDによってその後ボタンをフェッチし、このようにそれにイベントリスナーを追加することであった。callback方法内側

google.maps.event.addListener(marker, 'click', (function(marker, i) { 
       return function() { 

        infoWindow.setContent('<p class="iwTitle">' + locations[i][2] + '</p>'+ 
         '<p class="iwText">' + locations[i][3] + '<br>' + 
         locations[i][4] + '<br>' + 
         '<a href="http://' + locations[i][5] + '">' + locations[i][5] + '</a></p>' + 
         '<p class="iwText"><i class="fa fa-phone iwIcons"></i>' + locations[i][6] + '<br>' + 
         '<i class="fa fa-envelope iwIcons"></i><a href="mailto:"' + locations[i][7] + '>' + locations[i][7] + '</a></p>' + 
         (enableIwSelectButton ? '<button type="button" id="btnSelect' + i + '" class="iwButton"><p>Select Distributor</p></button>' : '')); 
        infoWindow.open(map, marker); 
        var el = document.getElementById("btnSelect" + i); 
        el.addEventListener("click", function(){callbackParent(locations[i][2])}); 
       } 
      })(marker, i)); 
+0

これを親コンポーネントにバインドしましたか? '' – somallg

+0

@somallgはい私はそれを試みました。どちらもうまくいきません。それは '警告:bind()を与えています:コンポーネントメソッドをコンポーネントにバインドしています。 Reactはこれを自動的に高性能な方法で実行しますので、この呼び出しを安全に削除することができます。 ' – RonRonDK

答えて

0

情報ウィンドウ内のボタンが反応コンポーネントではありません。おそらくsetContentによって解析される生のHTMLです。したがって、ボタンの 'onclick'属性はグローバル名前空間で関数を実行しようとします。どのように作成されたかについての認識はなく、callbackParentでもthis.props.callbackParentでもlocations[i][3]も参照するためのグローバル名前空間にはありません。

componentDidMountで通常のDOM操作を使用して、イベントリスナーを追加することができます。

infoWindow.setContent(... '<button type="button" class="iwButton"><p>Select Distributor</p></button>' : '')); 
infoWindow.open(map, marker); 

var el = document.getElementsByClassName("iwButton"); 
el.addEventListener("click", function() { callbackParent(locations[i][3]) }); 
+0

これは本当にそれをしました。私はgetElementByIdを使用し、各ボタンに "btnSelect" + i(ループ内のカウンタ)の値を持つIdを与えましたが。助けてくれてありがとう@ラジオ - 。 – RonRonDK

0

this」自体をコールバックすることを指します。したがって、コールバック関数内の 'this'にアクセスして、外部スコープを参照することはできません。

はES6構文を試してみてください。

myFn:()=>{ 
this.props.any(); 
} 

または、

var self = this. 
myFn:function(){ 
    self.props.any(); 
} 
+0

あなたは何を意味するのかよくわかりません。どのように/あなたはこれを実装しますか? – RonRonDK

関連する問題