emberjs action event.target is undefined - ember.js

Here's a link to a jsfiddle: http://jsfiddle.net/Qt972/
When you run the fiddle you'll see a name and a button to make the "person" say hello. This works fine, however the "event" is undefined.
An even simpeler case also fails:
http://jsfiddle.net/CCg2K/1/
Does anyone know how I can fix this issue?

When you do a console.log(arguments) inside your action callback you can see that there are actually 3 parameters passed. The first one is the view, the second is the event and the third is the context.
You can rewrite your edit action like this:
edit: function(view, event, context) {
var target = event.target;
...
}
UPDATE: since commit 657a2664 - available in release 0.9.6 I guess - only a single event parameter is passed which has the view and context as properties. So if you want to access those you have to do the following:
edit: function(event) {
var view = event.view;
var context = event.context;
...
}

Related

Ember active link

I have a route where I want to make a sibling route's link-to's active as well. I have tried using current-when in the link-to, but it's not working for me.
my routes are as follows
//projects
//projects/:project_id
//projects/:project_id/user/:user_id
When I navigate to //projects/:project_id route, the right link is set to active. I want the same link to be active on the //projects/:project_id/users/:user_id route.
My link-to in the parent //projects hbs template is
{{#link-to "projects.project" item.projectID current-when="projects.user" tagName="tr"}}
What am I doing wrong here?
UPDATE
I was able to get it to initially work when the route is rendered by using an edited version of #ykaragol's helper function and link-to...
{{#link-to "projects.project" item.projectName active=(calculate-active 'projects.user projects.project' item.projectName) tagName="tr"}}
compute(params, hash){
var pathname = window.location.pathname.split('/');
var pathProj = pathname[2];
var currRoute = this.get('currentRouteName');
var routes = params[0].split(' ');
if( ($.inArray( currRoute, routes) > -1) && (pathProj == params[1]) ){
return true;
}
return false;
}
But it's not updating when I click on a different project...
If routes don't have dynamic segments, it works as described in docs. I've tested it within this twiddle.
But I couldn't make it work while using dynamic segment. Please check this twiddle. I suspect this maybe a bug. You can ask this question in slack.
By the way, as a workaround, you can pass a boolean to the currentWhen property (as mentioned in docs). So you can write a helper or a computed property to calculate it with a regex.
Updated:
As a second workaround, you can handle active property of link-to by yourself. Try this twiddle.

How to get current page from Navigation in ionic 2

I am new to Ionic2, and I am trying to build dynamic tabs based on current menu selection. I am just wondering how can I get current page using navigation controller.
...
export class TabsPage {
constructor(navParams: NavParams,navCtrl:NavController) {
//here I want to get current page
}
}
...
From api documentation I feel getActiveChildNav() or getActive() will give me the current page, but I have no knowledge on ViewController/Nav.
Any help will be appreciated. Thanks in advance.
Full example:
import { NavController } from 'ionic-angular';
export class Page {
constructor(public navCtrl:NavController) {
}
(...)
getActivePage(): string {
return this.navCtrl.getActive().name;
}
}
Method to get current page name:
this.navCtrl.getActive().name
More details here
OMG! This Really Helped mate, Tons of Thanks! #Deivide
I have been stuck for 1 Month, Your answer saved me. :)
Thanks!
if(navCtrl.getActive().component === DashboardPage){
this.showAlert();
}
else
{
this.navCtrl.pop();
}
My team had to build a separate custom shared menu bar, that would be shared and displayed with most pages. From inside of this menu component.ts calling this.navCtrl.getActive().name returns the previous page name. We were able to get the current page name in this case using:
ngAfterViewInit() {
let currentPage = this.app.getActiveNav().getViews()[0].name;
console.log('current page is: ', currentPage);
}
this.navCtrl.getActive().name != TheComponent.name
or
this.navCtrl.getActive().component !== TheComponent
is also possible
navCtrl.getActive() seems to be buggy in certain circumstances, because it returns the wrong ViewController if .setRoot was just used or if .pop was just used, whereas navCtrl.getActive() seems to return the correct ViewController if .push was used.
Use the viewController emitted by the viewDidEnter Observable instead of using navCtrl.getActive() to get the correct active ViewController, like so:
navCtrl.viewDidEnter.subscribe(item=> {
const viewController = item as ViewController;
const n = viewController.name;
console.log('active page: ' + n);
});
I have tested this inside the viewDidEnter subscription, don't know about other lifecycle events ..
Old post. But this is how I get current page name both in dev and prod
this.appCtrl.getActiveNav().getActive().id
Instead of
...
...
//In debug mode alert value is 'HomePage'
//In production/ signed apk alert value is 'n'
alert(activeView.component.name);
if (activeView.component.name === 'HomePage') {
...
...
Use this
...
...
//In debug mode alert value is 'HomePage'
//In production/ signed apk alert value is 'HomePage'
alert(activeView.id);
if (activeView.id === 'HomePage') {
...
...
Source Link
You can use getActive to get active ViewController. The ViewController has component and its the instance of current view. The issue is the comparsion method. I've came up to solution with settings some field like id:string for all my Page components and then compare them. Unfortunately simple checking function name so getActive().component.name will break after minification.

Ember.Controller array content filtering

I have a fiddle http://jsfiddle.net/kristaps_petersons/9wteJ/2/ it loads 3 objects and shows them in a view. Data is shown alright, but i can not filter it before i show it.
This
nodes: function(){
this.get('controller.content').filter(function(item, idx, en){
console.log('should log this atleast 3x')
})
return this.get('controller.content')
}.property('controller.content')
method is called when template iterates over array of values, but it never goes in to the loop and print console.log('should log this atleast 3x') why is that?
You are trying to replace controller.content while also binding to it. You need to define another property, such as filteredContent and bind it to controller.content. Take a look at how Ember.SortableMixin computes the variable arrangedContent for controllers with a sortProperties variable defined. Using that method as a template I would implement it like this:
filteredContent: Ember.computed('content', function() {
var content = this.get('content');
return this.filter(function(item, idx, en) {
console.log('should log this atleast 3x');
});
}).cacheable()
This should be implemented in the controller, not the view. The controller is the place for data manipulation, computed properties, and bindings.
Then bind the view layout to filteredContent instead of content to show the filtered data. Then both the original content and the filtered content are available.
Ok i got it working, but it feels a bit strange. First i moved method to Controller class and changed it to look like this:
nodes: function(){
console.log('BEFORE should log this atleast 3x', this.get('content.length'))
this.get('content').forEach(function(item, idx, en){
console.log('should log this atleast 3x')
})
console.log('AFTER should log this atleast 3x', this.get('content.length'))
return this.get('content')
}.property('content').cacheable()
as it should be same as buuda's recomedation, because as i understand from docs .poperty() is the same as Ember.computed. As it was still not working, i changed .property('content') to .property('content.#each') and it was working. Fiddle: http://jsfiddle.net/kristaps_petersons/9wteJ/21/ . I guess, that tempate first creates a binding to controller.content and as content itself does not change does not notify this method again, instead template pulls data as it becomes available.

Dynamic templates with knockout

I have a viewmodel whose template I want to change dynamically at runtime when the state of my application changes. I referred to this link
while coming up with my solution.
In my html page I have a div that is bound to a list of view models:
<div class="app"
data-bind="template: {name: templateSelector, foreach: viewModelBackStack}">
</div>
And my templateSelector method looks like this:
this.templateSelector = function(viewModel)
{
if (!_itemTemplate)
{
_itemTemplate = ko.computed(function() {return this.template();}, viewModel);
}
return _itemTemplate();
}
var _itemTemplate;
As can be seen, I am constructing a computed observable which returns viewModel's template.
My viewModel looks like this:
function MyViewModel
{
this.template = ko.observable("MyTemplate");
}
I am changing the value of template as a result of an ajax call being completed and I see that computed observable is called correctly as well (I placed an alert in there to verify it), however the bindings in html does not update the template of my viewmodel. Any help will be appreciated.
UPDATE: I found the bug that was causing it not to work. Basically I was including jquery.tmpl plugin before including knockout.js. Removing jquery.tmpl did the trick !
I don't see a problem with your code, unless it lies in the part where you update the template observable as the result of an AJAX call. Make sure that you have a reference to your view model and are setting it as an observable vm.template(newValue); and not recreating the observable.
Here is your code working: http://jsbin.com/ipijet/5/edit#javascript,html,live
One thing to note is that bindings are already executed within the context of a computed observable, so it is unnecessary to create your own within your templateSelector function.
You can simply create a function that returns your observable directly like:
this.getTemplate = function(data) {
return data.template();
};
http://jsbin.com/ipijet/3/edit#javascript,html,live
Here is an article that I wrote a while back on this topic: http://www.knockmeout.net/2011/03/quick-tip-dynamically-changing.html

Computed property being observed doesn't fire if changed twice in a row

I have an Ember.Object that I'm updating with a property like below, but if I change primaryDemo twice in a row, it doesn't fire, yet if I change primaryDemo, then Rate, it does change. I'm puzzled as to why this is and how I can fix it.
dependantChanged: function() {
console.log('Firing change');
this.get('_update')(this);
}.observes('primaryDemo', 'Rate', 'Totals'),
UPDATE: So the first answer and fiddle got me thinking as to what the problem was, and it's due to changing a property on an object and not the object itself. I think ember does a hash check to see if there is a difference. In my case I'm already using underscorejs, so I just change the property, then use _.clone(demo) before doing the set. I'd rather not do that, so will wait to see if there is a more elegant solution before closing this.
You don't need to set primaryDemo again. In the example that does nothing. You need to force tell Ember to notify your observer. See this fiddle...
var demo = { Imps: 1, Demo: { Id: 2 } }
var obj = Ember.Object.create({
dependantChanged: function() {
console.log('Firing change');
}.observes('primaryDemo', 'Rate', 'Totals'),
});
obj.set('primaryDemo', demo);
demo.Imps = 2;
obj.set('primaryDemo', demo);
// Notify observers on obj#primaryDemo
Ember.notifyObservers(obj, 'primaryDemo');
​
Can you give more details? I created a simple JSFiddle http://jsfiddle.net/JjbXb/ from your description but changing the same property in a row, as you say, works.
Are you sure the value of primaryDemo is different in your 2 consecutive calls?