CytoscapeJS在React

时间:2017-10-20 11:33:52

标签: reactjs cytoscape.js

我正在尝试创建一个nodemap,使用cytoscapejs进行可视化反应。 当试图运行以下代码时,我得到错误“this.handleTextChange不是一个函数” 不允许从const中调用函数吗?它编译得很好,但是当点击节点时,会发生错误。

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>;
    }
}

如果没有设置状态,还有其他方法可以解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

1)您不需要将componentDidMount绑定到此。所以,删除以下

public class Utilisateur { [Required] [DisplayName("Login")] public string Name { get; set; } [Required] [DisplayName("Mot de passe")] [DataType(DataType.Password)] public string Pass { get; set; } } public class TestController : Controller { public ActionResult Index() { using (var ctx = new BddDataClassesDataContext()) { var lstUtil = ctx.Utilisateur; return View(lstUtil); } } } index.cshtml: @model IEnumerable<WebApplication1.Models.Utilisateur> @{ ViewBag.Title = "Index"; } <h2>Index</h2> <p> @Html.ActionLink("Create New", "Create") </p> <table class="table"> <tr> <th> @Html.DisplayNameFor(model => model.Name) </th> <th> @Html.DisplayNameFor(model => model.Pass) </th> <th></th> </tr> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.Name) </td> <td> @Html.DisplayFor(modelItem => item.Pass) </td> <td> @Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) | @Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) | @Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ }) </td> </tr> } </table>

2)使用箭头函数对其进行词法绑定,其值保持与定义箭头函数的上下文相同。所以,改为以下

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

除此之外:大多数发射器(如Node中的EventEmitter,jQuery侦听器或Cytoscape)将使用cy.on('tap', 'node',(evt) => { var node = evt.target; if (node.id() !== 1){ console.log(node.data('description')); this.handleTextChange(node.data('description')); } }); 在发射器对象的回调中设置Function.apply() - 这就是原因(2 )是必要的。