Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
237 views
in Technique[技术] by (71.8m points)

javascript - Ember.js draggable and droppable jqueryUI / native Drag and drop mixin

I need to create items that have drag and drop and sort functionality. So an item can be dragged into another item.

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.

Please can anyone tell me the best way to do this via mixins or subclassing or ... ?

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 ?

Is it best to use jqueryUI or the html5 drag and drop api or something else ?

Thanks for the help Rick

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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); };
      }
    });
  }
});

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']

});

the Resizable Mixin:

  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']
});

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.

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* } ).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...