问题描述
我需要创建具有拖放和排序功能的项目。所以一个项目可以被拖入另一个项目。
I need to create items that have drag and drop and sort functionality. So an item can be dragged into another item.
我已经看到一些解决方案,通过一个mixin拖动,并使用这个mixin创建一个可拖动的视图,然后创建另一个视图
I have seen a few solutions to do drag via a mixin and create a draggable view using this mixin and then creating another view from droppable via the droppable mixin.
但是,我需要每个项目/视图具有可拖放,可放置和可排序的功能。
But i need each item / view to have draggable, droppable and sortable functionality.
请任何人告诉我最好的方法,通过mixins或sublassing或...?
Please can anyone tell me the best way to do this via mixins or subclassing or ... ?
我也可以创建一个jqueryUi mixin作为基础mixin和然后在创建可拖动,可抽取和可排序的mixins时使用该mixin?这是可能吗?
Also can i create a jqueryUi mixin as a base mixin and then use that mixin when creating the draggable, droppable and sortable mixins ? is this possible ?
最好使用jqueryUI或html5拖放api或其他东西?
Is it best to use jqueryUI or the html5 drag and drop api or something else ?
Rick
推荐答案
不知道如果您看到Katz的代码,但我正在使用它来制作一个视图:Droppable,Draggable, ...或jQuery UI支持的任何其他交互。所以你定义一个基础Mixin,你将在所有jQuery UI交互中使用Mixins:
Not sure if you saw the code by Katz here, but I'm using this to make a View: Droppable, Draggable, ... or any other interaction supported by jQuery UI. So you define a base Mixin, which you will use in all jQuery UI interaction Mixins:
// Create a new mixin for jQuery UI widgets using the new SproutCore 2.0
// mixin syntax.
JQ.Base = Ember.Mixin.create({
// When SproutCore creates the view's DOM element, it will call this
// method.
didInsertElement: function() {
this._super();
// Make jQuery UI options available as SproutCore properties
var options = this._gatherOptions();
// Make sure that jQuery UI events trigger methods on this view.
this._gatherEvents(options);
// Create a new instance of the jQuery UI widget based on its `uiType`
// and the current element.
var ui = jQuery.ui[this.get('uiType')](options, this.get('element'));
// Save off the instance of the jQuery UI widget as the `ui` property
// on this SproutCore view.
this.set('ui', ui);
},
// When SproutCore tears down the view's DOM element, it will call
// this method.
willDestroyElement: function() {
var ui = this.get('ui');
if (ui) {
// Tear down any observers that were created to make jQuery UI
// options available as SproutCore properties.
var observers = this._observers;
for (var prop in observers) {
if (observers.hasOwnProperty(prop)) {
this.removeObserver(prop, observers[prop]);
}
}
ui._destroy();
}
},
// Each jQuery UI widget has a series of options that can be configured.
// For instance, to disable a button, you call
// `button.options('disabled', true)` in jQuery UI. To make this compatible
// with SproutCore bindings, any time the SproutCore property for a
// given jQuery UI option changes, we update the jQuery UI widget.
_gatherOptions: function() {
var uiOptions = this.get('uiOptions'), options = {};
// The view can specify a list of jQuery UI options that should be treated
// as SproutCore properties.
uiOptions.forEach(function(key) {
options[key] = this.get(key);
// Set up an observer on the SproutCore property. When it changes,
// call jQuery UI's `setOption` method to reflect the property onto
// the jQuery UI widget.
var observer = function() {
var value = this.get(key);
this.get('ui')._setOption(key, value);
};
this.addObserver(key, observer);
// Insert the observer in a Hash so we can remove it later.
this._observers = this._observers || {};
this._observers[key] = observer;
}, this);
return options;
},
// Each jQuery UI widget has a number of custom events that they can
// trigger. For instance, the progressbar widget triggers a `complete`
// event when the progress bar finishes. Make these events behave like
// normal SproutCore events. For instance, a subclass of JQ.ProgressBar
// could implement the `complete` method to be notified when the jQuery
// UI widget triggered the event.
_gatherEvents: function(options) {
var uiEvents = this.get('uiEvents') || [], self = this;
uiEvents.forEach(function(event) {
var callback = self[event];
if (callback) {
// You can register a handler for a jQuery UI event by passing
// it in along with the creation options. Update the options hash
// to include any event callbacks.
options[event] = function(event, ui) { callback.call(self, event, ui); };
}
});
}
});
然后定义Draggable Mixin:
And then define the Draggable Mixin:
JQ.Draggable = Ember.Mixin.create( JQ.Base, {
uiType: 'draggable',
uiOptions: ['disabled', 'addClasses', 'appendTo', 'axis', 'cancel', 'connectToSortable', 'containment', 'cursor',
'delay', 'distance', 'grid', 'handle', 'snap', 'snapMode', 'stack'],
uiEvents: ['create', 'start', 'drag', 'stop']
});
可调整大小的混音:
JQ.Resizable = Ember.Mixin.create( JQ.Base, {
uiType: 'resizable',
uiOptions: ['disabled', 'alsoResize', 'animate', 'animateDuration', 'animateEasing', 'aspectRatio', 'autoHide', 'cancel',
'containment', 'delay', 'distance', 'ghost', 'grid', 'handles', 'helper', 'maxHeight', 'maxWidth', 'minHeight',
'minWidth'],
uiEvents: ['create', 'start', 'resize', 'stop']
});
基本上每个UI交互都要定义 uiType
(可拖放,可放置,可排序等),交互的 uiOptions
(由mixin观察)和 uiEvents
您要在View中实现的交互。
Basically for each UI interaction you want to define the uiType
(draggable, droppable, sortable, etc.), the uiOptions
of the interaction (observed by the mixin), and the uiEvents
of the interaction that you want to implement in your View.
通过在您的View中包含JQ.Draggable和JQ.Droppable,它会自动变为可拖放和可拖放的+您可以在View中更改其选项,并反映出UI插件,例如 this.set('delay',900)
,并在您的View中实现插件事件,例如 drag:function(){/ *拖动时执行某些操作* \}
)
By including JQ.Draggable and JQ.Droppable in your View, it automatically becomes draggable and droppable + you are able to change its options in your View and reflect those changes on the UI plugin, e.g. this.set('delay', 900)
, and implement the plugin events in your View, e.g. drag: function(){ /* do something when dragging*\ }
).
这篇关于Ember.js draggable和droppable jqueryUI / native拖放mixin的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!