rmcsharry
rmcsharry

Reputation: 5552

EmberJS 2.7 - using a closure action to call a function vs calling that function as an action

In Ember with closure actions you can pass a function, like this:

1

    <div class="dropzone text-center" {{action (action openFilePicker)}}>   
<!-- this calls a function (no quotes!) -->
    </div>

instead of calling an action, like the following.

2

    <div class="dropzone text-center" {{action (action 'openFilePicker')}}> 
<!-- this calls an action (quotes!) -->
    </div>

In (1) the code backing this component looks like this:

  openFilePicker: function () {
    let child = this.$('div:first-child');
    child.removeClass('is-dragging');
    child.html('<h2>Upload GPX Route</h2><div class="dropzone-body-text"><h5>Drag and Drop here</h5>- or -<h5>click anywhere here</h5></div>');
    filepicker.pick({
      container: 'modal',
      maxSize: (5 * 1024 * 1024),
      services: ['COMPUTER']
    });
  }

This uses JQuery to remove some elements from the DOM, then calls another function (filepicker.pick) which is in an externally loaded JS file.

In (2) the same code is inside an action:

actions: {
    openFilePicker: function () {
        let child = this.$('div:first-child');
        child.removeClass('is-dragging');
        child.html('<h2>Upload GPX Route</h2><div class="dropzone-body-text"><h5>Drag and Drop here</h5>- or -<h5>click anywhere here</h5></div>');
        filepicker.pick({
          container: 'modal',
          maxSize: (5 * 1024 * 1024),
          services: ['COMPUTER']
        });
    }
}

What are the pros and cons of doing this? I understand that (1) is not the recommended way of doing this, but surely (1) makes it easier to access other code in the component (like properties of the component, for example). As usual the Ember documentation doesn't seem to shed any light on this (not that I can find anyway). All I can find is this blog post which makes the point to discourage calling arbitrary functions (otherwise why have actions in the first place?)

So although this question can result in opinions, that's not what I am after. I want to understand what is the SCOPING difference between these two approaches? For example, when you are inside the function INSIDE the action, what is the scope difference from the point of view of the JS runtime? Is 'this' the same thing in both cases, for example?

Upvotes: 1

Views: 419

Answers (1)

Lux
Lux

Reputation: 18240

There is not really a difference. Checkout this twiddle.

The only big difference is the action lookup time. While {{action 'foo'}} requires foo to exist on bound time, this is not a required for ={{action 'foo'}} (a closure action).

Action calls are bound by ember to the current this context. This is basically what the {{action}} helper for closure actions does. It creates a new function that calls the original function with this being the context when the {{action}} helper was evaluated.

If you call another function outside your current function scope this will always be different. Its important to understand that this is always bound to the function scope.

If you call a function like myfunction() then this inside that function will be null. If you call a function like foo.myfunction() then this inside myfunction will be foo.

Make sure that you understand this completely. In a nutshell, this is no way different in Ember. It's standard Javascript.

Upvotes: 1

Related Questions