Подтвердить что ты не робот

Как правильно добавить виджет автозаполнения пользовательского интерфейса jQuery с помощью Backbone.js

Я участвую в процессе обучения Backbone.js. В настоящее время я предполагаю, что если вы используете Backbone.js, тогда все клиентские javascript/jQuery должны быть интегрированы с Backbone. Из различных онлайн-руководств я вижу, как работает Backbone и понимает ее основные принципы.

Но как насчет виджета jQuery UI? Должны ли они также быть интегрированы с Backbone.js? Например, я хочу использовать виджет автозаполнения jQuery UI в поле формы (см. Код ниже). Как я буду делать это с помощью Backbone.js(или не потрудился бы использовать Backbone для таких вещей)? Похоже, что Backbone 'Model' и 'Collection' не будут работать с виджетами jQuery Autocomplete, поскольку такие вещи связаны с самим виджетами 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);

Какова стандартная практика для таких вещей? Единственное, что я мог подумать, это создать представление, а затем добавить виджет в функцию рендеринга. Но на самом деле это не очень похоже на Backbone-ish.

4b9b3361

Ответ 1

Подключить все ваши плагины при визуализации представления:

вы можете сделать что-то вроде этого:

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

Надеюсь, что поможет

Ответ 2

С моей точки зрения, доступ к коллекции с данными осуществляется с помощью this.collection, например, @saniko. Я устанавливаю автозаполнение в функции вида render:

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

    ...
},  
...

Ответ 3

Я использую автозаполнение для улучшения полей "локальности" во многих представлениях форм, которые взаимодействуют с разными моделями и различными поисковыми apis.

В этом случае я чувствую, что "автозаполнение локали" является "поведением" поля, а не самим представлением и для его сужения. Я реализую его следующим образом:

  • У меня есть экземпляр LocalityAutocompleteBehavior
  • У меня есть представления, используя этот экземпляр, применяя поведение к полю формы, которое они хотят
  • поведение связывает "jquery-ui autocomplete" с полем формы, а затем создает атрибуты в модели представления при автозаполнении, представление может затем делать все, что захочет, с этими полями.

Вот несколько извлечений coffeescript (я также использую requirejs и потрясающую оболочку jquery-ui amd в https://github.com/jrburke/jqueryui-amd)

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

И выдержка из представления с использованием этого поведения:

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