How to reference a model in Ember.js? - ember.js

I am working through toDoMVC and in the code below, just don't quite understand what this refers in var model = this.get('model');.
Does it refer to Controller or Route. If it is Controller, then where do we declare that Model x works with Controller y?
Todos.TodoController = Ember.ObjectController.extend({
isCompleted: function(key, value){
var model = this.get('model');
...
}.property('model.isCompleted')
});

I. Usually this variable inside Ember.Object functions refers to an instance of that Ember.Object (an instance of Todos.TodoController in your case).
Example:
App.SomeRoute = Em.Route.extend({
activate: function() {
this; // this is App.SomeRoute instance ref.
}
});
App.SomeController = Em.Controller.extend({
someMethod: function() {
this; // this is App.SomeController instance ref.
}
});
App.SomeView = Em.View.extend({
someMethod: function() {
this; // this is App.SomeView instance ref.
}
});
and so on.
II. this.get('model') is just a property of controller (you can set any value to that property if you want). *Before ember v1.7 model was an Ember.computed.alias to controller's property named content, but this behavior was changed in latest ember's versions.
There is another model property, in Em.Route, it differs from Em.ObjectController.model property. Actually, it's a function invoked in routing (transition) sequence, which returns data, which Em.Route uses to set a controller.model property in setupController hook of Em.Route. So, output of this.get('model') inside of Em.Route's methods will be a function.
P.S. I tried not to screw up with tenses, but most likely I didn't succeed.:) I'am sorry.

Related

Ember send action from component to context controller

