Search code examples
javascriptcoffeescriptjquery-ui-dialogmarionetteregion

Marionette js - how does coffeescript's fat arrow translate to Javascript in this custom region I'm building?


At 22:30 of this video tutorial, https://www.youtube.com/watch?v=hBVYDVy3QNI, the author does something in coffeescript that I'm unable to translate to Javascript. He maintains the context of a custom region from within an inner callback using a fat arrow. As such, he is able to call close on the region from within a dialog close callback? How do I do that in Javascript?

Here is my custom region attempt but it fails on the call to this.closeDialog() because "this" refers to the dialog and not the region:

    var DialogRegion = Backbone.Marionette.Region.extend({

        onShow: function (view) {
            this.$el.dialog({
                modal: true,
                resizable: false,
                draggable: false,
                width: "600px",
                close: function (e, ui) {
                        this.closeDialog()//This doesn't work.  Wrong context.  Need outer DialogRegion context?                
                }
            })
        },        

        closeDialog: function () {
            this.close();
            this.$el.dialog("destroy");
        }

    }); 

Solution

  • If you can assume a reasonably modern JavaScript then you can use Function.prototype.bind:

    The bind() method creates a new function that, when called, has its this keyword set to the provided value [...]

    That would look like this:

    close: function (e, ui) {
        this.closeDialog();
    }.bind(this)
    

    You're using Marionette so you're using Backbone and that implies that Underscore is available. That means that you could use _.bind if you don't want to use the native bind:

    close: _(function (e, ui) {
        this.closeDialog();
    }).bind(this)
    

    You're using jQuery-UI so you should have $.proxy available too. $.proxy serves the same purpose as _.bind and you'd use it thusly:

    close: $.proxy(function(e, ui) {
        this.closeDialog();
    }, this)
    

    The "classic" option is the one that elclanrs mentions in the comments:

    onShow: function (view) {
        var _this = this;
        this.$el.dialog({
            //...
            close: function (e, ui) {
                _this.closeDialog()
            }
        });
    }
    

    All four of those will be functionally equivalent to the close: (e, ui) => ... you saw in the CoffeeScript video.