2016-08-18 54 views
0

我无法弄清楚下面的代码有什么问题。点击提交按钮后,表格行不会更新。React js - 在ajax调用后更新表格行

我认为this.setState({data:arr})里面的manipulateData()会做到这一点,但它没有。

任何帮助将不胜感激。谢谢。

/* 
v1.0 
*/ 

var cols = [ 
    { key: 'sessionid1', label: 'Session 1' }, 
    { key: 'type', label: 'Type' }, 
    { key: 'sessionid2', label: 'Session 2' } 
]; 

var data = [ 
    { id: 1, sessionid1: 'acb20dc0', type: 'CLIENT', sessionid2: 'acb20dc0' }, 
    { id: 2, sessionid1: 'acb20dc0', type: 'CLIENT', sessionid2: 'acb20dc0' }, 
    { id: 3, sessionid1: 'acb20dc0', type: 'SERVER', sessionid2: 'acb20dc0' }, 
    { id: 4, sessionid1: 'acb20dc0', type: 'CLIENT', sessionid2: 'acb20dc0' } 
]; 

var Logviewer = React.createClass({ 
    getInitialState: function() { 
     return { 
      text: '', 
      kibana: false, 
      data: [], 
      cols: cols 
     }; 
    }, 

    render: function(){ 
     return(
      <div> 
       <div className="row header"> 
        <Header 
        text={this.state.text} 
        kibana={this.state.kibana} 
        /> 
       </div> 

       <div className="row"> 
        <TabularData cols={this.props.cols} data={this.state.data} /> 
        <Graphic /> 
       </div> 
      </div> 
     ); 
    } 
}); 

var Header = React.createClass({ 
    handleSubmit: function(){ 
     console.log('submit - ', this.state.data); 
     $.ajax({ 
       url: 'http://10.164.98.27:7474/db/data/cypher', 
       dataType: 'json', 
       type: 'POST', 
       data: this.state.queryData, 
       success: function(data) { 
       console.log('data: ', data); 
       // manipulate data first to correct format 
       this.manipulateData(data); 
       }.bind(this), 
       error: function(xhr, status, err) { 
       //this.setState({data: this.state.data}); 
       console.error(this.props.url, status, err.toString()); 
      }.bind(this) 
     });  
    }, 

    manipulateData: function(obj){ 
     console.log('manipulateData'); 
     var arr = []; 
     for(var i = 0; i < obj.data.length; i++){ 
      //console.log('size: ', i); 
      arr.push({id: i, sessionid1: obj.data[i][0].data.sessionid, type: obj.data[i][1], sessionid2: obj.data[i][2].data.sessionid});  
     } 
     console.log('manipulated obj: ', arr); 
     this.setState({data: arr});// this was supposed to update the table content but doesn't 
     $('#tabularDataTable').show(); 
    }, 

    handleCheckbox: function(){ 
     if($('#leftHandSide').is(':visible')){ 
      $('#leftHandSide, #rightHandSide').hide(); 
     } 
     else{ 
      $('#leftHandSide, #rightHandSide').show(); 
     } 
    }, 

    handleSessionIdChange: function(e){ 
     console.log('sessionId: ', e.target.value); 
     var query = { 
       "query" : "MATCH (a {sessionid : '" + e.target.value + "'})-[r*]-(b) UNWIND r AS rel RETURN distinct startNode(rel) AS a, type(rel), endNode(rel) AS b", 
        "params" : { } 
     } 
     this.setState({queryData: query}); 
    }, 

    render: function() { 
     return (
     <div className="columns small-12"> 
      <div className="columns small-2 logo"> 
       <img src="../images/247ToolsLogo.png" className="tools-logo" title="247 tools logo" /> 
      </div> 
      <div className="columns small-2 tool-name">Log Viewer</div> 
      <div className="columns small-8 search"> 
       <form className="sessionIdForm"> 
        <input 
         type="text" 
         placeholder="Session Id" 
         //defaultValue={this.state.text} 
         defaultValue={this.props.text} 
         onBlur={this.handleSessionIdChange} 
        /> 
        <a href="#" id="submit" onClick={this.handleSubmit} className="button">Find related session ids</a> 
        <div id="kibana"><input type="checkbox" id="kibanaCheckbox" checked={this.props.kibana} onClick={this.handleCheckbox} /><label htmlFor="kibanaCheckbox">Redirect to Kibana</label></div> 
       </form> 
      </div> 
     </div> 
    ); 
    } 
}); 

