PDA

View Full Version : Overriding methods in extended mixin doesn't work



vollekannehoschi
16 Sep 2012, 11:24 PM
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?



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'
}
});

vietits
17 Sep 2012, 1:34 AM
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:


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.


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.


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.


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.

vollekannehoschi
17 Sep 2012, 4:55 AM
Ah ok, thank you!

albanirneves
29 Aug 2017, 2:34 PM
Answering in 2017 for Ext 6.5:



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:



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.