最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to correctly add a jQuery UI autocomplete widget using Backbone.js - Stack Overflow

programmeradmin2浏览0评论

I am in the process of learning Backbone.js. I currently assume that if one is using Backbone.js then all client-side javascript/jQuery should be integrated with Backbone. From the various online tutorials I can see how Backbone works and understand its underlying principles.

But what about things like jQuery UI widgets? Should these also be integrated with Backbone.js? For example, I want to use the jQuery UI Autocomplete widget on a form field (See code below). How would I go about doing this with Backbone.js (or would one not bother using Backbone for such things)? It seems like Backbone 'Model' and 'Collection' wouldn't work with the jQuery Autocomplete Widget, since that kind of stuff is tied up within the jQuery UI Widget itself.

(function($){

  $(document).ready(function() {
    $(this.el).autocomplete({
      source: function(req, res) {
        $.ajax({
          url: '/orgs.json?terms=' + encodeURIComponent(req.term),
          type: 'GET',
          success: function(data) { 
            res(data); 
          },
          error: function(jqXHR, textStatus, errorThrown) {
            alert('Something went wrong in the client side javascript.');
          },
          dataType: 'json',
          cache: false
        });
      }
    });
  });

})(jQuery);

What is the standard practice for such things? The only thing I could think of was to create a view and then add the widget in the render function. But this doesn't really seem very Backbone-ish to me.

I am in the process of learning Backbone.js. I currently assume that if one is using Backbone.js then all client-side javascript/jQuery should be integrated with Backbone. From the various online tutorials I can see how Backbone works and understand its underlying principles.

But what about things like jQuery UI widgets? Should these also be integrated with Backbone.js? For example, I want to use the jQuery UI Autocomplete widget on a form field (See code below). How would I go about doing this with Backbone.js (or would one not bother using Backbone for such things)? It seems like Backbone 'Model' and 'Collection' wouldn't work with the jQuery Autocomplete Widget, since that kind of stuff is tied up within the jQuery UI Widget itself.

(function($){

  $(document).ready(function() {
    $(this.el).autocomplete({
      source: function(req, res) {
        $.ajax({
          url: '/orgs.json?terms=' + encodeURIComponent(req.term),
          type: 'GET',
          success: function(data) { 
            res(data); 
          },
          error: function(jqXHR, textStatus, errorThrown) {
            alert('Something went wrong in the client side javascript.');
          },
          dataType: 'json',
          cache: false
        });
      }
    });
  });

})(jQuery);

What is the standard practice for such things? The only thing I could think of was to create a view and then add the widget in the render function. But this doesn't really seem very Backbone-ish to me.

Share Improve this question edited Mar 25, 2012 at 17:42 Benjen asked Mar 12, 2012 at 7:56 BenjenBenjen 2,9255 gold badges30 silver badges43 bronze badges
Add a comment  | 

4 Answers 4

Reset to default 7

In my view, the collection with the data is accessed using this.collection, like @saniko i set up the autocomplete in the view's render function:

render : function() {
    ...

    var me = this; //Small context issues

    this.$el.find('input.autocompleteSearch').autocomplete({
        source : function(request, response){
            me.collection.on('reset', function(eventname){
                var data = me.collection.pluck('name');
                response(data); //Please do something more interesting here!
            });

            me.collection.url = '/myresource/search/' + request.term;
            me.collection.fetch();
        }
    });

    ...
},  
...

Attache all your plugins when you render the view:

you can do something like this:

