Bleext


Multiple inheritance in Ext 4 (mixins)


mixins-tns

This new version (Ext4) has been written completely new, with the purpose of making it very flexible and easy to learn, one of the new features that this version provides is that now we can do multiple inheritance using mixins. In this tutorial we will see how to use mixins and use them correctly.

To set multiple inheritance to a class we simply have to add the property “mixins”, this property must be an object with all the classes we want to inherit from or want to mix.

Ext.define("Bleext.training.Icon",{
	mixins	: {
		floating		: "Ext.util.Floating",
		observable	: "Ext.util.Observable"
	}
	//......
});

In the previous example we created a class called “Icon”, this class inherits directly from “Ext.Base” because we didn’t explicitly inherit from another class, by using the property “mixins” we are saying that the class “Icon” will inherit from two classes: ” floating “and” observable “.

The Floating class contains the methods necessary to position an element in the coordinates “X” and “Y” that we indicate to the instance, while the class “Observable” allows us to handle events within the class “Icon”.

If at this time we create an instance of “Icon” we will have all the properties and methods of the class “Ext.Base”, “Floating” and “Observable”.

Overriding the constructor

So far we have not defined a constructor for the class we’ve created, so the question is, what constructor of the three classes we are “inheriting” will be executed when the instance is being built?

To answer the previous question we must understand that the “pre-processor” (In a future post I will explain about the pre/post-processors) of mixins copies the methods and properties IF that method or property DOES NOT EXIST in the target class.

According to the mentioned previously the class “Icon” inherits the constructor of the class “Base” by single inheritance, this means that the constructors of “Floating” and “Observable” are not being executed and probably these constructors have important actions. So what we need to do is run the constructors of the mixins manually.

Ext.define("Bleext.training.Icon",{
	mixins	: {
		floating	: "Ext.util.Floating",
		observable	: "Ext.util.Observable"
	},
	
	width	: 100,
	height	: 100,
	border	: true,
	
	constructor	: function(options){
		Ext.apply(this,options);
		
		this.id = Ext.id(null,"icon-");	//Assigning a dynamic identifier

		this.addEvents("moved","created");	//method inherited from the class Observable
		
		if(this.renderTo){
			this.render(this.renderTo);
			delete this.renderTo;
		}
		
		this.mixins.floating.constructor.call(this);	//executing manually the
		this.mixins.observable.constructor.call(this); //constructors of the mixins
	}
});

To access the instances of the mixins we must use the property “this.mixins” followed by the name we assigned when we configured it.

This same concept is applied when there are methods with the same name in different classes that are inherited.

Rendering the Icon class

In the previous code the method “render” was executed if the property “renderTo” has been defined in the configuration parameters, it is our duty to implement this method.

render		: function(where){
	if(where){
		this.container = Ext.get(where);			// 1
		this.el = Ext.core.DomHelper.append(where,{	// 2
			id	: this.id,
			tag	: "div"
		});
		this.el = Ext.get(this.el);
		this.el.setStyle({					// 3
			width	: this.width?this.width+"px":"auto",
			height	: this.height?this.height+"px":"auto",
			border	: this.border?"1px solid #aaa":"none",
			background	: "#eee"
		});
	}
},
	
setPagePosition	: function(xy){		// 4
	this.el.setLeftTop(xy[0]+"px",xy[1]+"px");
	this.fireEvent("moved",xy);
}

In step 1, the reference of the container element is taken using the “Ext.get” method which returns an instance of the object “Ext.Element” which contains the reference to the DOM and also several methods to manipulate it in a simple manner.

In step 2 the element that will represent the class “Icon” is created, using the class “Ext.DomHelper” we can create DOM ​​elements in a very simple way, in this case we used the method “append” to add a node to the container .

In step 3 we apply the styles such as width, height, etc… These styles can be sent using the configuration object to change the default values.

In step 4 we define a function to assign the position of the element that represents the class “Icon”, this method is required to use the method “center” that we inherited from the class “Floating”.

Instantiating the class Icon

We have created a class that uses mixins, now we are going to test it by using an instance of it and executing some of the inherited methods.

Ext.onReady(function(){
	var icon = Ext.create("Bleext.training.Icon",{
		renderTo	: Ext.getBody()
	});

	icon.on("moved",function(xy){	//inherited from Observable
		console.log(xy);
	});
	
	icon.center();			//inherited from Floating
});

When you execute the example you will see a square in the center of the screen, we didn’t programmed the functionality of centering the square because we inherited that functionality from the class “Floating” which is responsible for calculating the center.

We also used the method “on” that has been inherited from class “Observable” and it’s used to add events to classes.

Difference between a mixin and plugin

Through mixins we can add properties and methods to a class, but if you think about it plugins do the same thing right? Yes, they do something very similar, they add extra functionality to a class.

The main difference is that a mixin is added at the class level and a plugin is added at the instance level, this means that the mixins are part of the definition of the class, while the plugins are not.

Conclusion

The mixins are useful to mix or add functionality from other classes to the class that we are defining, it help us to design a more robust and flexible application.

Comments


One Response to Multiple inheritance in Ext 4 (mixins)

  1. Hi Crysfel,
    I applied this example and I got this error:

    ext-all-dev.js:48152
    Uncaught TypeError: Object [object Object] has no method ‘up’

    Ext.define.registerWithOwnerCt
    Ext.define.constructor
    Ext.define.constructor
    constructor
    (anonymous function)
    Ext.ClassManager.instantiate
    (anonymous function)
    (anonymous function)
    isEvent
    fire
    Ext.apply.ready
    Event.event.fire
    (anonymous function)

Leave a Reply

Your email address will not be published. Required fields are marked *