【问题标题】:How to correctly add a jQuery UI autocomplete widget using Backbone.js如何使用 Backbone.js 正确添加 jQuery UI 自动完成小部件
【发布时间】:2012-03-28 15:18:11
【问题描述】:

我正在学习 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);

此类事情的标准做法是什么?我唯一能想到的就是创建一个视图,然后在渲染函数中添加小部件。但这对我来说似乎不是很骨干。

【问题讨论】:

    标签: javascript jquery-ui backbone.js


    【解决方案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();
              }
          });
      
          ...
      },  
      ...
      

      【讨论】:

      • 记得使用'reset'事件!
      • 您介意为此添加其余代码吗?这似乎是最好的解决方案,但我遇到了问题,我不确定您的意思是“使用重置事件”
      【解决方案3】:

      这是一篇有用的文章,给出了 Backbone.js+jQuery 中的自动完成示例并将其与纯 jQuery 进行比较 http://rockyj.in/2012/05/25/intro_to_backbone_jQuery.html

      【讨论】:

        【解决方案4】:

        我正在使用自动完成来增强许多表单视图中的“位置”字段,这些视图与不同的模型和不同的搜索 api 交互。

        在这种情况下,我觉得“自动完成位置”是该领域的“行为”,而不是视图本身,为了保持 DRY,我以这种方式实现它:

        • 我有一个 LocalityAutocompleteBehavior 实例
        • 我通过将行为应用到他们想要的表单字段来使用此实例的视图
        • 该行为将“jquery-ui 自动完成”绑定到表单字段,然后在发生自动完成时在视图的模型中创建属性,然后视图可以对这些字段执行任何操作。

        这里是一些coffeescript 的摘录(我还在https://github.com/jrburke/jqueryui-amd 使用requirejs 和很棒的jquery-ui 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()}
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-05-31
          • 1970-01-01
          • 2011-10-11
          • 1970-01-01
          • 1970-01-01
          • 2013-04-08
          • 2017-07-08
          • 2011-02-15
          相关资源
          最近更新 更多