What is the use of callParent

Mr_Green picture Mr_Green · Aug 1, 2013 · Viewed 8.9k times · Source

I have gone through this online tutorial to understand basic concepts of Sencha touch. Now, I am sure that I can look forward to begin coding for the real project with my knowledge.

But I have a question about the functionality of this.callParent(arguments) used by the Author in the tutorial.

I know the name clearly indicates that the "parent class of this is being called".
But I have questions like: (related to the tutorial)

  • Why we are calling the parent class?
  • Will this run the parent class again completely?

Please help me to understand callParent related to the above tutorial.

I have gone through the touch docs which I can't understand. (The explanation seems completely different to me with respect to the Author's code).

Project download link

Answer

Viswa picture Viswa · Aug 1, 2013

As you mentioned in your question this.callParent(arguments) calls the appropriate function in the super class.

That is Calling this.callParent(arguments) in a constructor calls the constructor of the super class that is being extended.

In the tutorial you mentioned, This is what the Author doing.

launch: function () {
  //This line simply calls the super class(Ext.app.Controller) launch function  
  this.callParent(arguments);
  var notesStore = Ext.getStore("Notes");
  notesStore.load();
  console.log("launch");
},

 init: function () {
  // This line simply calls the super class(Ext.app.Controller) init function   
  this.callParent(arguments); 
  console.log("init");
 }

But why he doing this, I am not sure because there is no need to call Ext.app.Controller class init and launch function in that tutorial.

Let me explain with example

1) Creating super class called Main

Ext.define('MyApp.controller.Main', {
    extend: 'Ext.app.Controller',

    launch: function () {
       console.log("Main launch");
    },      

    init: function () {
       console.log("Main init");
    },    

    config: {

    } 
});

2) Create subclass SubMain that extends MyApp.controller.Main

Ext.define('MyApp.controller.SubMain', {
    extend: 'MyApp.controller.Main',

    launch: function () {
        this.callParent(arguments);
       console.log("launch");
    },

     init: function () {
        this.callParent(arguments);
       console.log("init");
     },

    config: {
    }
});

Now when you run your application, the console.log we placed in both super and subclass will print following in browser console

Output

Main init 
Main init 
SubMain init 
Main launch 
Main launch
SubMain launch 

As we know that when we launch application init and launch function of every controller will be invoked once.

But, you see Main init & Main launch function is called twice, Why?

The reason it's called init and launch function of super class again is because of we placed this.callParent(arguments); in init and launch function of SubMain, that is calling init and launch function of Main(super class) class once again.

There is more, What about arguments which passed in callParent function

arguments is a special parameter.

Now, let us take an example to test

Ext.define('Mail.controller.Messages', {
    extend: 'Ext.app.Controller',

    config: {
        refs: {
            viewer: 'messageviewer',
            messageList: 'messagelist'
        },
        control: {
            messageList: {
                itemtap: 'loadMessage'
            }
        }
    },

    loadMessage: function(item) {
        this.getViewer().load(item);
    }
});

Mail.controller.phone.Messages class extends Mail.controller.Messages, this simply means all the configuration and functions are inherited.

 Ext.define('Mail.controller.phone.Messages', {
    extend: 'Mail.controller.Messages',

    config: {
        refs: {
            main: '#mainPanel'
        }
    },

    loadMessage: function(item) {
        // Without this line loadMessage function of super class will not be invoked
        this.callParent(arguments);
        this.getMain().setActiveItem(1);
    }
});

Now when the user tabs on a item in messageList the loadMessage function in Mail.controller.phone.Messages class will be invoked.

Also we placed this.callParent(arguments); at loadMessage function, so first Mail.controller.Messages class loadMessage function will be invoked and then this.getMain().setActiveItem(1); line will run.

As mentioned earlier loadMessage function in Mail.controller.Messages will not be invoked until you place this.callParent(arguments); in loadMessage function at Mail.controller.phone.Messages class.

Note that item argument will be only passed to loadMessage function of Mail.controller.phone.Messages, but loadMessage function of Mail.controller.phone.Messages still gets the item argument, How ?

It's Because of arguments you passed in this.callParent function within loadMessage function of Mail.controller.phone.Messages class.