Backbone.js - nested models & more then one model in collection? - backbone.js

Can one have nested models in backbone.js?
Example: Model A has one of its attributes as Model B
Can one store more then one model type in collection?

Yes you can store models in attributes (nesting models). The main thing to watch out for is that change events to the nested model or collection will not propagate to the outside model.
You could use different models in a collection, but the default create and add methods will only create one type of model if they are passed attributes rather than an explicit model. Also, saving and fetching will require you to specify the URL on each model you pass in for that to work. In general, I wouldn't recommend it.

Related

Sencha ExtJs5 Multiple models in one model and and one View

I'm new to ExtJs , so not sure how to implement the below scenario.
I do have one form which have multiple sections and table. Each section fields are binding with one model variables.
Now i need to fetch the data from the java models and assign the data to fields. In Java the model structure is : Model A -> Model B, Model C, Model D.
Here, Model A is the main Model and Model B, Model C, Model D are the sub models to the main model.
The same structure need to apply in ExtJs View/Controller. Main form binding with Model A and all form sections are binding with Model B / C / D .
How can I work on this scenario?
Best practice is to have models via the Ext.data.model which then are hosted by the Ext.data.store. You can setup the hierarchy as you need and then you just need to populate the store with the data.
Stores have various proxies to get populated from different sources.
After that you provide stores to different components as data which bind to them and provide the UI.
one cannot "fetch data from the Java models" ...use an ExtJS Store instead.

Two views, same model, different collection, how to use change event on model?

For my setup I have two sub-views (on the same View) that render the same type of Models, however each view uses a totally different set of Model (one displays the latest ones, the other is split in 4 subviews per category). Using filter() on a Collection doesn't work because I need 4 posts per Category and about 20 new ones.
Since they are both on the same page, when I update the model on one view, I want the same model to be updated on the second view.
I tried a couple of things:
Use one Collection on the mainView, fetch inside the mainView and give this common Collection to the subViews. This is working as long as both subViews are using the same set of Models, which I am not.
Use custom events and a Collection in each subView. When Model is updated, send a global Backbone.trigger with the modified Model, catch it on the other side and do stuff as needed. This is also working but the implementation is really not pretty or efficient. Having all the Models listen for change and only act if their id is the correct one seems counter productive.
Use one Collection on the mainView and one per subView, the idea being that the Collection on the mainView holds all the items and distribute them to each subView's Collection as needed. This works but fetching the data, duplicating in the main Collection and the other subView Collection is kind of a pain and requires me to hold an instance on mainView inside each subView, which I don't really want to do because each subView is a "component" and can be use in multiple places.
People online seem to do the Events way most of the time, but I wonder if someone has a better idea.
Thanks a lot.

When using Backbone + Stickit, do the view model objects need to extend Backbone.Model?

Loosely said, the various components in a MVVM pattern are
Model: this represents the data send by the server and sent back to the server. this contains no state related to display of the UI
ViewModel: this is constructed from one or models. this contains state meant for UI manipulation (is the button enabled or disabled). all logic meant for UI manipulation is stored here. this layer has no dependency on any UI framework (no jQuery calls)
View: this has tight coupling with the UI framework/underlying UI controls. One view observes one and only one view model. A view model can be observed by one or more views. The view is responsible for doing two-binding with the view model.
A presenter/coordinator: While not a part of the traditional implementation, in its absence the view model ends up with way too much responsibility. This guy helps coordinate making ajax calls (get/post), listening to events on the global event aggregator etc
Standalone Backbone has no concept of view models and data binding. In that scenario, the data returned by the server can be modelled as Backbone.Model objects. The bindings are done manually and a POJO can be used for view-model syncing.
If I wish to use Stickit for data binding, it appears that the view model needs to be an instance of Backbone.Model. Chiefly because the bindings work within the context of a Backbone.View and a Backbone.View expects a Backbone.Model object to be present as a property of the view. Also, a Backbone.Model raises change events and what not. I assume it will be difficult to observe a POJO. Again, this is my understanding from reading the Stickit docs. Please correct me if I am wrong.
A Backbone.Model has other methods on it that don't make sense from the point of view of a view model, like save, fetch etc. I was reading up on another mvvm library, Knockback. It can transform a Backbone.Model into a Knockout.js view model. Instead of passing in a full fledged Backbone.Model, it can also accept any POJO that has get/set methods and raises change events when the properties have changed.
Does Stickit have a similar contract wherein I can pass in a POJO that has get/set methods and raises change events? What is the recommended usage?
There's nothing in the source of Backbone.Stickit that requires that the model actually be an instance of Backbone.Model. So, it does appear that Stickit just needs some object that supports the contract provided by Backbone.Model--the various applications of set(), get() and on() are all I think you need.
Take a look at Stickit's test suite. If you wrote your own model API that passed that those tests (by replacing Backbone.Model with your own implementation in testScaffolding.js--and presuming the tests are thorough--then you should be able to use that model with Stickit.
EDIT: I may not have directly addressed the question. Stickit only requires that you use it in a Backbone.View, and that that view has either a model, or some other object specified by the optionalModel parameter you can pass to the stickit() function, that meets the contract provided by Backbone.Model.

Should views keep track of their model?

This nice article recommends against keeping track of the views belonging to a model inside the model. What about the opposite? It is recommended for views to keep track of the model(s) they are based on?
It seems difficult to imagine to do without. Maybe the recommended way is to use events, or something?
Views always keep a reference to the model. It is accessible through myView.model or myView.collection.models.
Due to the nature of views, I cannot imagine a case where you would want the view to not know about the model. Event binding happens in the view with a reference to a model. (Think about the collection.add event. Wouldn't be possible if you didn't bind to a reference to the collection)
Most of the time the view should know its model cause he is the visualization of the model. So the model can be there without a view, but a view without a model doesn't make much sense.
But as always there are cases where the view should not know its model directly. Think about a basket where a user can add products and maybe he can configure that products. You have different views that visualize the model, like a table with the products, a basket ico with the count of products and a view to show the total amount. All share the same model. So when ever the user creates a new model cause he delete the old one or order something and there after something new, you have to create a new model and pass it to your views. Sure you can to this by fire an event. But you can also pass a proxy for your model to your views, so the views always comunicate with your proxy and they never know that sometimes a new model was created.

How to make view model and model communicate?

I am using MVVM pattern for my app. The model actually runs a set of test in parallel and keeps tab of the status of the test including its result. I want the status and result to be displayed in the view. I am stuck at desiging the view model.
The problem is that there are lots of classes and sub class hierarchy in the model in which all the required data to be displayed in the view are stored. Those data are dynamic.
I am not sure how to design the view model now.
I was thinking along these lines - Create a new data structure in view model which reflects what is to be shown in the view and get all the view model will dig through the model to get the required data. In this case I am confused how the model will update the view model whenever a data changes. Or how do the model and view model communicate with each other given that the data are stored in different class and sub classes.
Your view model should have references of all models which required to show data on the view. Then view model should handle events from model classes and fire NotifyPropertyChanged event.
If your view is complex and require lots of models, then you can consider to split your view in multiple views and corresponding view model.
You say the user chooses which data to view, so I imagine your VM could hold an array of Models and an index indicating which is the 'active' one, and only communicate with that one.
For that communication, a solution could be to pass to the model an Action to call when new data is available, and that Action would that trigger a NotifyPropertyChanged in the VM. This would work especially well if you make sure only the 'active' model has that Action while in the others it would be null meaning 'don't trigger updates'.

Resources