How do I access the parent element within a Backbone view? - backbone.js

In Backbone model views, it seems $(this.el).parent() doesn't work. What is the best way to select the parent element from within a view?
I am setting el by using tagName: "li" for the view.

By default, Backbone assigns an empty div to your view and you can't access its parent, until it's been placed in the DOM through your render function.
You can use your approach of $(this.el).parent() if you are allowing Backbone to assign the default empty div. You can use the this.el.parent() if you are assigning el yourself in the constructor to a jQuery object.

What are you setting this.el to? If you're already setting it to a jquery element, for example:
this.el = $('#content');
then you don't need to wrap it again. Try changing what you have to:
this.el.parent()

Related

When should I not use a self-rendering view?

I've been studying this Backbone tutorial and came across this bit of code:
var LibraryView = Backbone.View.extend({
el:$("#books"),
initialize:function(){
this.collection = new Library(books);
this.render();
},
...
});
The author explains that this.render() makes the view render when its constructor is called.
When would you not want the view to self-render?
The render method does nothing more than adding HTML to the DOM by using jquery's html or append methods. Where you choose to call the render method on the view is an architectural choice.
Backbone is said to apply the MV* pattern where models are bound directly to the view.
As such, the view would render itself upon instantiation, and have the ability to render itself when the model changes.
However, Backbone leave a lot of decisions to the developer and is a flexible library. There is nothing that technically prevents you to use control objects that manage the flow of the views; as such, another object can instantiate and re-render the view as well.
var view = new Bb_View();
view.render();
In the end, render is just a method on the view, and you can define your own methods as well. An example reason why I would call custom methods on the view from outside the view, is when I keep reference to an array of views.
As an event occurs, I loop through the views, I might add some conditions, and then call the custom method on particular views based on the condition.

Backbone render the view once the dom loaded to avoid div jumping

Adding the view to dom id main-wrapper one router calls the view.Page loads one by one because of the sub view added in within main-wrapper. Need to know something similar to smooth loading the dom with fade in effect or shows the page once the dom is loaded.
Another approach you can take is hold off on adding the view to the main-wrapper until all subviews are created. Create a document fragment (default behavior if "el" is not defined). Once your view and its descendent views are all created in document fragment, then add it to the main-wrapper div. This way all of your content are shown at the same time instead of one view at a time.
Either use jQuery's onReady event or the native window.onload event. In both cases you register a callback function that then kicks of the initialization of the respective Backbone views.

Reloading handlebars partial from marionette view loses access to ui object defined for partial template element within parent view

By referring the this link; I am reloading the handlebars partial template from marionette view within my application.
In my marionette view I have defined ui object as below
ui: {
updateCarrierRow: ".hook--edit-carrier-row",
dispatchEquipment: ".hook--dispatch-equipment",
editButton: ".hook--edit-button",
trailerText: "#trailer-text",
tractorText: "#tractor-text"
},
From which trailerText & tractorText variables are referencing the elements from handlebars template loaded within current view's html template using Handlebars expression
{{> dispatchedEquipement}}
application user will be editing some fields from section rendered with this partial template so on changes submitted to server I need to reload this partial template with modified values from parent model.
So by referring link mentioned above I have reloaded partial template on the parent view using following code segment
this.ui.dispatchEquipment.empty().html(Handlebars.compileClean(dispatchEquipmentSectionPartial)({
"dispatchInformation": that.model.get("dispatchInformation"), "displayText": localizedText.displayText
}));
With this code I have successfully reloaded the partial view on my parent view but on subsequent edit operations when I try to access values of input elements within partial template or trying to change / add css classes it wont work with following code statment
this.ui.trailerText.val();
or
this.ui.tractorText.val();
It gives me empty value though text boxes contains proper values. and same happens with adding or removing css class of these elements with the help of this.ui object of parent view for example
this.ui.tractorText.addClass("hidden")
wont add hidden css class to element.
As of now I have managed to get things working with the help of jQuery id selector for those elements. But I would like to know how should I resolve this issue?
Thanks in Advance.
I reckon it is because the ui elements are bound when the view is initialized but during the life cycle of the view you empty and replace the html thereby no longer having your ui elements bound to what is now on screen.
you could try calling this.bindUIElements() afterwards but not fully sure as i've never had to use it like that.

ng-repeat Efficiency and Working

I am using ng-repeat for my Model render in angular ,
if i Push new Element in Model/Collection , Will angular only deal with Update or Loop through the whole model again.??
My experience (using Angular version 1.2.7) is such that whenever something changed in collection, the whole ng-repeat was repainted.
You can easily test it by modifying the generated DOM. For example by adding custom attributes like my-id="1", my-id="2" etc to the DOM elements.
Then change something in your collection, which will trigger new $digest cycle.
Angular will pick up the change and redraw the DOM -> your custom attributes will disappear.
So I would argue that Angular loops through the whole model.
In the documentation it is clearly mentioned:
ngRepeat
ngRepeat directive instantiates a template once per item from a collection. Each template instance gets its own scope
Angular associates an identity to every item, the elements already associated to the existing items of the collection won't be recreated.
Hence, only elements that are removed from the collection, are removed from the DOM. Furthermore, if an item moves within the collection it doesn’t need a new scope, but it needs to be moved in the DOM.

Backbone underscore update ui from model changes

I using backbone with underscore. I have a button
<%= model.testButtonText %>
This button is rendered in the render function of my view using template.
I am wondering if there is a way to automatically update the button's text when the model.testButtonText changes?
Or do I have to handle it specifically by binding to the model.testButtonText change and then do some jquery to find the element and update the text that way.
If you don't want to bind every element to model change event you can use this plugin: http://rivetsjs.com
Natively Backbone doesn't support ui-bindings.
Since it's tied to the model itself, you can listen for changes in your view to re-render it.
view.listenTo(this.model, 'change', this.render);
A useful extension for re-creating the view when your model changes -- Backbone.ModelBinder.

Resources