Handling Callbacks From Dynamically Attached Elements in Ember - templates

I am using the X-editable library with ember. It dynamically creates a view when a button is clicked. In such a situation, what is the correct way to deal with callbacks from this view. Should I create callback functions on my View and hook them up to the dynamically created view using the didInsertElement hook? The view element is not declared in a template and therefore I can't hook it up using an action.
Here's an example of what I've got at the moment. It's working fine, but I'm wondering if there is a better way:
App.NewsItemView = Ember.View.extend({
templateName: 'cms/news_item',
tagName: 'li',
onDateSave: function(e, params) {
self.get('content').set('date', params['newValue']);
},
didInsertElement: function() {
var elementID = this.get('elementId');
var editDate = $("#" + elementID + " .edit-date");
editDate.editable({
autotext: 'never',
display: false,
send: 'never'
});
var self = this;
editDate.on('save', function(e, params) {
self.onDateSave(e, params);
});
}
});

Related

Access application controller from didinsertelement view

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');

integrate hammerJS with emberJS

I'm trying to integrate HammerJS v2.0.2 with EmberJS 1.6.1.
I used many code samples but non of them work, I get different errors. lets take the simplest one.
I implemented this view:
ListApp.ScrollerView = Ember.View.extend({
setupTap: function() {
var self = this;
this.hammer = new Hammer(this.get('element'));
console.log(this.get('element'));
var tap = new Hammer.Tap();
tap.set('enable', true);
this.hammer.add(tap);
this.hammer.on('tap', function() {
console.log('before tap!');
self.tap();
});
}.on('didInsertElement'),
tap: function() {
console.log('tap!');
}
});
but I get the following error after the page is loaded:
Uncaught TypeError: Object.keys called on non-object
any idea why I see this?
Here is working bin with hammer integrated to a view.
Here's the relevant code on how you integrate hammer into a view
App.Hammer = Em.View.extend({
templateName: 'hammer',
setupTap: function() {
Hammer(this.$()[0]).on("tap", this.tap.bind(this));
}.on('didInsertElement'),
tap: function() {
alert('My tamplate name is ' + this.get('templateName'));
}
});

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 call Controllers method by name in new (ember-1.0.0-pre.4) version

I used Ember.ready function to add some keyboard binding like this https://github.com/greggyNapalm/firebat-overlord/blob/master/web_static/static/js/app/app.js#L24 is there any proper way to do this in new version, asking because can't anymore call method by its name?
The best place to do this sort of thing is from the view. Based on your example the appropriate view in this case is probably TestsView. From there you can bind and unbind keyboard bindings when the view is inserted/removed. For example:
var TestsView = Ember.View.extend({
templateName: 'testsTemplate',
didInsertElement: function() {
console.log("Controller: " + this.get('controller').toString());
var self = this;
Mousetrap.bind('ctrl+right', function() {
self.get('controller').goToPage('next');
});
},
wilLRemoveElement: function() {
Mousetrap.unbind('ctrl+right');
}
});
To see what controller is set to, try adding console.log("Controller: " + self.get('controller').toString());

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,