Search code examples
jquerybackbone.jsjscrollpane

backbone.js + jScrollPane: keep scrollpane on re-render?


http://tinkerbin.com/pla4NzJ9

I've created a tiny demo, where a backbone view is instantiated and using this.$el.jScrollPane(), a jScrollPane is attached to it.

When I re-render the view 5 seconds later, the jScrollPane disappears. Anyone know why?

Here I've duplicated the js:

var ScrollableView = Backbone.View.extend({
  initialize: function() {
    this.render();
  },

  render: function () {
    this.$el.html(_.template($('#scrollable_template').html(), {})); 
    this.$el.jScrollPane();
    return this;
  }
});

$(function () {
  var scrollableView = new ScrollableView({ el: $('#scrollable') });
  setTimeout(function() {
    scrollableView.render();
    console.log("re-rendered");
  }, 5000);
});

Solution

  • The plugin does this when you call this.$el.jScrollPane():

    return this.each(
        function()  
        {
            var elem = $(this), jspApi = elem.data('jsp'); 
            if (jspApi) {
                jspApi.reinitialise(settings); 
            } else {
                jspApi = new JScrollPane(elem, settings); 
                elem.data('jsp', jspApi);  
            }
        }   
    );
    

    Take note of the elem.data('jsp') check, that means that .jScrollPane() does something different the second time you call it on an element.

    When you do this:

    this.$el.html(_.template($('#scrollable_template').html(), {})); 
    

    Your killing off all the extra elements and event handlers that the first .jScrollPane() call added. Then you call .jScrollPane() again, it sees that .data('jsp') is there, so it probably assumes that everything is already there and doesn't set things up properly.

    There is a destroy method in the jScrollPane API but I can't get it to work. Manually removing the jsp data does seem to work though:

    render: function () {
      this.$el.removeData('jsp');
      this.$el.html(_.template($('#scrollable_template').html(), {})); 
      this.$el.jScrollPane();
      return this;
    }
    

    but I honestly don't know if that's going to do something nasty; I'd mess around with it more and try to get destroy working before doing removeDate('jsp') out of desperation.