React.js:对象的建模选择

时间:2014-01-02 09:48:59

标签: javascript reactjs

画布上有几个点,单击一个点会显示一个工具栏,允许编辑所选点的 x y 坐标。

JSFiddle

我试过了:

/**
 * @jsx React.DOM
 */
var EditorCanvas = React.createClass({
    getInitialState: function() {
        return {
            points: [
                {
                    x: 50,
                    y: 100
                },
                {
                    x: 200,
                    y: 50
                }
            ],
            selected: null
        };
    },

    render: function() {
        return <div>
            <Toolbar point={this.state.selected}/>
            <div id="canvas">
                {this.state.points.map(this.renderPoint)}
            </div>
        </div>;
    },

    renderPoint: function(point) {
        return <Point x={point.x} y={point.y} onClick={this.selectPoint.bind(this, point)}/>
    },

    selectPoint: function(point) {
        this.setState({selected: point});
    },

    renderToolbar: function() {
        var selected = this.state.selected;
        if (!selected) {
            return <div/>
        }
        return <div>
            x:<input type="number" value={selected.x} onInput={this.xChange}/>
            &middot;
            y:<input type="number" value={selected.y} onInput={this.yChange}/>
        </div>
    }
});

var Toolbar = React.createClass({
    render: function() {
        var point = this.props.point;
        if (!point) {
            return <div id="toolbar"/>;
        }
        return <div id="toolbar">
            x:<input type="number" value={point.x} onInput={this.xChange}/>
            &middot;
            y:<input type="number" value={point.y} onInput={this.yChange}/>
        </div>;
    },

    xChange: function(e) {
        this.setState({selected: {x: e.target.value}});
    },
    yChange: function(e) {
        this.setState({selected: {y: e.target.value}});
    }
});


var Point = React.createClass({
    render: function() {
        var style = {
            left: this.props.x + 'px',
             top: this.props.y + 'px'
        };
        return <div style={style} className="point" onClick={this.props.onClick}/>
    }
});

React.renderComponent(
    <EditorCanvas/>,
    document.body
);

它不起作用,因为state.selected是点对象的副本,而不是指向它的指针。

我怎样才能让它发挥作用?

1 个答案:

答案 0 :(得分:3)

您的EditorCanvas期望其状态中的points数组成为事实的来源,但工具栏中的更改并未使其返回到该数组。工具栏创建自己的状态,不会持久保存到EditorCanvas。我建议将所有状态保存在EditorCanvas中,并通过回调将更改从工具栏传递到画布。

使用JSFiddle:http://jsfiddle.net/krza5/2/

var EditorCanvas = React.createClass({
    getInitialState: function() {
        return {
            points: [
                {
                    x: 50,
                    y: 100
                },
                {
                    x: 200,
                    y: 50
                }
            ],
            selected: null
        };
    },

    render: function() {
        return <div>
            <Toolbar point={this.state.selected}
                onXChange={this.setSelectedX}
                onYChange={this.setSelectedY}/>
            <div id="canvas">
                {this.state.points.map(this.renderPoint)}
            </div>
        </div>;
    },

    renderPoint: function(point) {
        return <Point point={point} onClick={this.selectPoint.bind(this, point)}/>
    },

    selectPoint: function(point) {
        this.setState({selected: point});
    },

    setSelectedX: function(event) {
        var point = this.state.selected;
        point.x = event.target.value;
        this.forceUpdate();
    },

    setSelectedY: function(event) {
        var point = this.state.selected;
        point.y = event.target.value;
        this.forceUpdate();
    }
});

var Toolbar = React.createClass({
    render: function() {
        var point = this.props.point;
        if (!point) {
            return <div id="toolbar"/>;
        }
        return <div id="toolbar">
            x:<input type="number" value={point.x} onInput={this.props.onXChange}/>
            &middot;
            y:<input type="number" value={point.y} onInput={this.props.onYChange}/>
        </div>;
    }
});

var Point = React.createClass({
    render: function() {
        var style = {
            left: this.props.point.x + 'px',
             top: this.props.point.y + 'px'
        };
        return <div style={style} className="point" onClick={this.props.onClick}/>
    }
});