如何在Backbone.js应用程序中使用jQuery多选插件

How to use jQuery Multiselect plugins in Backbone.js Application?

本文关键字:jQuery 插件 Backbone js 应用程序      更新时间:2023-09-26

让多选jQuery插件在Backbone.js应用程序中工作的诀窍是什么?我试过使用SumoSelect、Bootstrap Multiselect、Chosen和jQuery UI的Multiselect。

我有一个模型,它是集合。我正在View的渲染方法中设置例如SumoSelect插件,代码低于

render : function() {   
....
    // Time for DOM
    setTimeout(function(){
      $(".dropdown-features", this.$el).SumoSelect()
    }, 100);
    return this;                            
},

类下拉特性在模板文件中定义,如

<div class="filter-header">
    <strong>${title}</strong>       
</div>              
        <div>
            <select class="dropdown-features">                   
                <option value="">Choose...</option>
            </select>
        </div>          
</div>

Model和Collection的定义通常类似于Backbone.js应用程序中的定义。

MyApp.Models = MyApp.Models || {};
(function () {
    'use strict';
    MyApp.Models.Facet = Backbone.Model.extend({
        idAttribute: "name"
    });
})();

MyApp.Collections=MyApp.Connections||{};

(function () {
    'use strict';
    MyApp.Collections.Facets = Backbone.Collection.extend({
        model: MyApp.Models.Facet,
        initialize : function(models, options) {
            if (_.isUndefined(options) ||
                _.isUndefined(options.label) ||
                _.isUndefined(options.title)) {
                throw new Error('Label and title must be given Facets collection in initialization.');
            } else {
                this.label = options.label;
                this.title = options.title;
            }
        },
        getName: function() {
            return this.title;
        },
        getLabel: function() {
            return this.label;
        },
        getFirstLabel: function() {
            return this.first().get('name');
        }
    });    
})();

如果我使用纯HTML Select标记,一切都很好,但当我尝试使用上面提到的插件时,我无法将任何数据输入Select Options。选择小部件更改为新样式,但不包含除"选择…"以外的任何内容。

我是Backbone.js的新用户,以前从未在Backbone.jsp应用程序中使用过UI插件。

谢谢,

Mike

我发现了这个问题,花了我一点时间,但我明白了。似乎所有这些框架都在采取简单的方法(我不是责怪他们,我也会做同样的事情),本质上是在做:$(<element you give it>).parent()问题,当你在主干视图中时,在大多数情况下,el还没有连接到DOM。解决方案:

  • 你可以使用setTimeout(不是我喜欢的,它很难看,以后很难调试)
  • 您可以创建一个包装器(只需在<select>周围添加一个<div>
  • 你可以把它连接到它需要去的地方,然后调用SumoSelect()或等效的

示例1:

我不会教你如何做setTimeout,因为我认为你已经掌握了它。

示例2:

var WrapperView = Backbone.View.extend({
  tagName: 'div', // <<< ----------------- look here
  template: _.template('<option value="<%=value%>"><%=name%></option>'),
  initialize: function() {
    this.render();
  },
  render: function() {
    var view = this;
    var select = $('<select>');
    view.$el.append(select);
    myCollection.each(function(model){
      select.append(view.template(model.toJSON()));
    });
    select.SumoSelect(); // <<< ----------------- look here
    return this.el;
  }
});
$('body').append((new WrapperView()).el);

示例3:

var WaitView = Backbone.View.extend({
  tagName: 'select', // <<< ----------------- look here
  template: _.template('<option value="<%=value%>"><%=name%></option>'),
  initialize: function() {
    this.render();
  },
  render: function() {
    var view = this;
    myCollection.each(function(model){
      view.$el.append(view.template(model.toJSON()));
    });
    return this.el;
  }
});
var waitview = new WaitView();
$('body').append(waitview.el);
waitview.$el.SumoSelect(); // <<< ----------------- look here

就我个人而言,我最喜欢选项2,它是最紧凑的选项,选项1我满怀激情地讨厌它,选项3我可以保证你会忘记它,3个月后回来,然后困惑不已;但最终,这是你的决定。以下是实施例2和3:http://jsfiddle.net/ghcp2g2t/4/


PS。下次你问JS问题时,请,非常漂亮的请,添加一个jsfiddle或任何类型的现成的问题测试环境,这需要大量时间来追踪CDN URL并设置测试。

这可能是范围问题。。。

// Time for DOM
setTimeout(function(){
  $(".dropdown-features", this.$el).SumoSelect()
}, 100);

这个$el可能未定义。这行得通吗?

var _this = this;
// Time for DOM
setTimeout(function(){
  $(".dropdown-features", _this.$el).SumoSelect()
}, 100);

或者我个人偏好:

var _this = this;
// Time for DOM
setTimeout(function(){
  _this.$el.find('.dropdown-features').SumoSelect()
}, 100);