我正在尝试创建一个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>;
}
}
如果没有设置状态,还有其他方法可以解决这个问题吗?
答案 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 )是必要的。