2016-07-17 26 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'是未来的功能,所以现在我没有打扰,但是谢谢你告诉我这些。对不起,难以通过它。 –