Jason Biondo
Jason Biondo

Reputation: 834

Append backbone EL twice in Ajax Success Not Working

When I try to append my backbone view to two different places at the same time in my success method only the second appending works. Do you know why?

$(content).prepend(this.$el.append(this.template({ data: data })));

$(chat_window).prepend(this.$el.append(this.template({ data: data })));

Upvotes: 1

Views: 270

Answers (4)

Sachin Jain
Sachin Jain

Reputation: 21842

I agree with @Peter Lyons, You can not inject the same node into two elements. Ultimately, the node will move to new element. One of the ways is to get HTML from the element you want to inject and inject the same HTML twice. Since html is a string and not a dom element. You can add it as many times and inside as many elements.

Try this one:

var html = this.$el.append(this.template({ data: data })).html();
$(content).prepend(html);
$(chat_window).prepend(html);

I hope you are not using id's on elements inside your template.

PS: I don't know your use case exactly.

Upvotes: 0

David Palita
David Palita

Reputation: 1293

In my opinion, the view you're talking about should not know about its distant parents or cousins but rather should trigger an event "I have new content" and then the interested views can act upon this the way they want.

That being said there is a difference between a view and its html representation(s), you could design your app so that you get 2 places in the html where you put ".new-content-holder" and pass this selector as the el of your view upon creation. Then the 2 places will be updated at the same time without you explicitly programming it. I sometimes use this technique for example when I want a paginator for a long list to be displayed over and under the list.

Some html :

<div class="content">
  <p>Recent comments</>
  <ul class="new-content-holder"></ul>
</div>

<div class="chat-room">
  Live feed
  <ul class="new-content-holder">
    <li>a chat message</li>
    <li>another chat message</li>
  </ul>
</div>

And a view

....
var MessageView = Backbone.View.extend({
  template: _.template('<li class="chat-message"><%= message %></li>'),

  prependData: function(data){
    this.$el.prepend(this.template(data))
  },

  onMessage: function(message) {
    this.prependData({message: message.data})
  }

});
....

//And in a super controller of sorts :
var messageView = new MessageView(el: '.new-message-holder')

Again, this is not a very good separation of concerns...but I hope that helps.

Upvotes: 0

Venkat Kotra
Venkat Kotra

Reputation: 10743

el corresponds to one html element that a backbone view generates. Into that html element you can append more html weather it be another backbone view or a rendered template.

Hence in your case if the el is attached twice it finally stays where it was attached last to the dom tree. If you want attach in multiple places then I guess you should instantiate the backboneview twice.

Upvotes: 1

Peter Lyons
Peter Lyons

Reputation: 145994

Each DOM node can have exactly 0 or 1 parent nodes, never more than 1. If you append a node somewhere, it gets removed from it's current parent and then appended to the new parent. What you need here is 2 distinct view instances each with it's own element.

Upvotes: 3

Related Questions