Access application controller from didinsertelement view - ember.js

I want to access application controller so I can get/set a variable (selected_date) value.
myApp.ApplicationController = Ember.Controller.extend({
selected_date: null,
actions: {
}
}
});
I would like to make edits to selected_date from a view (didinsertelement), the controller for the view is:
myApp.CreportController = Ember.ObjectController.extend({
needs: ["application"]
});
view:
CreportController View = Ember.View.extend({
didInsertElement: function() {
var controller = this.get('controller');
var selected_date = controller.get('controllers.application').get('selected_date');
...

You have your properties wrong. Using the needs functionality puts those controllers in a controllers property. Your view can then access its own controller using the controller property. So you need to do this in your view:
didInsertElement: function() {
var selected_date = this.get('controller.controllers.application').get('selected_date');
}

I updated the code with the solution:
var controller = this.get('controller');
var selected_date = controller.get('controllers.application').get('selected_date');

Related

Set computed property from another controller

I am trying to set the value of a computed property from one controller to another.
var BusinessOwner = Ember.ObjectController.extend({
actions: {
save: function(){
var self = this;
return Ember.$.ajax({
}).then(function(){
var ownerShow = self.store.getById('application',100);
ownerShow.get('ownerGeneral');
ownerShow.set('ownerGeneral', 'complete')
Ember.set(self, 'controllers.collectinfo.ownerGeneral','completed');
//self.set('controllers.collectinfo.ownerGeneral', "completed");
});
}
}
I have tried several different attempts at setting this property but have proved unsuccessful. If I use the self set, errors that I must use Ember.set(). If I use Ember.set() I get error collectinfo must be global if no obj given.
Thanks for any help
EDIT:
Thanks for looking at this. Yes I am includeing needs: 'collectinfo' I am still getting the error that Ember.set() needs to be used to set the object
You need to provide needs array in the controller as well.
var BusinessOwner = Ember.ObjectController.extend({
needs: 'collectinfo'
actions: {
save: function(){
var self = this;
return Ember.$.ajax({
}).then(function(){
var ownerShow = self.store.getById('application',100);
ownerShow.get('ownerGeneral');
ownerShow.set('ownerGeneral', 'complete')
Ember.set(self, 'controllers.collectinfo.ownerGeneral','completed');
//self.set('controllers.collectinfo.ownerGeneral', "completed");
});
}
}
Coding wise i suggest you create a own computed property for the one you want to access from other controller. So code becomes like this.
var BusinessOwner = Ember.ObjectController.extend({
needs: 'collectinfo',
ownerGeneral: Ember.computed.alias('controllers.collectinfo.ownerGeneral')
actions: {
save: function(){
var self = this;
return Ember.$.ajax({
}).then(function(){
var ownerShow = self.store.getById('application',100);
ownerShow.get('ownerGeneral');
ownerShow.set('ownerGeneral', 'complete')
Ember.set(self, 'ownerGeneral','completed');
//self.set('controllers.collectinfo.ownerGeneral', "completed");
});
}
}
You can set dependencies between controller with the controller needs property, it's documented at Ember Guide.
App.IndexController = Em.Controller.extend({
needs: 'application',
message: 'hi!',
actions: {
changeApplicationMessage: function() {
this.set('controllers.application.message', 'good bye');
},
changeMessage: function(){
this.set('message', 'bye');
}
}
});
The dependent controller property will be accesible in the controller at {{controllers.controllerName.propertyName}}
Demo: http://emberjs.jsbin.com/vevet/1/edit
In addition to what others said about "needs," just declare a shortcut variable for set and get:
var get = Ember.get;
var set = Ember.set;
and then use them like so:
set(object, 'property', 'value-to-set-property-to');
I assume that your controller declares a needs property with "collectInfo" as value? Then it should work this way:
var BusinessOwner = Ember.ObjectController.extend({
needs : ['collectInfo'],
actions: {
save: function(){
var collectinfoController = this.get('controllers.collectinfo');
return Ember.$.ajax({
}).then(function(){
var ownerShow = self.store.getById('application',100);
ownerShow.get('ownerGeneral');
ownerShow.set('ownerGeneral', 'complete')
collectinfoController.set('ownerGeneral','completed');
});
}
}

Ember.js get controller in view

I feel like this should be pretty straight-forward, but I'm unable to get the contents of a controller in a different view. Here is my code:
App.MapView = Ember.View.extend({
elementId: ['map-canvas'],
didInsertElement: function() {
var self = this;
var controller = this.get('controllers.markers');
}
});
If I console.log(controller) I get undefined.
In a controller I would do something like:
App.MarkersController = Ember.ArrayController.extend({
needs: ['map']
});
App.MapController = Ember.ObjectController.extend({
plot: function() {
var markers = this.get('controllers.markers');
}
});
You place the needs on the controller that needs another controller, and where you'll be accessing the other controller.
And from a view, in order to grab the controller you do this.get('controller') and the controllers object lives on the controller, so controller.controllers.markers
Additionally, the view is only created with the controller by default if ember creates it, if you are doing something like {{view App.MapView}} it isn't creating the MapController and associating it with it, it's using the controller that was in scope when you created the view.
App.MapView = Ember.View.extend({
elementId: ['map-canvas'],
didInsertElement: function() {
var self = this;
var controller = this.get('controller.controllers.markers');
}
});
App.MarkersController = Ember.ArrayController.extend({
});
App.MapController = Ember.ObjectController.extend({
needs: ['markers'],
plot: function() {
var markers = this.get('controllers.markers');
}
});
Check out this implementation of it:
http://emberjs.jsbin.com/ODuZibod/1/edit

How to disable a text field in emberJS when controller loads data

I have the following controller:
var ProductsController = Ember.ArrayController.extend({
search: function(queryString) {
this.set('model', App.Product.find({query: queryString }));
}
});
and a text field:
var SearchFieldView = Ember.TextField.extend({
insertNewline: function() {
this.get('controller').search(this.get('value'));
}
});
Now I want to disable the text field when the controller loads a new model in the search function. Using something like disabledBinding: 'controller.content.isLoaded' in the view doesn't work.
var ProductsController = Ember.ArrayController.extend({
search: function(queryString) {
this.set('isLoadingData', true);
var products = App.Product.find({query: queryString });
this.set('model', products);
products.then(function() {
this.set('isLoadingData', false);
});
}
});
var SearchFieldView = Ember.TextField.extend({
attributeBindings: ['disabled'],
disabledBinding: 'controller.isLoadingData',
insertNewline: function() {
this.get('controller').search(this.get('value'));
}
});
Explanation:
Before doing a request set isLoadingData to true. ember-data find() uses the Promise API: Set the isLoadingData to false when the request has been completed successfully. You might want to handle the failed case. See RSVP.js for reference. Finally bind the disabled property of Ember.TextField to controller.isLoadingData.
A simpler way, as you have already tried:
var ProductsController = Ember.ArrayController.extend({
search: function(queryString) {
this.set('model', App.Product.find({query: queryString }));
}
});
var SearchFieldView = Ember.TextField.extend({
attributeBindings: ['disabled'],
disabled: function() {
return this.get('controller.model.isLoaded') === false;
}.property('controller.model.isLoaded'),
insertNewline: function() {
this.get('controller').search(this.get('value'));
}
});
If you want all the Ember.TextField to have the disabled property binding:
Ember.TextField.reopen({
attributeBindings: ['disabled']
});

Ember.js bind class change on click

How do i change an elements class on click via ember.js, AKA:
<div class="row" {{bindAttr class="isEnabled:enabled:disabled"}}>
View:
SearchDropdown.SearchResultV = Ember.View.extend(Ember.Metamorph, {
isEnabled: false,
click: function(){
window.alert(true);
this.isEnabled = true;
}
});
The click event works as window alert happens, I just cant get the binding to.
The class is bound correctly, but the isEnabled property should be modified only with a .set call such as this.set('isEnabled', true) and accessed only with this.get('isEnabled'). This is an Ember convention in support of first-class bindings and computed properties.
In your view you will bind to a className. I have the following view in my app:
EurekaJ.TabItemView = Ember.View.extend(Ember.TargetActionSupport, {
content: null,
tagName: 'li',
classNameBindings: "isSelected",
isSelected: function() {
return this.get('controller').get('selectedTab').get('tabId') == this.get('tab').get('tabId');
}.property('controller.selectedTab'),
click: function() {
this.get('controller').set('selectedTab', this.get('tab'));
if (this.get('tab').get('tabState')) {
EurekaJ.router.transitionTo(this.get('tab').get('tabState'));
}
},
template: Ember.Handlebars.compile('<div class="featureTabTop"></div>{{tab.tabName}}')
});
Here, you have bound your className to whatever the "isSelected" property returns. This is only true if the views' controller's selected tab ID is the same as this views' tab ID.
The code will append a CSS class name of "is-selected" when the view is selected.
If you want to see the code in context, the code is on GitHub: https://github.com/joachimhs/EurekaJ/blob/netty-ember/EurekaJ.View/src/main/webapp/js/app/views.js#L100
Good answers, however I went down a different route:
SearchDropdown.SearchResultV = Ember.View.extend(Ember.Metamorph, {
classNameBindings: ['isSelected'],
click: function(){
var content = this.get('content');
SearchDropdown.SelectedSearchController.set('content', content);
var loadcontent = this.get('content');
loadcontent.set("searchRadius", $("select[name=radius]").val());
SearchDropdown.LoadMap.load(content);
},
isSelected: function () {
var selectedItem = SearchDropdown.SelectedSearchController.get('content'),
content = this.get('content');
if (content === selectedItem) {
return true;
}
}.property('SearchDropdown.SelectedSearchController.content')
});
Controller:
SearchDropdown.SelectedSearchController = Ember.Object.create({
content: null,
});
Basically stores the data of the selected view in a controller,

How do you test your emberjs routes?

After a few months without looking at emberjs, I'm trying to go back into it now, and I'm therefore trying the new router. And I would like to test my routes.
Has anybody tried to write some routing tests with emberjs ?
Let's suppose the very basic following router :
App.Router = Ember.Router.extend({
root: Ember.Route.extend({
index: Ember.Route.extend({
route: '/',
connectOutlets: function(router, context) {
router.get('applicationController').connectOutlet({name: 'home'});
}
})
})
})
How do you test that loading the root.index route properly loads the HomeView ?
Here is the full test, using Jasmine & Sinon :
code:
describe("Given the Router", function(){
var router = null;
beforeEach(function(){
router = Router.create();
});
afterEach(function(){
router = null;
});
it("Should be defined", function(){
expect(router).toBeDefined();
});
it("Should have an root route", function(){
expect(router.get("root")).toBeDefined();
});
describe("its root route", function(){
var root = null;
beforeEach(function(){
root = router.get("root").create();
});
afterEach(function(){
root = null;
});
it("should have an index route", function(){
expect(root.get("index")).toBeDefined();
});
describe("its index route", function(){
var indexRoute = null;
beforeEach(function(){
indexRoute = root.get("index").create();
});
it ("should have route of /", function(){
expect(indexRoute.get("route")).toEqual("/");
});
it ("should connect the outlets to home", function(){
var fakeRouter = Em.Object.create({applicationController: {connectOutlet: function(){} } });
var connectOutletSpy = sinon.spy(fakeRouter.applicationController, "connectOutlet");
var methodCall = connectOutletSpy.withArgs({name:"home"});
indexRoute.connectOutlets(fakeRouter);
expect(methodCall.calledOnce).toBeTruthy();
});
});
});
});
Hope it helps.
Here is how Ember has already tested the connectOutlet for you:
https://github.com/emberjs/ember.js/blob/master/packages/ember-views/tests/system/controller_test.js
test("connectOutlet instantiates a view, controller, and connects them", function() {
var postController = Ember.Controller.create();
var appController = TestApp.ApplicationController.create({
controllers: { postController: postController },
namespace: { PostView: TestApp.PostView }
});
var view = appController.connectOutlet('post');
ok(view instanceof TestApp.PostView, "the view is an instance of PostView");
equal(view.get('controller'), postController, "the controller is looked up on the parent's controllers hash");
equal(appController.get('view'), view, "the app controller's view is set");
});
Other routing related tests can be found at https://github.com/emberjs/ember.js/tree/master/packages/ember-routing/tests