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

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

我仍在使用 Backbone 寻找自己的方式,过去我一直使用 Prototype 而不是 jQuery,所以如果我做了一些愚蠢的事情,请原谅我。

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

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

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

最佳答案

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

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

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

关于jquery-ui - 链接的 jQuery 可排序列表和 Backbone 集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8156067/

相关文章:

html - 如何使 <tr> 中的单个 <td> 元素不可排序(jquery ui)

rest - 如何在 Backbone.js 中使用 Haskell Snap

javascript - 在backbonejs中删除模型并更新 View

javascript - 仅当我们传递 async :false as the parameter for fetch() method 时,Backbone Js 才会获取值

javascript - HTML 布局丢失

jquery - 谷歌地图 + jQuery : rendering bug

javascript - 通知 Polymer dom-repeat 对本地 DOM 的更改

jquery - 使用 jQuery 实现内联文本元素的交叉淡入淡出

php - 将可排序列表转换为查询并检索并再次显示

jquery-ui - JQuery sortable(具有各种高度的项目)移动到第一个或最后一个位置很麻烦