2017-10-20 190 views
0

我正在嘗試製作一個nodemap,用cytoscapejs在反應中進行可視化。 當試圖運行下面的代碼時,我得到錯誤「this.handleTextChange不是一個函數」。
不允許從const內部調用函數嗎?它編譯得很好,但是當點擊節點時,會發生錯誤。CytoscapeJS在React中調用setState函數

import React from 'react'; 
const cytoscape = require('cytoscape'); 
const cycola = require('cytoscape-cola'); 

cytoscape.use(cycola); 

export class NodeBox extends React.Component { 
    constructor(props) { 
     super(props); 
     this.componentDidMount = this.componentDidMount.bind(this); 
     this.state = { 
     description: '' 
     } 

     this.handleTextChange = this.handleTextChange.bind(this); 

    } 
    handleTextChange(text){ 
     this.setState({description: text}); 
    } 

    componentDidMount() { 

     const cy = cytoscape({ 

      container: document.getElementById('cy'), 
      boxSelectionEnabled: false, 
      elements: this.props.elements[0], 
      style: cytoscape.stylesheet() 
       .selector('node') 
       .css({ 
        'label': 'data(name)', 
        'width':'data(size)', 
        'height':'data(size)', 
        'border-width':'3', 
        'border-color': '#618b25', 
        'background-fit':'cover', 
        'background-image': 'data(img)' 

       }) 

       .selector('edge') 
       .css({ 
        'curve-style': 'unbundled-bezier', 
        'control-point-distance': '20px', 
        'control-point-weight': '0.5', // '0': curve towards source node, '1': towards target node. 
        'width': 1, // 
        'line-color': '#618B25', 
        'target-arrow-color': '#618B25', 
        'target-arrow-shape': 'triangle' 
       }) 


      }, 
      'layout':{ 
      'name': 'cola', 'maxSimulationTime': 0 
      } 

    ); 

     cy.panningEnabled(false); 

     cy.on('tap', 'node', function(evt){ 
      var node = evt.target; 
      if (node.id() !== 1){ 
      console.log(node.data('description')); 

      this.handleTextChange(node.data('description')); 
      } 
     }); 
     cy.panningEnabled(false); 
    } 
    render() { 
     return <div> <div style ={{'height':300, 'width':'100%'}} id="cy"> </div><h1 id="desc" style={{textAlign:"center"}}>{this.state.description}</h1></div>; 
    } 
} 

是否有任何其他方式來解決這個問題,而無需設置狀態?

+0

你永遠不需要綁定'componentDidMount'。另外,「發生錯誤」,哪一個? – JulienD

回答

1

1)您不需要將componentDidMount綁定到此。這樣,刪除以下

this.componentDidMount = this.componentDidMount.bind(this);

2)使用箭頭函數來詞法結合此,在此值保持相同,其中的箭頭函數定義的上下文。因此,除了更改爲以下

cy.on('tap', 'node',(evt) => { 
     var node = evt.target; 
     if (node.id() !== 1){ 
     console.log(node.data('description')); 

     this.handleTextChange(node.data('description')); 
     } 
}); 

:大部分的發射器(如EventEmitter的節點,jQuery的聽衆,或Cytoscape中)要使用Function.apply()設置this在回調到發射器對象---這是爲什麼(2)是必要的。