Ember.js + HTML5 拖放购物车演示 [英] Ember.js + HTML5 drag and drop shopping cart demo

查看:25
本文介绍了Ember.js + HTML5 拖放购物车演示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简而言之,我正在尝试重现 jquery-ui 的购物车演示的基本版本:http://jqueryui.com/demos/droppable/shopping-cart.html 带有 ember.js 和 HTML5 原生拖放.

In short, I am trying to reproduce a basic version of jquery-ui's shopping cart demo: http://jqueryui.com/demos/droppable/shopping-cart.html with ember.js and HTML5 native drag n drop.

之前尝试使用 ember + jquery-ui 实​​现拖放并且在使用此解决方案时遇到困难:http://jsfiddle.net/Wu2cu/2/,我看到了pangratz的HTML5解决方案:http://jsfiddle.net/pangratz666/DYnNH/ 并决定试一试.

After previously trying to implement drag and drop with ember + jquery-ui and having difficulty using this solution: http://jsfiddle.net/Wu2cu/2/, I saw pangratz's HTML5 solution: http://jsfiddle.net/pangratz666/DYnNH/ and decided to give it a shot.

我已经分叉了 pangratz 的 jsfiddle,创建了一个 productsController 和一个 addedToCartController,它根据 isAdded 属性过滤 productsController:http://jsfiddle.net/GU8N7/3/

I have forked pangratz's jsfiddle, created a productsController and an addedToCartController that filters the productsController based on an isAdded property: http://jsfiddle.net/GU8N7/3/

这很好用,但是当我尝试使用 #each 迭代器并将唯一的可拖动视图附加到迭代器中的每个对象时,我就卡住了.我希望能够拖动每个产品"对象,当它被放入购物车"区域时,将该对象的 isAdded 属性设置为 true,从而使其显示在购物车"中.

That works fine, but then I get stuck when I try to use an #each iterator and append unique draggable views to each object in the iterator. I want to be able to drag each "product" object, and when it is dropped into the "shopping cart" area, set that object's isAdded property to true, thus having it show up in the "shopping cart."

任何帮助将不胜感激!!

Any help would be greatly appreciated!!

(另外,作为奖励,我想让购物车中的商品可排序,但在第一次跨过桥之前,这可能要求太多了.)

(also as a bonus, I'd like to make the items in the shopping cart sortable, but that's probably too much to ask for until the first bridge is crossed.)

推荐答案

查看下面的代码以获得解决方案(还有一些额外的东西).包括购物车项目的排序(请参阅 JS 末尾的 cartController).

Take a look at the code below for a solution (with a few extras). Sorting of the cart items is included (see cartController at the end of the JS).

这里还有一个工作小提琴:http://jsfiddle.net/ud3323/5uX9H/.

And a working fiddle here: http://jsfiddle.net/ud3323/5uX9H/.

更新:添加了一个拖动图像示例.

UPDATE: Added a drag image example.

把手

<script type="text/x-handlebars" >  
    <b>Available Products</b>
    <br /><br />
    {{#each App.productsController}}
      {{#view App.ProductView contentBinding="this"}}
        {{content.name}}
      {{/view}}<br />
    {{/each}}
    <hr />

    {{#view App.ProductDropTarget 
            dragContextBinding="App.productsController.currentDragItem"}}
    Shopping Cart
    <div style="height: 20px">{{helpText}}</div>
    {{/view}}
    <br />
    {{#each App.cartController}}
      {{#view App.ProductView contentBinding="this"}}
        {{content.name}}
      {{/view}}<br />
    {{/each}}    
</script>​

JavaScript:

App = Ember.Application.create({});

DragNDrop = Ember.Namespace.create();

DragNDrop.cancel = function(event) {
    event.preventDefault();
    return false;
};

DragNDrop.Draggable = Ember.Mixin.create({
    attributeBindings: 'draggable',
    draggable: 'true',
    dragStart: function(event) {
        var dataTransfer = event.originalEvent.dataTransfer;
        dataTransfer.setData('Text', this.get('elementId'));
    }
});

DragNDrop.Droppable = Ember.Mixin.create({
    dragEnter: DragNDrop.cancel,
    dragOver: DragNDrop.cancel,
    drop: function(event) {
        event.preventDefault();
        return false;
    }
});

App.Product = Ember.Object.extend({
    name: null,
    isAdded: null
});

App.ProductView = Ember.View.extend(DragNDrop.Draggable, {
    tagName: 'span',

    // .setDragImage (in #dragStart) requires an HTML element as the first argument
    // so you must tell Ember to create the view and it's element and then get the 
    // HTML representation of that element.
    dragIconElement: Ember.View.create({
        attributeBindings: ['src'],
        tagName: 'img',
        src: 'http://twitter.com/api/users/profile_image/twitter'
    }).createElement().get('element'),

    dragStart: function(event) {
        this._super(event);
        // Let the controller know this view is dragging
        this.setPath('content.isDragging', true);

        // Set the drag image and location relative to the mouse/touch event
        var dataTransfer = event.originalEvent.dataTransfer;
        dataTransfer.setDragImage(this.get('dragIconElement'), 24, 24);
    },

    dragEnd: function(event) {
        // Let the controller know this view is done dragging
        this.setPath('content.isDragging', false);
    }
});

App.ProductDropTarget = Ember.View.extend(DragNDrop.Droppable, {
    tagName: 'div',
    classNames: ['dropTarget'],
    classNameBindings: ['cartAction'],
    helpText: null,

    // This will determine which class (if any) you should add to
    // the view when you are in the process of dragging an item.
    cartAction: Ember.computed(function(key, value) {
        if(Ember.empty(this.get('dragContext'))) {
            this.set('helpText','(Drop Zone)');
            return null;
        }

        if(!this.getPath('dragContext.isAdded')) {
            this.set('helpText', '(Drop to Add)');
            return 'cart-add';
        } else if(this.getPath('dragContext.isAdded')) {
            this.set('helpText', '(Drop to Remove)');
            return 'cart-remove';
        } else {
            this.set('helpText', '(Drop Zone)');
            return null;
        }

    }).property('dragContext').cacheable(),

    drop: function(event) {
        var viewId = event.originalEvent.dataTransfer.getData('Text'),
            view = Ember.View.views[viewId];

        // Set view properties
        // Must be within `Ember.run.next` to always work
        Ember.run.next(this, function() {
            view.setPath('content.isAdded', !view.getPath('content.isAdded'));
        });

        return this._super(event);
    }
});

App.productsController = Ember.ArrayController.create({
    content: [
      App.Product.create({ name: "MacBook Pro", isAdded: false }),
      App.Product.create({ name: "iPhone", isAdded: false }),
      App.Product.create({ name: "iPad", isAdded: true }),
      App.Product.create({ name: "iTV", isAdded: false })
    ],

    currentDragItem: Ember.computed(function(key, value) {
        return this.findProperty('isDragging', true);
    }).property('@each.isDragging').cacheable(),

    productsInCart: Ember.computed(function(key, value) {
        return this.filterProperty('isAdded', true);
    }).property('@each.isAdded').cacheable()

});

App.cartController = Ember.ArrayController.create({    
    content: Ember.computed(function(key, value) {
        var cartItems = this.get('cartItems');

        if(!Ember.empty(cartItems)) {
            // Sort desc by name
            return cartItems.sort(function(a,b){
                if((a.get('name').toLowerCase()) < (b.get('name').toLowerCase()))
                    return -1;
                else return 1;
            });
        }
    }).property('cartItems').cacheable(),

    cartItemsBinding: 'App.productsController.productsInCart'
});

这篇关于Ember.js + HTML5 拖放购物车演示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