2014-01-09 11 views
20

Ich habe Probleme beim Menüpunkten immer zu einem Event-Handler verbunden. Hier sehen Sie ein Beispiel für die Benutzeroberfläche, auf der Statusänderungen im Laufe der Zeit angezeigt werden. Es ist ein Drop-Down-Menü (über Bootstrap), mit der Wurzel Menüpunkt die aktuelle Auswahl zeigt:Wie Ereignishandler gesetzt in Reaktion Subkomponente

[ANN]<click ... [ANN]    ... [BOB]<click ... [BOB] 
        [Ann]          [Ann] 
        [Bob]<click + ajax       [Bob] 
        [Cal]          [Cal] 

Das Endziel ist es, den Seiteninhalt asynchron auf der Auswahl des Benutzers basierend zu ändern. Ein Klick auf Bob sollte die handleClick auslösen, aber es ist nicht.

Als eine Randnotiz bin ich nicht sehr glücklich mit der Art, wie componentDidMount this.handleClick(); aufruft, aber es funktioniert für jetzt als eine Möglichkeit, erste Menüinhalte vom Server zu erhalten.

/** @jsx React.DOM */ 

var CurrentSelection = React.createClass({ 
    componentDidMount: function() { 
    this.handleClick(); 
    }, 

    handleClick: function(event) { 
    alert('clicked'); 
    // Ajax details ommitted since we never get here via onClick 
    }, 
    getInitialState: function() { 
    return {title: "Loading items...", items: []}; 
    }, 
    render: function() { 
    var itemNodes = this.state.items.map(function (item) { 
     return <li key={item}><a href='#' onClick={this.handleClick}>{item}</a></li>; 
    }); 

    return <ul className='nav'> 
     <li className='dropdown'> 
     <a href='#' className='dropdown-toggle' data-toggle='dropdown'>{this.state.title}</a> 
     <ul className='dropdown-menu'>{itemNodes}</ul> 
     </li> 
    </ul>; 
    } 
}); 


$(document).ready(function() { 
    React.renderComponent(
    CurrentSelection(), 
    document.getElementById('item-selection') 
); 
}); 

Ich bin fast sicher, dass mein trübes Verständnis von JavaScript-Scoping schuld ist, aber alles, was ich bisher ausprobiert habe versagt hat (einschließlich versucht, den Handler nach unten durch Requisiten passieren).

Antwort

40

Das Problem besteht darin, dass Sie die Elementknoten mit einer anonymen Funktion erstellen, und innerhalb dieser this bedeutet die window. Das Update ist .bind(this) auf die anonyme Funktion hinzuzufügen.

var itemNodes = this.state.items.map(function (item) { 
    return <li key={item}><a href='#' onClick={this.handleClick}>{item}</a></li>; 
}.bind(this)); 

Oder eine Kopie this erstellen und verwenden, die statt:

var _this = this, itemNodes = this.state.items.map(function (item) { 
    return <li key={item}><a href='#' onClick={_this.handleClick}>{item}</a></li>; 
}) 
+15

Sie auch 'passieren kann map' ein zweites Argument von' this', die sie als Rahmen, innerhalb dessen verwenden werden, auszuführen die Zuordnungsfunktion. –

+0

Brilliant. Vielen Dank! Ich beenden die Funktionsparameter zu 'map' Ausklammern bis machen es besser lesbar mit' this' als zweitem param: 'var itemNodes = this.state.items.map (this.itemNode, this);' – clozach

+0

@ clozach- Wenn dies Ihre Frage beantwortet, können Sie bitte die Antwort akzeptieren? – imjared