2

li選択可能なビューとして要素を使用してアプリを作成しようとしています。このアプリでは、クリックアンドドラッグインターフェイスを使用して複数の要素を選択する必要があります。このため、Backbone.jsを使用して要素の状態とビューを追跡し、選択UIにはjQueryUISelectableを使用しています。

現在、私が持っている唯一の構造は、メインのアプリビュー、li要素のモデルとビュー、およびモデルのコレクションです。

メインのアプリビューが選択された要素を追跡して操作できるように、これを構造化するための最良の方法は何ですか?

4

1 に答える 1

3

これは私がかなり前にしたことの要約版です。必要なものに対しては過度に複雑かもしれませんが、機能しました。プログラムでアイテムを選択/選択解除し、jQuery-selectableで処理できるようにする必要がありました。そのため、モデルにSelected属性があります。このアプローチを使用すると、UIですべてを実行できmodel.set({Selected:true})、すべての同期が維持されます。

それを実証するためにjsFiddleを追加しました:http://jsfiddle.net/phoenecke/VKRyS/5/

次に、アプリビューで、次のような操作を実行できます。

_.each(collection.where({Selected:true}), function(item){
    // do something with item
});

それが役に立てば幸い。

ItemView:

var ItemView = Backbone.View.extend({

  tagName: "li",

  initialize: function(options) {
     this.listenTo(this.model, 'change:Selected', this.selectedChanged);
  },

  render: function() {
     this.$el.html(template(this.model));
     // add cid as view's id, so it can be found when jQuery-selectable says selection changed (in ListView below).
     this.$el.attr({
        'id': this.model.cid
     });
     this.selectedChanged();
     return this;
  },

  selectedChanged: function() {
     // respond to model's Selected change event.
     // This way, you can programmatically change it, ie. model.set({Selected:true}).
     // but usually this class is already on the view, 
     // since jQuery selectable adds/removes it. it does not hurt to re-add it,
     // but you could check for the class.
     if(this.model.get('Selected')) {
        this.$el.addClass('ui-selected');
     } else {
        this.$el.removeClass('ui-selected');
     }
  }
});

リストビュー:

var ListView = Backbone.View.extend({
    initialize: function(options) {
        this.listenTo(this.collection, 'reset', this.render);
        this._views = {};
    },

    render: function() {
        this.collection.each(function(item) {
            var view = new ItemView({model: item});
            this._views[item.cid] = view;
            this.$el.append(view.render().el);
        }, this);
        this.setupSelectable();
    },

    setupSelectable: function() {
        var thisView = this;
        // Set up JQuery UI Selectable
        this.$el.selectable({
            filter: 'li',
            selected: function(event, ui) {
                var cid = ui.selected.id;
                var view = thisView._views[cid];
                if(view) {
                    // I think I only did this stuff to keep the model's Selected 
                    // attribute in sync with the UI. 
                    // this will trigger a redundant call to 'selectedChanged' in the
                    // ItemView, but it has no negative effect.
                    view.model.set({
                        Selected: true
                    });
                }
            },
            unselected: function(event, ui) {
                var cid = ui.unselected.id;
                var view = thisView._views[cid];
                if(view) {
                    view.model.set({
                        Selected: false
                    });
                }
            }
        });
    }
});
于 2013-03-06T06:10:30.803 に答える