0
votes

The referenced fiddle and code here does not actually work. I don't know how to get a controller defined in a one file project. At any rate, my issue is that when I'm in a controller function (afterrender in my case). I can't figure out how to get a reference to testval. if I create a simple example with just lines 19-32 in a separate launch it works (see fiddle: https://fiddle.sencha.com/#fiddle/1ae7 ).

However, in my controller case I'm not getting the testval in my success or failure event. how to pass in context (scope) of my function I'm calling the ajax request from?

https://fiddle.sencha.com/#fiddle/1ae9

Ext.define('mycontroller', {
    extend: 'Ext.app.Controller',
    alias: 'controller.main',
    myfun: function() {
        console.log('controller:myfun');
    }
});



var mypanel = Ext.create('Ext.panel.Panel', {
    controller: {
        type: 'main'
    },
    listeners: {
        afterrender: function() {
            console.log('afterrender');

            var testval = "hi there";

            Ext.Ajax.request({
                method: 'POST',
                url: '/dummy',
                jsonData: 'jsonData',
                scope: this,
                success: function() {
                    // this never gets called, just testing scope
                },
                failure: function() {
                    // testval   IS NOT IN SCOPE, CONFUSED ABOUT SCOPE AND THIS HERE
                    Ext.Msg.alert('info', testval);
                }
            });
        }
    },
    html: 'test panel'
});


Ext.application({
    name: 'Fiddle',

    launch: function() {
        Ext.create('Ext.container.Viewport', {
            layout: 'fit',
            items: [mypanel]
        });

    }
});
1
It's not clear what you are trying to do, just access local variable testval defined inside afterrender, like in your example? Then it should work, controller is not used in your example anywhere, afterrender belongs to the view and you are accessing some local scope variable inside a function. if you want to move the listener to a controller you need to define the listener as listeners: {afterrender:"controller_function"}, and move your function to the controller file. - serg
@serg my issue is that testval is undefined inside of the failure return of the Ext.Ajax.request. In my example (fiddle), I'm just trying to get afterrender to be called and not understanding how to wire it up in fiddle (though that's not my real problem, just trying to demo my real problem) - Peter Kellner
If your real code structure is different from this example it would be helpful to see it, even if it doesn't work inside fiddle. - serg
Your second fiddle fails because you're extending the wrong controller class. It should be Ext.app.ViewController. Once you fix that up it runs and shows the failure message. Otherwise, it's just JS, the testval var is captured in closure scope. - Evan Trimboli
Thanks @EvanTrimboli See you at SenchaCon in November? - Peter Kellner

1 Answers

3
votes

You have to think in basic JS structures to find the scope. The basic structure is a function Ext.Ajax.request(), which takes one(!) parameter in this case.

That single parameter is an object. If you are using this inside an object, this refers to that very object. The pattern used by Sencha to transfer the outer scope into the function would be

var me = this;
Ext.Ajax.request({
    ...
    scope: me,
    ...
});

That said, var testvar is a local variable, which is not scoped into any object - it is scoped to the function block.

        var testval = "hi there";

        Ext.Ajax.request({
            failure: function() {
                // testval IS ALWAYS "IN SCOPE" HERE, NO MATTER WHAT YOU SET scope TO,
                // BECAUSE IT IS DEFINED INSIDE THE SAME FUNCTION BLOCK
                Ext.Msg.alert('info', testval);
            }
        });

That said, I have made a working fiddle for you by just fixing the error I found in browser console.