I'm trying to learn some Ember.js and while I realize everything is in flux and the moment, it seems that this bit of code from the Sproutcore 2 guides (which are linked to at the Ember.js github readme) doesn't work any longer:
App.userController = SC.ObjectController.create({
content: SC.Object.create({
firstName: "Albert",
lastName: "Hofmann",
posts: 25,
hobbies: "Riding bicycles"
})
});
Looking at the ember.js source, the only type of controller that seems to be supported is an arryay controller. Is there an established best practice for proxying between a single model object that is not part of an array/collection and a view? Or do people forego the proxying and simply set up bindings directly between the model and view objects? Thoughts?
There are plans to bring back ObjectController/ObjectProxy. Peter and I have started working on it here, but we need to add some lower level functionality to Ember before it can be fully supported.
Until then, you can use Ember.Object with a content property. You'll have to explicitly reference the content property in property paths (eg. App.userController.content). When ObjectController is finished you'll be able to switch your controllers to inherit from it instead and you can update your property paths to not explicitly reference content.
UPDATED: Yes, Ember.ObjectController is a first-class part of Ember and is most frequently used to proxy a model's properties for easy rendering by templates. See http://emberjs.com/api/classes/Ember.ObjectController.html for documentation.
It's in master now, see:
https://github.com/emberjs/ember.js/commit/c6954ba40ab9f007dd499634bfccf40fc31a73d7
Related
Learning Ember.js and have a reasonable understanding of getters and setters (accessors) through Ruby and Java.
In Ember/Javascript, I seem to have a very serious lack of understanding. For instance in my controllers/models, I don't have a clue whether to use object.set(property,value) or refer them directly object.property = 'value'
As an example, in my earlier question (How to get Model values in Controller), part of working answer was to use object.name instead of object.get('name'). It worked but I miss the basic understanding.
Would appreciate some clarifications.
The rule is: You should always use .get()/.set() when you are in your .js-files. When you are in your templates (.hbs or other) you should not (you can't do it).
If you access a property via myObj.myProp it will work for regular properties, but computed ones won't. If you set a property via myObj.myProp you can still get the value back, but bindings and observers won't be notified that it has changed and won't updated properly.
This is a design decision by the Ember team which allows for efficient bindings/observers instead of doing dirty-checking of all bound/observed properties (which is what Angular currently does).
I made a small jsbin showing this. Three values are bound initially, the button then changes one and logs it into the console (so make sure to have the console open), the binding isn't updated but the value can be retrieved. It then tries to get a computed property via myObj.myProp which returns undefined and then the regular way.
http://emberjs.jsbin.com/cipapaxevi/2/
Also, as a side note. If you want a property thats on a child object to what you have you can access it via myObj.get('myProp.myOtherProp') instead of doing myObj.get('myProp').get('myOtherProp'). It saves you from the worry that myProp could return null or undefined.
That's the way Javascript works and it's one of its disadvantages. It doesn't have public/private proprieties nor methods. Therefore, we should rely on good comments in the code.
I am not an expert in Ember, but when I face the similar problems in JS I usually look at the source code of the library to see how it's constructed and then make a decision. That's why probably js libraries are usually shipped with both min and dev versions.
However, if the object has special methods to access its properties then they are there for a reason, so use them instead of the direct access to the properties. As I said above, in Js you can't make properties be private or protected.
I have been looking for information about how can we build relationship in Backbone and came across following two nice plugins:
Backbone-relational
Backbone-associations
Both seems to have exist more than two years and seems to be stable. However, Backbone-relational outshines against Backbone-associations in following terms:
Providing almost all relations like one-to-one, one-to-many, many-to-one as we have in Database
Nice documentation (similar to Backbone.js) on first glance
Since, I haven't had time to go through both the plugins extensively, I would like to know from the experienced person following things:
Does both support AMD (like Requirejs)?
How easy to use the plugin with back-end-server like Ruby on Rails?
How easy to implement polymorphic relationship?
Biggest difference is that Backbone-relational fobids creating multiple instances of same model with identical ids. Consider:
let Person = Backbone.RelationalModel.extend({
relations: [
type: Backbone.HasMany,
key: 'likes_movies',
relatedModel: 'Movie'
]
});
let peter = new Person({
likes_movies: [{id: 1, title: 'Fargo'}, {id: 2, title: 'Adams Family'}]
);
let john = new Person({
likes_movies: [{id: 1, title: 'Fargo'}, {id: 2, title: 'Adams Family'}]
);
// Change title of one of Peter's movies
peter.get('likes_movies').get(1).set('title', 'Fargo 2 (Sequel)');
// John's corresponding movie will have changed its name
console.log(john.get('likes_movies').get(1)); // Fargo 2 (Sequel)
If rewritten for Backbone-associations, the movie title for John wouldn't have changed. This can be considered a feature or a disadvantage, depending on how you look at it.
Besides this, both libraries are very similar, except that development of Backbone-associations seems to have stopped almost a year ago.
Actually, based on both GitHub pulse (activity indicator), Backbone-relational community seems much more active.
I've studied both of these libraries when I was looking for something like EmberData or Restangular for Backbone.
Both of these libraries try to make up for the main Backbone weakness: handle properly Rest API Restful Resources.
In fact, Backbone promotes new models creation each time it need to be rendered (instead of reusing the instance used for another rendering somewhere else on the application).
Some inconsistencies then occurs because some model updates are not propagated everywhere on the web-application.
A cache of backbone model instances is then required..
Backbone Relational provides such a cache but Backbone Association doesn't.
Furthermore, both have reimplemented the code methods of Backbone (set, get, reset, trigger) so they are strongly coupled with Backbone.
That could complexify the Backbone library migrations especially if you use another MVC framework on top of Backbone (Marionnette, Thorax, Chaplin,...)
Backbone Association is lighter than Backbone Relational in terms of lines of code (800 vs 2000).
Backbone Association implementation is easier to debug because it directly manages relationships into the overloaded methods (set, get,...)
On the contrary, Backbone Relational relies on queues to synchronize relationship content with its internal store. That makes the debugging tricky...
Another lightweight (but less used) alternative is "Backbone SuperModel": http://pathable.github.io/supermodel/
This library is compound of 800 lines of code easier to understand than Backbone Relational (I was able to fix a little bug on it myself.)
It offers a backbone instance cache based on Backbone Collection
On my side,
I succeed to integrate the last one with RequireJs
I manage some polymorphic associations with it
A protocol between my web-application and my Java backend emerged
I succeed to upgrade Backbone and Marionette every time I need
I am evaluating JS persistence libraries. I'm on an Angular stack so ngResource and Restangular are options, but so are Breeze and Backbone's Models/collections and I'm open to others.
Is there a JS persistence library out there that will monitor changes to the model and do a PATCH of only the changed properties?
Example:
// Get a pretend user with a name, email, and some other stuff.
var currentUser = user.get(42)
// Change only the email address
currentUser.email = 'tractorDaddy#aol.com'
// Save changes
// The model could know that only one property has changed.
// The model could do a PATCH of a partial object, but I don't know a library that does.
currentUser.save()
This seems like it should be the default implementation but none of these libraries do it, that I could see.
Backbone's model decides whether to POST or PUT based on the newness of the model (determined by presence of id, as I recall). I think this is a nice move and could be extended to include PATCH.
I understand that Restangular and others have a .patch() method, but I believe in all cases you have to specify the object partial explicitly.
Is there a library that does this?
I think there is no existing JS model/persistence layer that will track and PATCH only change values.
I have high hopes for AngularJS 2.0's data layer: http://tinyurl.com/pa7rxf8
I am wondering how to structure a KnockoutJS application the right way.
The official documentation almost always uses just one single ViewModel!
After only a few implemented functions my code became very confusing and coming from an object-oriented background I am very allergic to architecture like that. So there must be a better solution.
Being not very experienced with JavaScript I was searching Stackoverflow and found those three options. So I tried the first two options and I am not happy with them:
Having multiple ViewModels like here.
I find it very difficult to decide what DOM-element gets what ViewModel. Also there were several functions called from outside the DOM-element. Maybe I used too little ViewModels with this kind of architecture but communicating between ViewModels seemed to be different and somehow shouldn't be necessary I hope. So how to do that properly?
Having sub views and utilizing the with binding (the second option from those three).
This was my preferred type of architecture because you can have document-wide bindings out of one view model but you can also structure your code into sub-chunks and bind them to wherever you want by using the with binding. This option though requires object literals instead of functions, which are inferior as described in this answer.
I haven't tried method three because it seems a little overkill and also uses object literals.
So is there a method to structure my code and also have full control without using object literals?
I hope this was not too confusing :-P
For any of the options that you mentioned, you do not need to use object literals. The samples just used them to simplify the code. You can choose to create the individual view models in any way that you see fit.
For example in #3, you can use a constructor function like: http://jsfiddle.net/rniemeyer/PctJz/149/. Of course, the actual data would get passed into the function rather than being static. Same with #2, you just would have it wrapped in the "View" object.
From couple of days, I have started working/learning the backbone.js. I have read documentation on their site. I have also read few tutorials available here.
As per my understanding below are few major differences between Views and Models.
Only view has 'el'. Why it is not there in Model ?
Only Models have 'get','set', 'save' methods.
Only Models have functions like fetch, save, destroy, validate
methods,clear,has.
According Hello World examples here, View can also do the things Models can do.
Both have extend, render, initializer, getter setter methods.
Both can be converted into JSON using toJSON.
hence, I am confused between Models and Views. When to use each one ?
my question is.. what is practical difference between Models and Views? What are different situations to use Models/Views ? What should be appropriate to use for displaying(render)?
Can anyone good # Backbone.js explain with practical scenario ?
Your help will make my understanding much clear.
Model and Views are not Backbone terms. You can read about MVC paradigm first.
Model contain data and logic for data manipulations. View describes how this data should be displayed.
Hence only View have 'el' - because this it is used while displaying data.
Getters and setters are in model according to MVC paradigm.