2016-07-17 57 views
0

我是JavaScript新手,正在使用實時搜索應用程序,我正在使用反應來獲取搜索結果。 我使用ajax從網址獲取數據,因爲我不得不使用jsonp來解決服務器約束。雖然我可以在我的searchForTerm函數的console.log中得到結果,但不能在渲染函數中使用,因爲我無法正確地將它綁定到我的變量。所以我無法在屏幕上得到我想要的結果。使用Reactjs和ajax實時搜索URL訪問數據

請檢查我jsfiddle

這裏是我的代碼:

// var test = {}; 
// var json = {"F": {"symbol": "F", "name": "Ford Motor", "bidPrice": 13.43, "askPrice": 13.52}}; 
// test.data = [json]; 
// If i use the above variable and feed them to data during initialization, 
// then it works. But when i get the same data from server i am not able to 
// get the same update on my screen. 


var SearchStock = React.createClass({ 

    getInitialState: function() { 
     return {searchString: '', data: [], quantity: ''}; 
    }, 

    componentWillMount: function() { 
     // Get the initial terms 
     this.doSearch(); 
    }, 

    componentWillUnmount: function() { 
     this.serverRequest.abort(); 
    }, 

    doSearch: function(term) { 
     this.serverRequest = this.searchForTerm(term || '').then(this.handleSearchResult); 
    }, 

    searchForTerm: function (term) { 
    var url = 'http://data.benzinga.com/rest/richquoteDelayed?symbols=' + term; 
    return $.ajax({ 
     url, 
     dataType: 'jsonp', 
     success: function (data) { 
      console.log("in search", JSON.stringify(data)); 
      this.setState({data: [JSON.stringify(data)]}); 
      }.bind(this) 
     }); 
    }, 

    handleSearchResult: function(quote) { 
     this.setState(quote); 
    }, 

    handleChange: function(e) { 
     this.setState({searchString: e.target.value}); 

     // The server doesn't seem to respond to lowercase values 
     this.doSearch(e.target.value.toUpperCase()); 
    }, 

    buy: function(e){ 
     if(!term.quantity){ 
      term.quantity = e; 
     } else { 
      term.quantity = term.quantity + e; 
     } 
     return term.quantity; 
    }, 

    sell: function(e){ 
     term.quantity = term.quantity - e; 
     return term.quantity; 
    }, 

    viewStock: function(e){ 
     searchForTerm(e); 
    }, 

    render: function() { 
     var stocks = this.state.data; 
     console.log("in render", stocks); 

     var searchString = this.state.searchString.trim().toLowerCase(); 

     if (searchString.length > 0) { 
      stocks = stocks.filter(function(l) { 
       // return l.name.toLowerCase().match(searchString); 
       return l[Object.keys(l)[0]]["symbol"].toLowerCase().match(searchString); 
      }); 
     } 

     return (
      <div> 
       <div id='searchResult'> 
        <input type="text" value={this.state.searchString} onChange={this.handleChange} placeholder="Type here" /> 
        <ul> 
         {stocks.map(function(l) { 
          return <div> 
           <h3>{l[Object.keys(l)[0]]["name"]}</h3> 
           <table class="table table-striped table-bordered"> 
            <tr> 
             <th>Bid</th> 
             <th>Ask</th> 
            </tr> 
            <tr> 
             <td>{l[Object.keys(l)[0]]["bidPrice"]}</td> 
             <td>{l[Object.keys(l)[0]]["askPrice"]}</td> 
            </tr> 
           </table> 
          </div> 
         })} 
        </ul> 
        <input type="text" value={this.state.quantity} placeholder="Quantity" /> 
        <input type="button" value="Buy" onClick={this.buy} /> 
        <input type="button" value="Sell" onClick={this.sell} /> 
       </div> 
       <div id='currentPorfolio'> 
        <h5>Current Portfolio</h5> 
        <h5>$100,000 This needs a disabled text box with value comming from a variable with initial value as $100000</h5> 
        <table class="table table-striped table-bordered"> 
         <tr> 
          <th>Company</th> 
          <th>Quantity</th> 
          <th>Price Paid</th> 
          <th></th> 
         </tr> 
         {stocks.map(function(l) { 
          return <tr> 
           <td>{l[Object.keys(l)[0]]["name"]}</td> 
           <td>{l[Object.keys(l)[0]]["quantity"]}</td> 
           <td>{l[Object.keys(l)[0]]["bidPrice"]}</td> 
           <td>{<input type="button" value="View Stock"/>}</td> 
          </tr> 
         })} 
        </table> 
       </div> 
      </div> 
     ); 
    } 
}); 

