2016-10-27 52 views
2

我正在尝试更新集合更新时仅由骨干视图使用的模板的一部分。以下代码成功执行search()render_list()方法。此外,console.log(html)显示完整模板的html。但是当我执行replaceWith时,它将空选择替换为选择器。如果我用一个字符串替换$(selector,html)(即:'test'),它会成功替换'test'。如何更新集合时更新模板的一部分?

因此,出于某种原因,$(selector, html)选择器没有按照它的意思去做。更奇怪的是,更新的html选择器中的图像被浏览器请求,即使没有更新的html被插入到文档中。

define([ 
    'jquery', 
    'underscore', 
    'backbone', 
    'collections/tracks', 
    'collections/genres', 
    'text!templates/search_view_title.html', 
    'text!templates/search_view.html' 
],function($,_,Backbone,Tracks_collection,Genres_collection,Search_view_title_template,Search_view_template){ 
    var Search_view = Backbone.View.extend({ 
     el: $('#app'), 
     events: { 
      'change #genre_select': function(){this.search('genre')}, 
      'click #search_btn': function(){this.search('search')} 
     }, 
     template: _.template(Search_view_template), 
     initialize: function(){ 
      // SET SOME IMPORTANT LAYOUT SETTINGS 
      $('#pagetitle').html(_.template(Search_view_title_template)); 
      $('body').css('padding-top','124px'); 

      this.genre_collection = new Genres_collection(); 
      this.listenTo(this.genre_collection,'update',this.render); 
      this.genre_collection.fetch(); 

      this.collection = new Tracks_collection(); 
      this.listenTo(this.collection,'update',this.render_list); 

     }, 
     search: function(searchtype){ 
      switch(searchtype){ 
       case 'genre': 
        console.log('genre changed'); 
        this.collection.fetch({ 
         data: {limit: 30, type:'genre',genre_id:$('#genre_select').val()} 
        }); 
       break; 
       case 'search': 
        console.log('search changed'); 
        this.collection.fetch({ 
         data: {limit: 30, type:'search',keyword:$('#keyword').val()} 
        }); 
       break; 
      } 
      console.log(this.collection); 

     }, 
     render_list: function(){ 
      var that = this; 
      console.log('render list'); 
      var html = that.template({genres: this.genre_collection.models,tracks: this.collection.models}); 
      console.log(html); 
      var selector = '#tracklist'; 
      console.log($(selector,html)); 
      that.$el.find(selector).replaceWith($(selector,html)); 
      return this; 
     }, 
     render: function(){ 
      // MAKE 'THIS' ACCESSIBLE 
      var that = this; 
      console.log('render'); 

      that.$el.find('#container').html(that.template({genres: this.genre_collection.models})); 

      return this; 
     } 
    }); 

    return Search_view; 

}); 

回答

1

如果没有HTML模板,我可以假设。

这是接近到我会怎么做:

var Search_view = Backbone.View.extend({ 
    el: $('#app'), 
    events: { 
     'change #genre_select': 'onGenreChange', 
     'click #search_btn': 'onSearchClick' 
    }, 
    template: _.template(Search_view_template), 
    initialize: function() { 
     // SET SOME IMPORTANT LAYOUT SETTINGS 
     $('#pagetitle').html(Search_view_title_template); 

     // Do this in css 
     $('body').css('padding-top', '124px'); 

     this.genre_collection = new Genres_collection(); 
     this.genre_collection.fetch(); 

     this.collection = new Tracks_collection(); 

     this.listenTo(this.genre_collection, 'update', this.render); 
     this.listenTo(this.collection, 'update', this.render_list); 

    }, 

    render: function() { 
     console.log('render'); 

     this.$('#container').html(this.template({ 
      genres: this.genre_collection.models 
     })); 

     return this; 
    }, 

    render_list: function() { 
     console.log('render list'); 
     var html = this.template({ 
      genres: this.genre_collection.models, 
      tracks: this.collection.models 
     }); 
     console.log(html); 
     var $selector = this.$('#tracklist'); 
     console.log($selector); 
     $selector.replaceWith($(html)); 
     return this; 
    }, 

    //////////// 
    // events // 
    //////////// 
    onSearchClick: function() { 
     console.log('search changed'); 
     this.collection.fetch({ 
      data: { limit: 30, type: 'search', keyword: $('#keyword').val() } 
     }); 
    }, 

    onGenreChange: function() { 
     console.log('genre changed'); 
     this.collection.fetch({ 
      data: { limit: 30, type: 'genre', genre_id: $('#genre_select').val() } 
     }); 
    }, 
}); 

$('#pagetitle').html(_.template(Search_view_title_template)); 

_.template函数返回一个函数,它本身调用时返回呈现模板。

它可能与this.template混淆,其中经常包含_.template的结果,并且可以调用(this.template(data))。


拆分你的回调,功能很便宜,不必要的switch是丑陋的。我的searchonGenreChangeonSearchClick


$('body').css('padding-top','124px'); 

尽量避免,就可以很容易地用CSS实现,甚至在线<style>标签或内嵌style=""属性。如果因为它涉及到一个动态的行为,有必要对你来说,在一个CSS文件中创建一个类(如search-class),然后切换使用jQuery类,动“设计”责任了JS的:

$('body').toggleClass('search-class'); 

var that = this; 

这是与回调其中上下文(this)是在回调不同处理时必要的。在Backbone中,大部分时间,这是可以避免的,因为context选项通常可用并且在大多数情况下自动设置(例如events回调)。


this.$el.find(selector) 

这相当于this.$(selector)。只是一个小捷径。


.replaceWith($(selector,html)); 

replaceWith期望一个htmlString或元或阵列或jQuery的

$(selector, html)预计选择器和上下文。你想$(html)将你的html字符串转换成jQuery元素。