【问题标题】:Integrate Backbone.js with jQuery UI Selectable将 Backbone.js 与 jQuery UI Selectable 集成
【发布时间】:2013-03-05 21:36:01
【问题描述】:

我正在尝试使用li 元素作为可选视图创建应用程序。该应用程序要求使用单击和拖动界面选择多个元素。因此,我使用 Backbone.js 来跟踪元素状态和视图,以及用于选择 UI 的 jQuery UI Selectable。

目前,我拥有的唯一结构是主 App 视图、li 元素的模型和视图以及模型的集合。

最好的结构方式是什么,以便我的主 App 视图可以跟踪所选元素并与之交互?

【问题讨论】:

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


    【解决方案1】:

    这是我很久以前做过的事情的精简版。对于您的需要,它可能过于复杂,但它确实有效。我需要能够以编程方式选择/取消选择项目以及让 jQuery-selectable 处理它,这就是模型具有Selected 属性的原因。使用这种方法,您可以执行model.set({Selected:true}),并且所有内容都在 UI 中保持同步。

    添加了jsFiddle来演示:http://jsfiddle.net/phoenecke/VKRyS/5/

    然后在您的 App 视图中,您可以执行以下操作:

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

    希望对你有帮助。

    项目视图:

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

    【讨论】:

    • 看起来这样就可以了。骨干新手,所以像这样的例子总是有帮助的,谢谢。
    • ItemViews 本身不监听选择的变化,但它必须在父视图中监听,这不是很奇怪吗?
    猜你喜欢
    • 2011-07-22
    • 1970-01-01
    • 1970-01-01
    • 2012-01-26
    • 1970-01-01
    • 1970-01-01
    • 2010-10-19
    • 2013-12-14
    相关资源
    最近更新 更多