Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

backbone.js structuring nested views and models

Using backbone.js:

I have a top level ModelA that contains 2 attributes and 2 nested models, ModelB and ModelC. ModelB and ModelC each have 2 attributes as follows:

ModelA     attributeA1     attributeA2     ModelB         attributeB1         attributeB2     ModelC         attributeC1         attributeC2 

There is a ViewA for ModelA, and a ViewB for ModelB. ViewA's render function places a new div onto the body, whereas ViewB's render creates an h1. ViewA's initialization calls ViewB's render to insert that h1 into the new div. The rationale behind this separation is that the h1 may change and require re-rendering independent from ViewA.

ViewA     initialise:          //call ViewA's own render function         this.render()           //call ViewB's render function that further modifies the $("#new") div created earlier.         $("#new").append(ViewB.render().el)      //ViewA's own render function     render: //place <div id="new"></div> onto 'body'  ViewB     render: //create a <h1></h1>     funcB1: //can this access it's parent ModelA's attributes and other objects? 

Q1: ViewB has a function funcB1. Can this function access it's parent model's attributes? Attributes such as attributeA1, or even attributeC1 (which would be a sibling/cousin)?

Q2: As a further expansion to Q1, can funcB1 access the DOM elements associated with ViewA? (in this example, the #new div?)

Q3: In general, how do I define the associations between the Views and Models as described above so that everything ties together properly?

I realize this question is somewhat abstract but any appreciate any help or guidelines appreciated.

like image 726
fortuneRice Avatar asked Jun 15 '11 05:06

fortuneRice


People also ask

What is the architecture of backbone JS?

It is based on the Model-View Controller framework that binds data, which is abstracted into models, and DOM which is abstracted into views, using events. It is a JavaScript library. Applications of Backbone. js: Following are the applications of Backbone.

What are the main components of backbone JS?

Unlike most of the MVC frameworks, Backbone. js consists of six main components: Models, Views, Collections, Events, Routers and Sync.

What are views in Backbone JS?

In backbone. js, there are 7 modules HTTP request, Router, View, Events, Model, and Collection. Whenever a user makes a request it is directed to the router and in response to these requests, a user interface is displayed at the user end which is known as Views.

What is backbone JS used for?

BackboneJS allows developing of applications and the frontend in a much easier way by using JavaScript functions. BackboneJS provides various building blocks such as models, views, events, routers and collections for assembling the client side web applications.


2 Answers

To be able to reach attributes on related models, the model must have some kind of knowledge about what models it is related to. Backbone.js does not implicitly deal with relations or nesting, which means you must yourself make sure that the models have knowledge of each other. To answer your questions, one way to go about it is to make sure each child model has a 'parent' attribute. This way you can traverse the nesting first up to the parent and then down to any siblings that you know of.

To be more specific with your questions. When initializing modelA, you are probably creating modelB and modelC, I would suggest setting a link to the parent model when doing this, like this:

ModelA = Backbone.Model.extend({      initialize: function(){         this.modelB = new modelB();         this.modelB.parent = this;         this.modelC = new modelC();         this.modelC.parent = this;     } } 

This way you can reach the parent model in any child model function by calling this.parent.

Regarding your views, when doing nested backbone views, I find it easier to let each view represent one HTML tag by using the tagName option of the view. I would write your views as this:

ViewA = Backbone.View.extend({      tagName: "div",     id: "new",      initialize: function(){        this.viewB = new ViewB();        this.viewB.parentView = this;        $(this.el).append(this.viewB.el);     } });  ViewB = Backbone.View.extend({      tagName: "h1",      render: function(){         $(this.el).html("Header text"); // or use this.options.headerText or equivalent     },      funcB1: function(){         this.model.parent.doSomethingOnParent();         this.model.parent.modelC.doSomethingOnSibling();         $(this.parentView.el).shakeViolently();     }  }); 

Then in your application initialization code (eg in your controller), I would initiate ViewA and place its element inside the body element.

like image 79
Jens Alm Avatar answered Oct 12 '22 14:10

Jens Alm


The general answer to the question "Can I" is always "yes, as long as you're willing to write the code." The point behind Backbone is to provide a strong separation of model and view. If B1 has a reference to A1, and A1 has a reference to C1, then you're fully capable of creating methods and setting the rules by which B1 can modify A1 and C1 and so forth.

The views should be set up to receive CRUD events from their respective models. If the user does something with B1view that modifies B1model, and B1model in turn modifies A1model, then A1model should generate an event that A1view receives and causes a re-render of A1view, and so forth. It should happen like magic. (In practice, it takes some time to get the magic right, but I've found Backbone to be really powerful. And BackboneRelational helps with things like what you're describing here.)

like image 32
Elf Sternberg Avatar answered Oct 12 '22 15:10

Elf Sternberg