如何为拖动目的克隆反应元素
How to clone a react element for dragging purposes
所以,我有一个列表,我现在可以使用 react-draggable 将元素 (div) 拖出该列表。 React-draggable 使原始元素可拖动(有意义),但我需要拖动原始元素的副本(克隆),并将原始元素保持在原位。
所以,我有包含元素的实体列表,每个元素都有一个调用父元素列表的事件,希望克隆原始班次,并用可拖动元素包装原始元素以使其可拖动。一旦它 draggable/created,我想将它附加到屏幕上的不同元素,并将初始位置放在鼠标光标所在的中心。
我想做的最后一件事是,如果将元素放在 "wrong" 位置,它应该将 return 动画化(我猜是反应运动)到原始位置。最初它是用 Jquery 编写的,我显然知道如何使用 jquery-ui 来实现这一切,但我有点坚持使用反应方式。
var Scheduler = require('scheduler/components/Scheduler');
var ShiftTypeDiv = require('scheduler/components/ShiftType');
var Draggable = ReactDraggable;
var ShiftTypes = React.createClass({
getInitialState: function() {
return ({
shiftTypes: SchedulerStore.getShiftTypes(),
clonedItem: null
})
},
handleStart: function (event, ui) {
console.log('handleStart: ', event);
console.log('Position: ', ui.position);
},
cloneShiftBeforeDrag: function (item) {
console.log('cloning', item);
React.cloneElement(item);
ReactDOM.findDOMNode
this.setState({
clonedItem: item
});
},
handleDrag: function (event, ui) {
console.log('handledrag: ',ui);
console.log('dragging');
},
handleStop: function (event, ui) {
console.log('handleStop: ', event);
console.log('Position: ', ui.position);
},
render: function() {
var self = this;
shiftTypesJSX = this.state.shiftTypes.map(function(shiftType,index) {
return (
<ShiftTypeDiv shiftType={shiftType} key={index} cloneShiftBeforeDrag={self.cloneShiftBeforeDrag.bind(null, shiftType)} />
)
});
return (
<div >
<div className="box-header">
<ul>
<li className="title title-name">Shift Templates</li>
<li className="title edit-link"></li>
</ul>
</div>
<div className="box-content" data-onboarding-item="2">
<Draggable
handle=".ui-draggable"
zIndex={100}
onStart={this.handleStart}
onDrag={this.handleDrag}
onStop={this.handleStop}
>
<div className="draggable-custom-shift ui-draggable ui-draggable-handle"><strong>New Shift</strong></div>
</Draggable>
</div>
<div className="box-content" id="shift-templates">
<div className="row-fluid">
<div id="shift-types-list" className="span12">
<div className="input-group shift-type-filter-form">
<input type="text" className="span12" id="shift-type-filter" placeholder="Filter shift templates" />
<i className="icon-remove-sign" id="remove-shift-type-filter"></i>
</div>
<div id="shift_types" >
{shiftTypesJSX}
</div>
</div>
</div>
</div>
</div>
)
}
})
module.exports = ShiftTypes;
var Scheduler = require('scheduler/components/Scheduler').default;
var Draggable = ReactDraggable;
var ShiftTypeDiv = React.createClass({
handleStart: function (event, ui) {
console.log('cloning');
this.props.cloneShiftBeforeDrag(this);
},
handleDrag: function (event, ui) {
console.log('handledrag: ',ui);
console.log('dragging');
},
handleStop: function (event, ui) {
console.log('handleStop: ', event);
console.log('Position: ', ui);
this.setState({
})
},
render: function() {
shiftType = this.props.shiftType;
return (
<Draggable
bounds="body"
zIndex={100}
onStart={this.handleStart}
onDrag={this.handleDrag}
onStop={this.handleStop}
position={null}
>
<div className="draggable-shift-type ui-draggable ui-draggable-handle" data-shift-type-id={shiftType.id}>
{shiftType.name} <span dangerouslySetInnerHTML={{__html:shiftType.start_time + '-' + shiftType.end_time}}></span>
</div>
</Draggable>
)
}
})
module.exports = ShiftTypeDiv;
由于没有人回答,这就是我的解决方案。当组件识别出它正在被拖动时(例如 prop dragged = true),它只会添加另一个类似的移动。我仍然没有尝试实现它的所有 "animation" 部分,但可以使用 css 或者 react-motion。
克隆一个react元素可以参考这个问题:
这是API:
React.cloneElement(
element,
[props],
[...children]
)
所以,我有一个列表,我现在可以使用 react-draggable 将元素 (div) 拖出该列表。 React-draggable 使原始元素可拖动(有意义),但我需要拖动原始元素的副本(克隆),并将原始元素保持在原位。 所以,我有包含元素的实体列表,每个元素都有一个调用父元素列表的事件,希望克隆原始班次,并用可拖动元素包装原始元素以使其可拖动。一旦它 draggable/created,我想将它附加到屏幕上的不同元素,并将初始位置放在鼠标光标所在的中心。 我想做的最后一件事是,如果将元素放在 "wrong" 位置,它应该将 return 动画化(我猜是反应运动)到原始位置。最初它是用 Jquery 编写的,我显然知道如何使用 jquery-ui 来实现这一切,但我有点坚持使用反应方式。
var Scheduler = require('scheduler/components/Scheduler');
var ShiftTypeDiv = require('scheduler/components/ShiftType');
var Draggable = ReactDraggable;
var ShiftTypes = React.createClass({
getInitialState: function() {
return ({
shiftTypes: SchedulerStore.getShiftTypes(),
clonedItem: null
})
},
handleStart: function (event, ui) {
console.log('handleStart: ', event);
console.log('Position: ', ui.position);
},
cloneShiftBeforeDrag: function (item) {
console.log('cloning', item);
React.cloneElement(item);
ReactDOM.findDOMNode
this.setState({
clonedItem: item
});
},
handleDrag: function (event, ui) {
console.log('handledrag: ',ui);
console.log('dragging');
},
handleStop: function (event, ui) {
console.log('handleStop: ', event);
console.log('Position: ', ui.position);
},
render: function() {
var self = this;
shiftTypesJSX = this.state.shiftTypes.map(function(shiftType,index) {
return (
<ShiftTypeDiv shiftType={shiftType} key={index} cloneShiftBeforeDrag={self.cloneShiftBeforeDrag.bind(null, shiftType)} />
)
});
return (
<div >
<div className="box-header">
<ul>
<li className="title title-name">Shift Templates</li>
<li className="title edit-link"></li>
</ul>
</div>
<div className="box-content" data-onboarding-item="2">
<Draggable
handle=".ui-draggable"
zIndex={100}
onStart={this.handleStart}
onDrag={this.handleDrag}
onStop={this.handleStop}
>
<div className="draggable-custom-shift ui-draggable ui-draggable-handle"><strong>New Shift</strong></div>
</Draggable>
</div>
<div className="box-content" id="shift-templates">
<div className="row-fluid">
<div id="shift-types-list" className="span12">
<div className="input-group shift-type-filter-form">
<input type="text" className="span12" id="shift-type-filter" placeholder="Filter shift templates" />
<i className="icon-remove-sign" id="remove-shift-type-filter"></i>
</div>
<div id="shift_types" >
{shiftTypesJSX}
</div>
</div>
</div>
</div>
</div>
)
}
})
module.exports = ShiftTypes;
var Scheduler = require('scheduler/components/Scheduler').default;
var Draggable = ReactDraggable;
var ShiftTypeDiv = React.createClass({
handleStart: function (event, ui) {
console.log('cloning');
this.props.cloneShiftBeforeDrag(this);
},
handleDrag: function (event, ui) {
console.log('handledrag: ',ui);
console.log('dragging');
},
handleStop: function (event, ui) {
console.log('handleStop: ', event);
console.log('Position: ', ui);
this.setState({
})
},
render: function() {
shiftType = this.props.shiftType;
return (
<Draggable
bounds="body"
zIndex={100}
onStart={this.handleStart}
onDrag={this.handleDrag}
onStop={this.handleStop}
position={null}
>
<div className="draggable-shift-type ui-draggable ui-draggable-handle" data-shift-type-id={shiftType.id}>
{shiftType.name} <span dangerouslySetInnerHTML={{__html:shiftType.start_time + '-' + shiftType.end_time}}></span>
</div>
</Draggable>
)
}
})
module.exports = ShiftTypeDiv;
由于没有人回答,这就是我的解决方案。当组件识别出它正在被拖动时(例如 prop dragged = true),它只会添加另一个类似的移动。我仍然没有尝试实现它的所有 "animation" 部分,但可以使用 css 或者 react-motion。
克隆一个react元素可以参考这个问题:
这是API:
React.cloneElement(
element,
[props],
[...children]
)