4

I have the following JavaScript code, which works as expected...

/** @jsx React.DOM */

var TreeView = React.createClass({
  render: function() {    
  return <div ref="treeview"></div>;  
  },
 componentDidMount: function() {
   console.log(this.props.onChange);
   var tree = $(this.refs.treeview.getDOMNode()).kendoTreeView({
     dataSource: ...,
     dataTextField: "Name",
     select: this.props.onChange
     }
   });
 }
});

var MyApp = React.createClass({   
  onChange: function(e) {    
    console.log(e);
    this.setState({key: e});
  },
  render: function() {
    return (
      <div>
        <TreeView onChange={this.onChange}/>  
        <GridView />         
      </div>
    );
  }
});

However, with the kendo treeview, on selecting a tree node, the whole node is passed. To get at the underlying key, I would need to process the node as follows:

select: function(e) { 
  var id = this.dataItem(e.node).id;
  this.props.onChange(id);
}

However I've obviously not quite got it right since, and here please excuse my noobness, it seems that in the working instance a reference to the function is being used, whereas in the non-working instance, the function is actually being executed... Or something like that: the error message being returned is:

Cannot call method 'onChange' of undefined.

So what would I need to do to be able to reference the function which extracts the key before calling the onChange method? Note that, if my understanding is correct, onChange needs to be executed in the context of the MyApp class so that any child components will get notified on the change.

EDIT: I've tried using partial application but am still not quite there. I've updated the onChange routine to take a function which returns the key from the node

onChange: function(getKey, e) {      
  this.setState({Key: getKey(e)});
},

But am not sure how to wire it all up.

peak
  • 105,803
  • 17
  • 152
  • 177
Simon Woods
  • 2,223
  • 4
  • 27
  • 34
  • the html in the return statement shouldn't work in JS. so there is probably an error that is causing MyApp to be undefined. You should see something like ... `SyntaxError: Unexpected token <` – Shanimal Jan 03 '14 at 16:30
  • @Shanimal. Thx. Reactjs has a tool, JSX, which permits html-like statements in js. I've just edited the js to reflect the reference to the JSX lib for clarity – Simon Woods Jan 03 '14 at 16:32
  • Cool. So I have to check that out. Im still confused though, it looks like you are doing everything correctly, but are you including the JSX Transformer in your html? – Shanimal Jan 03 '14 at 16:40
  • 1
    I added the line at the top. I don't really know much about JSX but that seems to be enough to make it work. Well that and the script ref in the index.html – Simon Woods Jan 03 '14 at 16:46

1 Answers1

4

Your code looks mostly right. I believe your only problem is that the select callback you're passing to the treeview is being called with the wrong scope. Note that you're using this to mean two different things within the function (once for the actual tree view object and the other for the React component). Easiest solution is probably to store a reference to the onChange function like so:

componentDidMount: function() {
   var onChange = this.props.onChange;
   var tree = $(this.refs.treeview.getDOMNode()).kendoTreeView({
     dataSource: ...,
     dataTextField: "Name",
     select: function(e) { 
       var id = this.dataItem(e.node).id;
       onChange(id);
     }
   });
 }

Hope this helps.

Sophie Alpert
  • 139,698
  • 36
  • 220
  • 238