In the case below videoEnded function is successfully called, however how do I get a reference to the actual Ember component it self?
export default Ember.Component.extend({
videoEnded: function(){
var self = this;
alert('how do i get a reference to the actual ember component object here ?')
}
didInsertElement: function() {
var self = this;
var options = {};
self._soundjs = soundjs('soundOne', options, function(){
});
self._soundjs.on('ended',self.videoEnded);
}
The following solved my issue. videEnded callback was losing the components context. The following code resolved the issue, self passed to video ended refers to the component context which can then be used, to send actions to the context controller.
self._soundjs.on('ended',function() { self.videoEnded.apply(self, arguments); });
Credit: #teddyzeenny

Emberjs - Pass an object from the view to controller

I am using a radialProgress as a jQuery plugins (homemade), and I need to implement it for ember but I have some issue to do that.
Quick explanation for the plugins :
var chart = $(yourElement).pieChart(options); // initialise the object to an element
chart.setCompleteProgress( complete, false ); // set how many item you have to complete the task
chart.incrementProgress(); // increment + 1 every time you call it
It's a very simple progress pie.
In my case my task are located inside my controller, but the chart as to select a dom element so I need to initialise it inside my view.
My task in the controller are called from the router from the setupController to reload the model over time.
Here is a small sample of what I would like to do :
App.ApplicationRoute = Ember.Route.extend({
setupController: function(controller) {
var promise = controller.getModel();
this._super(controller, promise);
}
})
App.ApplicationController = Ember.ArrayController.extend({
getModel: function() {
// chart.setcompleteProgress();
// A lot of code are here to get some data
// chart.incrementProgress();
return newModel;
}
})
App.ApplicationView = Ember.View.extend({
didInsertElement: function() {
var chart = $(element).pieChart(opts);
}
})
I don't know how to pass the chart object from the view to the controller to be able to have access to my plugin function.
Che chart won't be inserted into the DOM until the didInsertElement therefore you can't attempt to manipulate it in the route during setupController etc. I'd suggest creating a method in the controller setupChart and calling that on didInsertElement.
App.ApplicationView = Ember.View.extend({
prepPieChart: function() {
var chart = $(element).pieChart(opts);
this.get('controller').setupPieChart(chart);
}.on('didInsertElement')
})
App.ApplicationController = Ember.ArrayController.extend({
setupPieChart: function(chart) {
chart.setcompleteProgress();
// A lot of code are here to get some data
chart.incrementProgress();
}
})
All that being said, maybe it belongs in the view, but I'm not sure of what you're completely doing.

Adding Model to a hasmany relationship wont unpdate

I am trying to add model to a hasmany relationship. In my route I have:
App.CourseRoute = Ember.Route.extend({
model: function(){
return this.store.find('course','-JNPcfHFQC8FNwyt_-Wh');
}
});
and in my controller I have a save action:
App.CourseController=Ember.ObjectController.extend({
actions: {
save: function() {
var _this = this;
var course = this.get('model');
_this.get('session').get('user').get("courses").pushObject(course)
_this.get('session').get('user').save()
}
}
});
The session property refers a global sessions object that is injected into the controller. This project is using firebase and emberFire data adapter. No errors are being thrown and no data is updated on the firebase backend. I can't seem to figure out what is going on.
Breakpoint your code before the save call and you'll probably see that this.get('session').get('user') has an isDirty property of false. So the save becomes a no-op. You can try to solve that by callingthis.get('session').get('user').notifyPropertyChange('courses').

What is the new official way to get from a controller the value of an instance variable of an other one controller

What is the new way to get from a controller the value of an instance variable of an other controller.
For instance, I was using before I was using before
App.router.get("applicationController.isLoopingEnabled") to access the value and App.router.set("applicationController.isLoopingEnabled") to set the value of isLoopingEnabled variable from my PlaybarController instance.
I just want to know what is the best practice right now on Ember RC3. I'm experiencing a lot of problems to upgrade from the pre-version.
There isn't "one way" to access properties of different controllers anymore. It depends on where you want to access it from.
To access a controller from another controller:
Use the Controller's needs depedency
Example:
App.PostsController = Em.ArrayController.extend({
someValue: 1
});
App.CommentsController = Em.ArrayController.extend({
needs: ['posts'],
postsValuePlusOne: function() {
return this.get('controllers.posts.someValue') + 1;
}).property('controllers.posts.someValue')
});
To access a controller from a route:
App.PostsController = Em.ArrayController.extend({
someValue: 1
});
App.CommentsRoute = Em.Route.extend({
renderTemplate: function() {
var someValue = this.controllerFor('posts').get('someValue');
}
});
To access a controller from a view:
App.PostsController = Em.ArrayController.extend({
someValue: 1
});
App.PostsView = Em.View.extend({
someValueBinding: 'controller.someValue'
});
If you want to access a value of a controller other than the view's controller (for example CommentsController, use the controller's needs: controller.controllers.comments.someValue
Finally,
There is a global method to access any controller, but use this only for debugging and testing, never in production:
var postsController = App.__container__.lookup('controller:posts')

How to get any controller instance from init() method of a view?

I am migrating my project from older version of EmberJS. In some places i used to get controller instance which is not related to the view, by using following in any view's init() method:
var controller = App.get('router').get('firstController');
But now this throws following error.
Uncaught TypeError: Cannot call method 'get' of undefined
This may be because it is not able to get the Router object. Now how to get controller instance which is not related to the view? or how to get the Router Object
The 'needs' feature allows a controller to access to other controllers, which allows a controller's view to access other controllers. (a good explanation of needs in Ember: http://darthdeus.github.com/blog/2013/01/27/controllers-needs-explained/)
As explained in Cannot access Controller in init function of View in 1.0.0rc, the controller property of a view is not yet set when init() is called, so you will need to access controller at a later time in the view's life cycle. This could be the willInsertElement() or didInsertElement() hooks, for example.
Here is an example demonstrating using needs access another controller from a view:
http://jsbin.com/ixupad/186/edit
App = Ember.Application.create({});
App.ApplicationController = Ember.Controller.extend({
doSomething: function(message) {
console.log(message);
}
});
App.IndexView = Ember.View.extend({
templateName: 'index',
init: function() {
this._super();
// doesn't work, controller is not set for this view yet see:
// https://stackoverflow.com/questions/15272318/cannot-access-controller-in-init-function-of-view-in-1-0-0rc
//this.get('controller.controllers.application').doSomething("from view init");
},
willInsertElement: function() {
this.get('controller.controllers.application').doSomething("from view willInsertElement");
},
clickMe: function() {
this.get('controller.controllers.application').doSomething("from clickMe");
}
});
App.IndexController = Ember.Controller.extend({
needs: ['application']
});