2014-01-09 179 views
20

我無法使菜單項連接到事件處理程序。這是用戶界面的一個模擬,顯示隨着時間的推移狀態變化。這是一個下拉菜單(通過引導),根菜單項顯示當前選擇:如何在React子組件中設置事件處理程序

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

的最終目標是改變異步地根據用戶的選擇頁面內容。點擊Bob應該會觸發​​,但事實並非如此。

作爲一個便箋,我並不滿意componentDidMount調用this.handleClick();的方式,但它現在可以用作從服務器獲取初始菜單內容的一種方式。

/** @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') 
); 
}); 

我幾乎可以肯定,我的javascript作用域的朦朧認識是難辭其咎的,但一切到目前爲止,我已經嘗試已經失敗(包括試圖通過道具向下傳遞處理器)。

回答

40

問題是您正在使用匿名函數創建項目節點,並且其中this表示window。解決方法是將.bind(this)添加到匿名函數。

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

或創建this副本,並使用它:

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

您也可以通過'map'的'this'第二個參數,它會作爲在其中執行上下文中使用映射函數。 –

+0

輝煌。非常感謝!我最終將函數參數分解爲'map',以使得'this'作爲第二個參數更具可讀性:'var itemNodes = this.state.items.map(this.itemNode,this);' – clozach

+0

@ clozach-如果這回答你的問題,你能接受答案嗎? – imjared

相關問題