链接的jQuery可排序列表和Backbone集合

时间:2011-11-16 17:35:12

标签: jquery-ui backbone.js jquery-ui-sortable

我仍然在寻找Backbone的方式,过去我总是使用Prototype而不是jQuery,所以如果我做些蠢事,请原谅我。

我正在尝试开发一个包含多个连接的无序列表的UI,其中每个sortable列表由一个单独的Backbone集合表示。我正在使用ICanHaz和Mustache模板,但这对我的问题并不重要。

在列表之间拖动项目时,如何最好地实现集合的自动更新(从一个模型中删除模型并将其插入另一个模型)?我目前正在尝试在jQueryUI Sortable交互中使用receive和remove方法 - 我至少在正确的行上吗?

var WS = {};

(function(ns) {
    ns.Item = Backbone.Model.extend();

    ns.Content = Backbone.Collection.extend({
        model: ns.Item,
        url: location.href,
        initialize: function(el) {
            this.el = $(el);
            this.deferred = this.fetch();
        },
        recalculate: function() {
            var count = this.length;
            this.el.next(".subtotal").html(count);
        },
        setOrder: function() {
            $.ajax({
                url: this.url + "/reorder",
                type: "POST",
                data: "tasks=" + $(this.el).attr("id") + "&" + this.el.sortable("serialize")
            });
        }
    });

    ns.ContentRow = Backbone.View.extend({
        tagName: "li",
        className: "item",
        events: {
            "click .delete":  "destroy"
        },
        initialize: function(options) {
            _.bindAll(this, "render", "destroy");
            this.model.bind("change", this.render);
            this.model.view = this;
        },
        render: function() {
            var row = ich.item(this.model.toJSON());
            $(this.el).html(row);
            return this;
        },
        destroy: function() {
            if (confirm("Really delete?")) {
                this.model.destroy({
                    success: function(model, response) {
                        $(model.view.el).remove();
                    },
                    error: function(model, response) {
                        console.log(response);
                    }
                });
            }
        }
    });

    ns.ListView = Backbone.View.extend({
        initialize: function(collection) {
            this.el = collection.el;
            this.collection = collection;

            this.collection.bind("add", this.addOne, this);
            _.bindAll(this, "addOne");

            this.el.sortable({
                axis: "y",
                connectWith: ".tasks",
                receive: _.bind(function(event, ui) {
                    // do something here?
                }, this),
                remove: _.bind(function(event, ui) {
                    // do something here?
                }, this),
                update: _.bind(function(event, ui) {
                    var list = ui.item.context.parentNode;
                    this.collection.setOrder();
                }, this)
            });
        },
        insert: function(item) {
            var prefix = this.el.parentsUntil('ul').parent().attr("id"),
                view = new ns.ContentRow({
                    model: item,
                    id: prefix + "_" + item.id
                });

            this.el.append(view.render().el);
        },
        addOne: function(item) {
            if (item.isNew()) {
                item.save({}, {
                    success: _.bind(function(model, response) {
                        // I should set id from JSON response when live
                        model.set({ id: this.collection.length });
                        this.insert(model);
                    }, this)
                });
            } else {
                this.insert(item);
            }
        },
        addAll: function() {
            this.collection.each(this.addOne);
        },
        render: function() {
            this.collection.deferred.done(_.bind(function() {
                this.addAll();
            }, this));
        }
    });

    ns.AppView = Backbone.View.extend({
        lists: [],
        initialize: function(holder) {
            holder.find("ul").each(_.bind(function(index, list) {
                var Items = new WS.Content(list),
                    App = new WS.ListView(Items);

                App.render();

                this.lists.push(Items);
            }, this));
        }
    });

})(WS);

$(document).ready(function() {
    var App = new WS.AppView($("#tasks"));
});

2 个答案:

答案 0 :(得分:2)

你走在正确的轨道上。您可能希望将每个可排序元素的id添加到模板中的某个位置。然后,当您收到该事件时,您知道要从集合中添加或删除哪个模型。例如,添加...

<div data-id={{id}}> ... my thing ... </div>

在可排序的调用中获取目标的id属性并调用Collection.add()或remove()

答案 1 :(得分:1)

只需使用Backbone.CollectionView ..它具有开箱即用的内置功能。<​​/ p>

var listView = new Backbone.CollectionView( {
  el : $( "#list1" ),
  sortable : true,
  sortableOptions : {
      connectWith : "#list2"
  },
  collection : new Backbone.Collection
} );

var listView = new Backbone.CollectionView( {
  el: $( "#list2" ),
  sortable : true,
  sortableOptions : {
      connectWith : "#list1"
  },
  collection : new Backbone.Collection
} );