render: function () {

  var view = this;
  // Fetch the template, render it to the View element and call done.

  application_namespace.fetchTemplate(this.template, function (tmpl) {
    var viewModel = view.model.toJSON();
    view.$el.html(tmpl(viewModel));

    view.$("#categories").autocomplete({
      minLength: 1,
      source: function (request, response) {
        $.getJSON("url" + view.storeId, {
            term: request.term,
          }, function (data) {
            response($.map(data, function (item) {
              return {
                value: item.title,
                obj: item
              };
          }));
        });
      },

      select: function (event, ui) {
        //your select code here
        var x = ui.item.obj;
        var categories = view.model.get("x");

        // bla bla
      }
      error: function (event, ui) {
        //your error code here
      }
    }
  });
}

Hope that helps

I'm using autocomplete to enhance "locality" fields in many form views which interact with different models and different search apis.

In this case I feel that "autocomplete locality" is a "behavior" of the field, rather than a view itself and to keep it DRY I implement it this way:

  • I have a LocalityAutocompleteBehavior instance
  • I have views using this instance by applying the behavior to the form field they want
  • the behavior binds "jquery-ui autocomplete" to the form field, and then creates attributes in the view's model when autocomplete happened, the view can then do whatever it wants with these fields.

Here is some coffeescript extracts (I'm also using requirejs and the awesome jquery-ui amd wrapper at https://github.com/jrburke/jqueryui-amd)

The LocalityAutocompleteBehavior :

define [
  'jquery'
  #indirect ref via $, wrapped by jqueryui-amd
  'jqueryui/autocomplete'
], ($) ->
  class LocalityAutocompleteBehavior

    #this applies the behavior to the jQueryObj and uses the model for 
    #communication by means of events and attributes for the data
    apply: (model, jQueryObj) ->
      jQueryObj.autocomplete
        select: (event, ui) ->
          #populate the model with namespaced autocomplete data 
          #(my models extend Backbone.NestedModel at 
          # https://github.com/afeld/backbone-nested)
          model.set 'autocompleteLocality',
            geonameId: ui.item.id
            name: ui.item.value
            latitude: ui.item.latitude
            longitude: ui.item.longitude
          #trigger a custom event if you want other artifacts to react 
          #upon autocompletion
          model.trigger('behavior:autocomplete.locality.done')

        source: (request, response) ->
          #straightforward implementation (mine actually uses a local cache 
          #that I stripped off)
          $.ajax
            url: 'http://api.whatever.com/search/destination'
            dataType:"json"
            data:request
            success: (data) ->
              response(data)

  #return an instanciated autocomplete to keep the cache alive
  return new LocalityAutocompleteBehavior()

And an extract of a view using this behavior :

define [
  'jquery'

  #if you're using requirejs and handlebars you should check out
  #https://github.com/SlexAxton/require-handlebars-plugin
  'hbs!modules/search/templates/SearchActivityFormTemplate'

  #model dependencies
  'modules/search/models/SearchRequest'

  #autocomplete behavior for the locality field
  'modules/core/behaviors/LocalityAutocompleteBehavior'


  ], ($, FormTemplate, SearchRequest, LocalityAutocompleteBehavior ) ->
    #SearchFormView handles common stuff like searching upon 'enter' keyup, 
    #click on '.search', etc...
    class SearchActivityFormView extends SearchFormView

    template: FormTemplate

    #I like to keep refs to the jQuery object my views use often
    $term: undefined
    $locality: undefined

    initialize: ->
      @render()

    render: =>
      #render the search form
      @$el.html(@template())
      #initialize the refs to the inputs we'll use later on
      @$term = @$('input.term')
      @$locality = @$('input.locality')

      #Apply the locality autocomplete behavior to the form field 'locality'
      LocalityAutocompleteBehavior.apply(@model, @$locality)

      #return this view as a common practice to allow for chaining
      @

    search: =>
      #A search is just an update to the 'query' attribute of the SearchRequest 
      #model which will perform a 'fetch' on 'change:query', and I have a result 
      #view using using the same model that will render on 'change:results'... 
      #I love Backbone :-D
      @model.setQuery {term:  @$term.val(), locality: @$locality.val()}

Here's a useful article giving an example of autocomplete in Backbone.js+jQuery and comparing it to the pure jQuery http://rockyj.in/2012/05/25/intro_to_backbone_jQuery.html

发布评论

评论列表(0)

  1. 暂无评论