0

I am trying to append a view to an item in Backbone with a following code:

var viewContainer = this.$el.find('.view-container'),
  pageWrap = this.$el.nextAll();

FIX if (viewContainer.empty()) {

  this.myView= new ProductsView();
    viewContainer.append(application.myView.render().$el),
    console.log(myView);
}

I am appending this view to the viewContainer with a toggle function, however, every time I click on the button, myView is appended again and again to the viewContainer instead of of only once. How do I check if the view is already rendered inside it before appending it? Is there a !this.rendered() equivalent I can use?

I found this thread but it is not helping me in this instance.

UPDATE - FROM console.log(viewContainer)

[div.view-container.product-container.active, div#subjects_menu.view-container.product-container.hidden.active, prevObject: p.fn.p.init[1], context: undefined, selector: ".view-container"]

Community
  • 1
  • 1
HGB
  • 2,157
  • 8
  • 43
  • 74
  • Possible duplicate of [How can I check if a Backbone.View is currently rendered in DOM?](http://stackoverflow.com/questions/12332373/how-can-i-check-if-a-backbone-view-is-currently-rendered-in-dom) – AKS Mar 30 '16 at 13:02
  • Possibly but it still does not tell me how to access `this.rendered = true;` prior to appending the view. – HGB Mar 30 '16 at 13:39
  • I think you want to check if `viewContainer` has any childrens rather than `viewContainer.length`. You can do so by using `viewContainer.is(:empty)` inside the if condition. – AKS Mar 30 '16 at 13:43
  • `viewContainer.is(:empty)` does not work as it is a div. I tried using `if (viewContainer.length == 0)` but now it stays empty without errors. – HGB Mar 30 '16 at 13:48
  • You need to append the products view inside `viewContainer` so you need to check if it is empty or not before appending. Using `viewContainer.length` will tell you if you have an element `.view-container` in the UI and it seems you already have that. Can you show the value of `console.log(viewContainer)` before and after appending.? – AKS Mar 30 '16 at 13:50
  • Interesting... it is giving me undefined in spite of having `var viewContainer = this.$el.find('.view-container'),` outside of the scope – HGB Mar 30 '16 at 14:13
  • Please see if you can fix that and then try using `viewContainer.is(:empty)` in if condition. If you can post more code as in where is this code being called etc. it would be helpful. – AKS Mar 30 '16 at 14:15
  • Thanks for your quick response @AKS I have pasted the contents of the console.log above. However if if I use the `if (viewContainer.is(:empty)){` above throws an unexpected token error. – HGB Mar 30 '16 at 15:05
  • `:empty` should be in quotes, such as `viewContainer.is(':empty')`. – fbynite Mar 30 '16 at 15:13
  • Fixed. The syntax is actually `if (viewContainer.empty()){ ` so no colons. – HGB Mar 30 '16 at 15:19
  • [or with colons](https://api.jquery.com/empty-selector/) and quotes. – fbynite Mar 30 '16 at 15:35
  • @fbynite is correct. The syntax is `viewContainer.is(':empty')`.However, `viewContainer.empty()` is used for removing all the child nodes of a selected node. [More Here](https://api.jquery.com/empty/). And it seems to work to you because as soon as you call `empty()` the view container child nodes are removed and then you don't seen duplicate elements being added. You still haven't added any more details as in where this code is wrapped in and when is that being called etc. and that's why none of us here are able to help you. – AKS Mar 31 '16 at 04:23

1 Answers1

0

From the looks of it, you want to make sure ProductsView is not created if it already exists.

Simplest way to do this would be:

if(!this.myView) {
  this.myView= new ProductsView();
  viewContainer.append(application.myView.render().$el),
}

It is better to work with application state than querying DOM. When you remove product view, simply do this.myView = null afterwards.


The only time you'd want to query DOM to know if a view is rendered is probably when you have to integrate an isolated external application over which you have no control that doesn't trigger any event/provide callbacks etc while rendering.

T J
  • 42,762
  • 13
  • 83
  • 138