2016-04-06 3 views
0

Ich arbeite an einer ReactJS-Komponente, die eine Google-Karte aus der Google Maps Javascript API rendert. Auf der Karte platziere ich dynamisch Marker, die verschiedene Verteilerstandorte zeigen. Im Moment kommen die Mock-Daten von einer Reihe von Verteilern mit verschiedenen Informationen und werden von einer Schleife durchlaufen. Wenn ein Marker angeklickt wird, habe ich das InfoWindow, das die Händlerdetails anzeigt. Jetzt habe ich in diesem InfoWindow einen Button, mit dem der Kunde diesen Verteiler auswählen kann.ReactJS-Komponente, die Daten an die übergeordnete Komponente zurückgibt, funktioniert nicht

Die GoogleMap-Komponente gehört der ChooseDistributor-Komponente. Wenn Sie auf die Schaltfläche klicken, möchte ich eine ID (die gerade eine Zeichenfolge mit dem Namen des Verteilers ist), die von einer Rückruffunktion an die ChooseDistributor-Komponente zurückgesendet werden soll.

Das Problem ist, dass ich eine Uncaught TypeError: Cannot read property 'callbackParent' of undefined bekomme, wenn ich auf die Schaltfläche klicke. Dies könnte ein Problem mit dem Umfang sein, da sich this nicht auf die GoogleMap-Komponente selbst bezieht, während ich in der Schleife bin (?).

Ich habe dann versucht, eine Variable callbackParent außerhalb der Schleife zu erstellen, die this.props.callbackParent enthält, die zurück mit der Empfangsfunktion in der ChooseDistributor-Komponente verknüpft werden sollte. Ich rufe diese Variable dann über den Button onclick an. Dies funktioniert auch nicht, da ich eine Uncaught ReferenceError: callbackParent is not defined bekomme.

Ich würde mich freuen, wenn jemand eine mögliche Lösung für dieses Problem hat. Fehle ich etwas oder ist es ein einfacher Syntaxfehler? Danke im Voraus.

Unten ist mein Code.

ChooseDistributor Komponente

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; 

GoogleMap Komponente:

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: Dank @ Radio- mein Problem gelöst wurde. Die Lösung wurde jede Taste eine ID zu geben, und dann die Taste danach durch diese ID holen und ein Eventlistener um es wie folgt hinzu:

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

Haben Sie versucht, dies mit der übergeordneten Komponente zu verbinden? '' – somallg

+0

@somallg Ja, ich habe das versucht. Funktioniert auch nicht. Es gibt ein 'Warnen: bind(): Sie binden eine Komponentenmethode an die Komponente. Reagiert das automatisch für Sie automatisch auf eine hochleistungsfähige Weise, so können Sie diesen Anruf sicher entfernen. " – RonRonDK

Antwort

0

Die Schaltfläche im Infowindow ist eine Komponente Reagieren nicht. Es ist Roh-HTML, möglicherweise geparst von setContent. Das Attribut 'onclick' der Schaltfläche wird also versuchen, eine Funktion im globalen Namespace auszuführen. Es ist nicht bekannt, wie es erstellt wurde, und weder callbackParent noch this.props.callbackParent noch locations[i][3] befindet sich im globalen Namespace, auf den es verweisen kann.

Sie können die reguläre DOM-Manipulation in componentDidMount verwenden, um den Ereignis-Listener hinzuzufügen.

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

Das hat es wirklich getan. Obwohl ich getElementById verwendet habe und jedem Button eine ID mit dem Wert "btnSelect" + i (der Zähler in der Schleife) gegeben hat. Vielen Dank für Ihre Hilfe @ Radio-. – RonRonDK

0

this‘ innen callback Methode selbst Rückruf bezieht. Sie können also nicht innerhalb der Callback-Funktion "this" auf den äußeren Bereich zugreifen.

try ES6 Syntax:

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

oder

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

Ich bin mir nicht sicher, was Sie meinen. Wie/wo würdest du das umsetzen? – RonRonDK

Verwandte Themen