I just started learning backbone.js. I have a problem understanding how/when use models and collections. I found several tutorial online and each of them use different approach of building the application. There are cases where data is retrieved from REST API in a Collection object, in other examples in a Model object? I also noticed in every example json data was in format like
{'id':1, 'name':'some name'}.
My api returns a bit more complex data structure - something like {'message':'response message', 'error':'', 'data': [{list of data objects to be manipulated},{}]}. Is it possible to use such formatted data in backbone.js.
Well, yes, for both of your questions. Typically here is how the Relational database system relates to backbone.js:
Your model is a record from a table of the database.
Your collections are the table itself. So set of models make up the collection.
Views are used to define how your model should look and what it should do. There are views for your models, collections and intermediate data.
Your response if different; hence, you need to parse the data before it is set to the model, collection. Use the parse method and define the data key.
Related
Referring to this question: https://softwareengineering.stackexchange.com/questions/218391/arrays-vs-objects-in-view-template
I was wondering what are the best practices to pass data from controller to view?
I'm currently working on php/Laravel and using service layer between controller and models. I'm not using repository layer yet, so just getting eloquent object from models and passing them to controller then view. The format is not persistent, at some location the data is being passed as eloquent object/collection and at some points it's being passed in an associative array format.
We know, the best practice is that our view should know least about the backend code/structure. If we pass an eloquent object to the view, then our view even knows the field names in models. This way, changing one model field name will break our code till the view.
If we pass array then we can definitely such kind of information? There is also some concept about DTO (Data transfer object), how it can help in hiding our data from view? I'm looking for a way through which my front-end and back-end least depend on each other.
With Backbone, I do a somewhat expensive calculation for each Model in my Collection and there can be a lot of Models. I'm thinking I'd like to store the result in each Model with set(), but I don't want to save it to the server. Is this generally a bad idea?
If that's not good, is the better practice to keep it in an array variable or a Model (a calculations results model separate from the cached server data model)?
Why do I think this might be a good idea?
I wouldn't ever have to give thought to the array variable's scope/context.
No looking up the array contents once I have the relevant Model.
Data is more encapsulated
Why do I think this might be a bad idea?
Mixes cached server data with calculated local data.
Probably have to write sync code so that save() only saves the attributes the server should get.
Thanks!
EDIT
Found someone exploring a similar issue, with good discussion: Custom Model Property in Template.
This seems to have a pretty thorough answer that I am exploring: Backbone Computed Properties.
One solutions might be to override the toJSON function of your Model.
This function is called by the save function to get the attributes to be send back to the server.
Looking at the docs of the toJSON function is basically is saying you could use it for your specific purpose:
Return a copy of the model's attributes for JSON stringification. This can be used for
persistence, serialization, or for augmentation before being sent to the server.
I would personally not consider it as bad practice but all depends on the amount of and the calculations itself that is needed. So it would depend on your specific use case.
Also you could not store the calculated object in your model.attributes object but somewhere in your model instance. That way it would be hidden from the model attributes you will synchronize back and forth with your server.
I am just beginning to use backbone.js for a new crash project. My app has a dynamic (data-driven) user menu. Each menu option is a set of graphs/small tables, of mixed types. For example, a Sales Overview menu option can have a page with 2 pie chart objects, 2 line charts, a bar chart, and so on. I don't know up front what the menu options are going to be, nor what each menu option will entail.
I am considering defining a bunch of generic model "classes" by extending Backbone.Model - PieModel, BarModel, DispersionModel, etc. And corresponding View classes that can render an object of a type - PieView, LineView, and so on. Then I can assemble a page by putting these together as defined by the dynamic configuration. Each model instance's data url can be easily generated on the fly, via the dynamic configuration..
My first concern was if Backbone supports a Collection of mixed Model types. This is instigated by presence of a "model" property for a Collection - does it assume homogeneity? But it also says a collection can hold an ordered set of models.... model attribute can be polymorphic... a method to get "models" held in the collection. Should I be reading this as "model objects"?
A "page" to me really is a collection of such objects. I would like to create a Collection on the fly and populate it with instances of different model types. And then render this through a View. Or, create a View with an array of various model objects and render the View, bypassing the Collection all together.
I will appreciate your inputs on the design I have outlined, and good reference on backbone, and clarity on how to deploy a Collection in mixed model cases? Perhaps there is a different, smarter way to handle such scenarios...
Thanks.
Collections only really use their model attribute when passing plain objects into its adder functions (e.g. add, push). If you take a look at the source, each adder function passes the input through _prepareModel, which checks if the input is an instance of a Backbone.Model. If it's not, it tries to instantiate a new model using the collection's model, otherwise it just returns the input untouched.
So as long as you're always adding real Model objects to your collections you should be fine using different types.
However, if you're planning to use aggregate functions that act on model attributes (e.g. pluck) you may run into errors when the function tries to get at an attribute that doesn't exist in one type of model (though most of the time I think it would just silently fail, which might be what you want).
I am not sure if I have 100% properly understood your scenario, however, I am not convinced you are thinking about this in the right way...
In my opinion, your models should contain the data, and views should represent them. As such, in a sales context you might have a SalesData model which could be displayed in PieView, BarView or TableView. Try to completely separate display logic from data - the type of chart falls under display logic in my opinion.
With the above approach, each page would then contain a set of different views, which you could potentially contain in a master view if you felt the need. Each view would have its own model (or collection depending on how you structure the data), which you can then update/manipulate using the normal Backbone methods.
As far as I know it is not possible for a collection to have different types of models contained within it, but even if it was, I would probably not recommend it as it would complicate the code a lot.
In terms of learning resources, here are a couple:
Learn Backbone JS compeltely -- javascriptissexy.com - this one is very thorough but will take some time to get through.
Backbone patterns - much quicker to get you in the right frame of mind.
Wijgrid will not work with breeze and angular. To save me repeating myself, please have a look at this post:
http://wijmo.com/topic/wijgrid-will-not-play-with-angular-and-breeze-together/
Your model, like most models, has circular references. We are not wijgrid experts (at all!) but we suspect that the wijgrid component - at least as you have it configured - is unprepared for objects with circular references.
Objects with circular references are not bad. In fact they are normal and expected in entity models. A customer has orders and each order has a property that returns its parent customer. If you don't
We suggest you consult the vendor on this topic.
If you are using the grid read-only, you can write a simple function to copy just the data you want to display from the queried entities into special purpose "ItemViewModel" objects; then load those into the grid. It's even easier to query with a Breeze projection because that returns raw data, not entities; just remember that Breeze isn't caching those non-entity results either.
The situation is more complicated if you want to edit the grid.
I want to reiterate that this is not a Breeze problem. It is a problem with the grid control.
Given that I have an API which describes it's different resources via json-schema like this:
https://github.com/salesking/sk_api_schema/blob/master/json/v1.0/address.json
Is there a frontend javascript framework that can use json-schema as (or translate it to) a model? it should be possible to validate the model against the json schema and it should be able to handle references between different json-schema models.
I have been looking a bit at ember.js but it seems that even if i write some code to translate the json schema to an ember model, it would still be a far cry to get the validation working for ember.js models. Correct?
Without knowing much about JSON Schema, I believe Knockout can support this fairly easily.
Since KO models can be any Javascript object, you would just need read the schema, and generate an object from each of the "properties" property's properties (haha)
You can also add validation dynamically using the Knockout Validation plugin:
https://github.com/ericmbarnard/Knockout-Validation
Combined example:
var schema = // read in json
var model = {}
for (prop in schema.properties) {
model[prop] = ko.observable().extend({
maxLength: /* get your value from schema, etc */,
minLength: /* get your value from schema, etc */
}
}
JXT (http://www.jxtdev.com) models are initialized with JSON, moreover JSON is used to configure JavaScript packages. JXT implements the MVC pattern and when data contained in the model changes, it will notify its controller which will reload the view automatically. This event driven approach is used everywhere in the framework, starting from JXT collections (which are wrappers around native JavaScript collection). I just released the first beta (yes, I'm the developer behind it), so you may find it still immature, but it worth a look imo ;)