Re-Rendering Handlebars partial from backbone view

前端 未结 1 664
Happy的楠姐
Happy的楠姐 2021-02-15 01:53

I have a view, which holds handlebars template. that template consist of another partial template. that partial template holds a list of results, which i am using in different p

1条回答
  •  野趣味
    野趣味 (楼主)
    2021-02-15 02:24

    Yes, it's possible. The easiest way is to execute the whole template as you do when rendering the complete view, but only replace the the part you need in the view's el.

    Something like:

    template: Handlebars.compile(templateHtml),
    
    render: function() {
      //let's say your render looks something like this
      this.$el.html(this.template(this.model.toJSON());
    },
    
    renderList: function() {
      var html = this.template(this.model.toJSON());
      var selector = "#list";
    
      //replace only the contents of the #list element
      this.$el.find(selector).replaceWith($(selector, html));
    }
    

    Depending on how dynamic your template is, you may have to call this.delegateEvents() after replacing the list for the view's events to work correctly.

    Edit based on comments:

    To clarify, the method I propose here does execute the view's main handlebars template again, but it doesn't render the whole view again.

    Step by step:

    1. Execute the Handlebars template function as you do in normal render.

      var html = this.template(this.model.toJSON());
      

      The variable html now contains a string of HTML markup. Nothing has yet been rendered.

    2. Define a selector for the element, which you would like to re-render.

      var selector = "#list";
      
    3. Find the DOM element to replace. This presumes that you have already rendered the view once. Otherwise there will be no #list element within this.$el.

      this.$el.find(selector)
      
    4. Find the corresponding element in the templated html string, and replace the existing element with the new one:

      .replaceWith($(selector, html));
      

    This will only replace the #list element that's currently on the page. Anything outside #list will not be re-rendered or touched in any way.

    The main reason I propose you do it this way instead of executing and rendering the partial template separately is that your view doesn't need to know anything about the implementation details of the template and the templating engine. All it needs to know that there is an element #list. I believe this is a cleaner solution, and keeps your template details separate from your view logic.

    0 讨论(0)
提交回复
热议问题