2012-03-12 14 views
12

Estoy en proceso de aprender Backbone.js. Actualmente asumo que si uno está utilizando Backbone.js, entonces todos los javascript/jQuery del lado del cliente deberían estar integrados con Backbone. De los diversos tutoriales en línea, puedo ver cómo funciona Backbone y comprender sus principios subyacentes.Cómo agregar correctamente un widget de autocompletar de jQuery UI con Backbone.js

Pero, ¿qué pasa con cosas como los widgets de jQuery UI? ¿Deberían estos también ser integrados con Backbone.js? Por ejemplo, quiero usar el widget de autocompletar de la interfaz de usuario de jQuery en un campo de formulario (ver código a continuación). ¿Cómo haría esto con Backbone.js (o no me molestaría en usar Backbone para tales cosas)? Parece que Backbone 'Model' y 'Collection' no funcionarían con el widget de autocompletado de jQuery, ya que ese tipo de cosas están vinculadas dentro del widget de jQuery UI.

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

¿Cuál es la práctica estándar para tales cosas? Lo único que se me ocurrió fue crear una vista y luego agregar el widget en la función de renderizado. Pero esto realmente no parece muy difícil para mí.

Respuesta

3

Attache todos sus plugins Al representar la vista:

se puede hacer algo como esto:

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

Espero que ayude

7

En mi opinión, se accede a la colección con los datos de usando this.collection, como @saniko configuré el autocompletar en la función render de la vista:

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

    ... 
}, 
... 
+0

Recuerde utilizar el evento ''store'' – miguelr

+0

¿Te importaría agregar el resto del código para esto?Parece la mejor solución pero estoy teniendo problemas y no estoy seguro de lo que quiere decir "use el evento de reinicio" – reach4thelasers

3

estoy usando autocompletar para mejorar los campos "localidad" en muchos puntos de vista de forma que interactúan con diferentes modelos y diferentes apis de búsqueda.

En este caso siento que "localidad autocompletar" es un "comportamiento" del campo, en lugar de una vista en sí y para mantenerlo seco implemento de esta manera:

  • tengo una instancia LocalityAutocompleteBehavior
  • que tienen puntos de vista que utilizan este ejemplo, aplicando el comportamiento al campo de formulario que quieren
  • el comportamiento une "jquery-ui autocompletar" para el campo de formulario, y luego crea atributos en el modelo de la vista cuando autocompletar sucedió, la vista puede hacer lo que quiera con estos campos.

aquí tienes extractos CoffeeScript (También estoy usando RequireJS y el envoltorio impresionante jquery-ui amd en https://github.com/jrburke/jqueryui-amd)

El 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() 

y un extracto de una vista usando este comportamiento:

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()} 
Cuestiones relacionadas