var TabularData = React.createClass({ 
    render: function(){ 
     console.log('TabularData - 1'); 
     return(
      <div className="columns small-6" id="leftHandSide"> 
       <h4>Table View</h4> 
       <Table cols={this.props.cols} data={this.props.data} /> 
      </div> 
     ); 
    } 
}); 

var Table = React.createClass({ 
    render: function() { 
     console.log('Table - render'); 
     var headerComponents = this.generateHeaders(), 
      rowComponents = this.generateRows(); 

     return (
      <table id="tabularDataTable"> 
       <thead>{headerComponents}</thead> 
       <tbody>{rowComponents}</tbody> 
      </table> 
     ); 
    }, 

    generateHeaders: function() { 
     var cols = this.props.cols; // [{key, label}] 

     // generate our header (th) cell components 
     return cols.map(function(colData) { 
      return <th key={colData.key}>{colData.label}</th>; 
     }); 
    }, 

    generateRows: function() { 
     var cols = this.props.cols, // [{key, label}] 
      data = this.props.data; 

     return data.map(function(item) { 
      // handle the column data within each row 
      var cells = cols.map(function(colData, i) { 
       if(i === 0 || i === 2){ 
        return <td key={i}><a target="_blank" href={"https://logview01.pool.sv2.247-inc.net/#/discover?time:(from:now-30d,mode:quick,to:now))&amp;_a=(columns:!(_source),index:'logstash-shared-services-*',interval:auto,query:(query_string:(analyze_wildcard:!t,query:&quot;" + item[colData.key] + "&quot;)),sort:!('@timestamp',desc))&amp;_g=(refreshInterval:(display:Off,pause:!f,section:0,value:0),time:(from:now-30d,mode:quick,to:now))"}>{item[colData.key]}</a></td>; 
       } 
       else{ 
        return <td key={i}>{item[colData.key]}</td>; 
       } 
      }); 
      return <tr key={item.id}>{cells}</tr>; 
     }); 
    } 
}); 

var Graphic = React.createClass({ 
    render: function(){ 
     return(
      <div className="columns small-6" id="rightHandSide"> 
       <h4>Graphic View</h4> 
      </div> 
     );  
    } 
}); 

ReactDOM.render(
    <Logviewer data={data} cols={cols} />, 
    document.getElementById('content') 
); 
+0

您正通过'this'设置'Header'组件的'state'而不是'LogViewer'。通过'props'将'handleSubmit'方法传递给'LogViewer'中的'Header'并在那里更新'state'。 – Joe

回答

1

的问题是,你设置的状态为Header组件。所以会发生什么是你的LogViewer有它自己的状态包含一组数据,而你的Header也有它自己的状态与一组单独的数据。由于TabularData组件从LogViewer的状态(通过道具)获取数据,因此它从不知道有关更新数据的任何信息。

你可以用几种不同的方法解决这个问题。一种方法是将数据提取和setState调用转移到LogViewer。另一是从LogViewer传下一个回调函数,作为道具,到Header组件,这样的事情:

<Header 
    text={this.state.text} 
    kibana={this.state.kibana} 
    onDataFetch={(data) => { this.setState({ data }) } 
/> 

,然后在你的Header组件,你叫this.props.onDataFetch(arr)而非this.setState({data: arr})

+0

我用你的第二个建议,回调,它运作良好。谢谢。 –

+0

不用担心。如果没有别的东西,请标记为正确:) – tobiasandersen