Связанные сортируемые списки jQuery и коллекции Backbone - PullRequest
6 голосов
/ 16 ноября 2011

Я все еще нахожу свой путь с Backbone, и я всегда использовал Prototype вместо jQuery в прошлом, поэтому, пожалуйста, прости меня, если я делаю что-то глупое.

Я пытаюсь разработать пользовательский интерфейс, содержащий несколько связанных неупорядоченных списков, где каждый список sortable представлен отдельной коллекцией Backbone. Я использую шаблоны ICanHaz и Mustache, но это не важно для моего вопроса.

При перетаскивании элементов между списками, как лучше всего добиться автоматического обновления коллекций (удалить модель из одной и вставить ее в другую)? В настоящее время я пытаюсь использовать методы получения и удаления в сортируемом взаимодействии jQueryUI - я хотя бы на правильной линии?

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 ]

2 голосов
/ 18 ноября 2011

Вы на правильном пути. Возможно, вы захотите добавить идентификатор каждого сортируемого элемента в шаблон где-нибудь. Затем, когда вы получаете событие, вы знаете, какую модель добавить или удалить из коллекции. Например добавить ...

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

И в сортируемом вызове получите атрибут id цели и вызовите Collection.add () или remove ()

1 голос
/ 10 января 2014

Просто используйте Backbone.CollectionView .., эта функциональность встроена из коробки.

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