ReactDOM.render(<SearchStock />, document.getElementById('container')); 

我覺得這應該涉及到的變量的作用域,他們正在更新的方式。但是,如果有人能夠幫助我,我將不勝感激,因爲我可以在控制檯日誌中看到結果,但不能在屏幕上看到結果。

在此之後,我必須努力解決這個問題,因爲現在即使沒有變化,它也會向服務器發送請求。有沒有更好的方法來使用handleChange只有當文本框中有變化時纔會調用?

道歉,如果我在這裏缺少的東西,因爲我是相當新的JavaScript和反應。我一直對JavaScript處理範圍的方式感到困惑。

+0

如果我嘗試運行你的小提琴,我會爲AJAX調用得到'blocked:mixed content'。你是說你看到'console.log(「渲染」,股票)的新數據;'(所以一切正常),但DOM不更新?試着把簡單的東西放在'

股票:{this.state.stocks.length}

'。這是否更新? –

+0

@DavidGilbertson我的道歉,我的意思是我可以看到'console.log(「在搜索」,JSON.stringify(數據));',但不是在呈現中的數據。而我正在搜索的數據與var json中的數據類似。我已經更新了我的帖子和小提琴,使其更加清晰。 –

+0

好的,我不確定'這個'會在jQuery的'ajax()'裏面指向什麼,我會看看... –

回答

0

我能用onBlur代替onChange做出反應。這裏是一篇文章,我介紹並幫助我們理解javascript onchange()中的差異,並對onChange()屬性做出反應,以及onBlur()如何反應等同於javascript的onchange()。

How to "onchange" in ReactJS

我希望這可以幫助別人誰是這兩個函數混淆。

1

這裏有幾個問題,第一個可能是this沒有引用jQuery的ajax()方法中的React組件(因爲URL不適用於我)。

試試這個,它會給你一個來自jQuery代碼之外的setState的引用。

searchForTerm: function (term) { 
    const setState = state => this.setState(state); 
    var url = 'http://data.benzinga.com/rest/richquoteDelayed?symbols=' + term; 
    return $.ajax({ 
    url, 
    dataType: 'jsonp', 
    success: function (data) {// your code here 
     console.log("in search", JSON.stringify(data)); 
     setState({data: [JSON.stringify(data)]}); 
     }.bind(this) 
    }); 
}, 

如果這沒有幫助,我會建議固定在控制檯中顯示的所有錯誤,或移除所有導致它們(例子)的代碼。如果有一個簡單的例子說明某些東西不能像你期望的那樣工作,那麼其他人會更容易幫忙。

你會遇到的另一個問題是變量的作用域被定義爲它們被定義的函數。因此在buy()sell(),term是未定義的。

+0

對不起,我沒有檢查你的答案。這似乎是一個反彈的問題。因爲我現在也能夠獲取渲染值,所以我只需要使用'JSON.stringify()',因爲我正在獲取json對象。但它發送新的請求,即使在獲取數據後,屏幕上也不會顯示任何內容。因此,我需要在handleChange中設置一個條件,其中僅在文本框發生更改時才發送ajax請求。這是一個更新[小提琴](https://jsfiddle.net/69z2wepo/49386/)。 –

+0

感謝您看到這一點,我將不勝感激我可以找到一種方法來阻止應用程序發送請求後,在文本框中的任何更改。 'buy'和'sell'是未來的功能,所以現在我沒有打擾,但是謝謝你告訴我這些。對不起,難以通過它。 –