Results 1 to 4 of 4

Thread: Overriding methods in extended mixin doesn't work

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1

    Default Answered: Overriding methods in extended mixin doesn't work

    Hi,

    I'm using Ext 4.1 and can't override a method when I extend a mixin. This code gives me two times "I'm on the highway to hell" when I create an instance of Musician2 and call "sing" on it. What I want is one times "I'm on the highway to hell ...." followed by "2" from the overriden method. Is this a bug or is something wrong with my understatement of mixins in Ext?

    Code:
    Ext.define('CanSing', {
         sing: function(b) {
             console.log("I'm on the highway to hell...", b);
             this.sang();
         },
         sang: function(b) {
             console.log("I'm on the highway to hell...", b);
         }
    });
    
    
    Ext.define('CanSing2', {
        extend:'CanSing',
        sang: function(b) {
             console.log("2", b);
         }
    });
    
    
    Ext.define('Musician', {
        mixins: {
            foo: 'CanSing'
        },
    
    
        sing: function(b) {
            this.mixins.foo.sing.call(this);
        }
    
    
    });
    
    
    Ext.define('Musician2', {
        extend:'Musician',
        mixins: {
            foo: 'CanSing2'
        }
    });
    

  2. This is normal. To understand, you should follow the following rules when defining a class:
    - Extending class will be done before mixing classes: During extending, members form parent class will be attached to class prototype.
    - During mixing classes, members from mixins classes only be attached to class prototype if it does not exists yet.
    Follow these rules, let try to walk thru the code:
    Code:
    Ext.define('CanSing', {
        sing: function(b) {
            console.log('CanSing.sing')
            console.log("I'm on the highway to hell...", b);
            this.sang();
        },
        sang: function(b) {
            console.log('CanSing.sang')
            console.log("I'm on the highway to hell...", b);
        }
    });
    CanSing.prototype will contain sing() and sang() methods.
    Code:
    Ext.define('CanSing2', {
        extend:'CanSing',
        sang: function(b) {
            console.log('CanSing2.sang')
            console.log("2", b);
        }
    });
    CanSing2.prototype will contain:
    - sing() method from extending CanSing class.
    - sang() method form CanSing2 definition.
    Code:
    Ext.define('Musician', {
        mixins: {
            foo: 'CanSing'
        },
        sing: function(b) {
            console.log('Musician.sing')
            this.mixins.foo.sing.call(this);
        }
    });
    Musician prototype will contain:
    - sing() from Musician definition.
    - sang() from mixing CanSing class.
    Code:
    Ext.define('Musician2', {
        extend:'Musician',
        mixins: {
            foo: 'CanSing2'
        }
    });
    Musician2 prototype will contain:
    - sing() method from extending Musician.
    - sang() method from extending Musician which is from CanSing.
    sang() from mixing CanSing2 will not be attached to Musician2 prototype.

  3. #2
    Sencha User
    Join Date
    Jan 2012
    Posts
    1,376
    Answers
    347

    Default

    This is normal. To understand, you should follow the following rules when defining a class:
    - Extending class will be done before mixing classes: During extending, members form parent class will be attached to class prototype.
    - During mixing classes, members from mixins classes only be attached to class prototype if it does not exists yet.
    Follow these rules, let try to walk thru the code:
    Code:
    Ext.define('CanSing', {
        sing: function(b) {
            console.log('CanSing.sing')
            console.log("I'm on the highway to hell...", b);
            this.sang();
        },
        sang: function(b) {
            console.log('CanSing.sang')
            console.log("I'm on the highway to hell...", b);
        }
    });
    CanSing.prototype will contain sing() and sang() methods.
    Code:
    Ext.define('CanSing2', {
        extend:'CanSing',
        sang: function(b) {
            console.log('CanSing2.sang')
            console.log("2", b);
        }
    });
    CanSing2.prototype will contain:
    - sing() method from extending CanSing class.
    - sang() method form CanSing2 definition.
    Code:
    Ext.define('Musician', {
        mixins: {
            foo: 'CanSing'
        },
        sing: function(b) {
            console.log('Musician.sing')
            this.mixins.foo.sing.call(this);
        }
    });
    Musician prototype will contain:
    - sing() from Musician definition.
    - sang() from mixing CanSing class.
    Code:
    Ext.define('Musician2', {
        extend:'Musician',
        mixins: {
            foo: 'CanSing2'
        }
    });
    Musician2 prototype will contain:
    - sing() method from extending Musician.
    - sang() method from extending Musician which is from CanSing.
    sang() from mixing CanSing2 will not be attached to Musician2 prototype.

  4. #3

    Default

    Ah ok, thank you!

  5. #4

    Default

    Answering in 2017 for Ext 6.5:

    Code:
    Ext.define('Overrides.app.ViewController', {
        override:'Ext.app.ViewController',
    
    
        constructor: function () {
            var i, j;
    
    
            this.callParent(arguments);
    
    
            //child mixins override parent mixins
            if(this.mixins) {
                for(i in this.mixins){
                    for(j in this.mixins[i].functions) {
                        this[j] = this[j] || this.mixins[i].functions[j];
                    }
                }
            }  
        }
    });
    Then declare your mixin like that:

    Code:
    Ext.define('MyMixin', {
        extend: 'Ext.Mixin',
    
    
        functions: {
            myFunction: () => {
                console.log('do something');
            }
        }
    });
    This way if child mixin has some function with same name of parent mixin, it will be overrided.
    Thanks
    Albanir Neves

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •