Home >Web Front-end >JS Tutorial >Extjs Study Notes 8: Inheritance and Event Basics_extjs

Extjs Study Notes 8: Inheritance and Event Basics_extjs

WBOY
WBOYOriginal
2016-05-16 18:36:491008browse

The meaning of the interface here is that Observable actually acts as an abstract class. A large number of components in Extjs inherit from this class. This class provides some basic methods such as addEvents, addlistener, fireEvent, etc.

This article does not introduce how to use extjs components to respond to events, but introduces some implementation principles of Extjs events. The entire Extjs framework is developed in an object-oriented manner, so it is also important to understand inheritance in Javascript. My previous article was also a preparation for this article. In addition, there is a well-written series in the blog park Detailed explanation of JavaScript inheritance. He is mainly based on two articles by Douglas Crockford. In fact, the principles for implementing inheritance are similar, so you can read them for reference. The function inherited by Extjs is a very core function Ext.extend. The extend method has two refactored versions. The first one accepts two parameters, and the first one is extend(Function superclass, Object overrides) , the second one is extend(Function subclass, Function superclass,Object overrides): Function, the second version is based on subclass. Superclass is the constructor of the superclass, overrides is an object, and the attributes inside are to override the attributes of the parent class. A subclass that inherits a parent class has all the methods in the prototype of the parent class. And subclasses can override the methods of the parent class (override). Furthermore, each object of the subclass can also override the methods of the parent class. In fact, I think this function has no effect. The effect of modifying the prototype is equivalent. Of course, the purpose of extjs is to completely shield the magical thing of prototype, so that programmers can process Javascript like other languages. Of course, even so, its inheritance is still somewhat different from ordinary inheritance. Let’s take a look at an example first. Prepare a Person class


Person = function(name) {
this.name = name;
this.fn = function() { alert('I am a person ') };
}
Person.prototype.print=function(){ alert('I am a person');}
Person.prototype.showAge = function() { alert('I am older than 0'); }
Person.prototype.showName = function() { alert('Show Name:' this.name) };
var per = new Person('Tom');
per.showName(); Subclass: Student = function(id) {
this.id = id;
}
Student.prototype.showID = function() { alert(this.id); } //Methods of subclasses


Inherited:
Ext.extend(Student, Person);
stu.showName(); !!No result! stu has no definition of name stu.fn(); !!No result stu.showID(); !!!Still no result At this point we have discovered some differences: the content in the constructor of the parent class will not be inherited. , the constructor of the parent class will not be called, and the existing methods of the subclass (in prototype) will also be lost! Continue reading and replace the code below Ext.extend with:


var stu = new Student('01');
Student.override({ print: function() { alert('I am a student'); } });
stu.override({ print : function() { alert('I am a bad student,but I won't affect others'); } });
stu.print();
stu.showAge();
var stu2 = new Student();
stu2.print();


The functions here can all be output as expected. showAge is the executed method of the parent class, and stu.print is the executed stu The method specified in .override, while stu2 executes the method specified in Student.override. At this point, we can roughly guess how extend is implemented. Let’s look at its real source code below. This method is located in Ext.js. The code and comments are as follows: extend : function(){


Copy code The code is as follows:

// inline overrides
var io = function(o){ //Pay attention to this method. You don’t know what this is just by looking at it. The following io will be assigned to sbp.override , that is, the prototype of the subclass
for(var m in o){ //The override of each subclass object will point to this method. If the subclass object calls override, then this is the object of the subclass. . That is,
this[m] = o[m]; //The effect shown by stu.override in the above example is only valid for the current object. It can be seen from here that override is not only an override in the traditional sense, it can also be used
} // to add new methods.
};
var oc = Object.prototype.constructor;

return function(sb, sp, overrides){
if(Ext.isObject(sp)){ // is in Detect which version of the refactoring function is currently in use. If sp actually overrides, do some substitutions so that the actual meaning of the variable matches its name.
overrides = sp;
sp = sb;
sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);}; //Didn’t read this Got it...
}
var F = function(){},
sbp,
spp = sp.prototype;

F.prototype = spp; //F is the parent A "clean" copy of a class. Clean means that it does not bring over the properties defined inside the constructor of the parent class. //For example Person=function() // {this.privateFn=new function{ some code goes here}} //Then this privateFn is invisible to subclasses, so the attributes defined using this in the constructor are equivalent to Private variables of the class.
sbp = sb.prototype = new F(); //Set the prototype of the subclass to the prototype of the parent class, the core step of inheritance. sbp.constructor=sb; //Set the correct constructor pointer, see JavaScript inheritance details
sb.superclass=spp; //Set the parent class
if(spp.constructor == oc){ //Didn’t read it Got it..., what is this for? Please give me some advice
spp.constructor=sp;
}
sb.override = function(o){ //The rewriting method of the subclass, this rewriting method is the rewriting method of the function. It modifies the prototype.
Ext.override(sb, o); //See the end.
};
sbp.superclass = sbp.supr = (function(){ //Set the parent class of the prototype
return spp;
});
sbp.override = io; / / Provide an override method to the prototype of the subclass, so that a single entity can be overridden, and it modifies the entity object. Note the difference from the override of sb above.
Ext.override(sb, overrides); //Rewrite
sb.extend = function(o){return Ext.extend(sb, o);}; //Provide the extend method to subclasses to Implement multiple inheritance
return sb; //Return subclasses.
};
}();

The following is the code of Ext.override, which is relatively clear. Compared with the inline override, it is the modified prototype:override:
Copy code The code is as follows:

function(origclass, overrides){
if(overrides) {
var p = origclass.prototype;
Ext.apply(p, overrides);
if(Ext.isIE && overrides.hasOwnProperty('toString')){ // What is this? What's special about IE?
p.toString = overrides.toString;
}
}
}

Now you can start to formally introduce the event model of Extjs. Similar to events in other languages, you must first define an event for a class. Events in other languages ​​(such as C#) generally have a special event type. The event type can actually be regarded as an array of delegates. Of course, the delegate is actually a function. Add The time listener (listener) just wants to add a delegate (function) to the delegate array. The so-called trigger event is to execute all the functions in the array. Javascript is similar, except that Javascript's functions are much more powerful and flexible than those languages, so there is no need for an event type. Javascript events look like a string (it should also retain an array internally). You can add events through the Observale.addEvents method, trigger events through Observale.fireEvent, and add event listeners through Observale.addListner. Here is an example that makes little sense but illustrates the problem.
Copy code The code is as follows:

Odder = function(min, max) {
this.min = min;
this.max = max;
this.addEvents('onFindOdd');
}
Ext.extend(Odder, Ext.util.Observable, { run:
function() {
for (var i = this.min; i < this.max; i ) {
if (i % 2 != 0) {
this.fireEvent('onFindOdd ',i);
}
}
}
});
var p = new Odder(4, 8);
p.addListener('onFindOdd',function( n){alert(n);});
p.run();

Odder is a class that passes in a range through a constructor, then searches for all odd numbers in the range, and triggers an event every time it finds one. I add an event handler to it to alert the odd numbers it finds. It should be noted that the parameters of the event handler here can only be kept consistent by the programmer. It is not as strongly typed as a delegate.

Note that I did not use the example on the official website:
Copy the code The code is as follows:

Employee = Ext.extend(Ext.util.Observable, {
constructor: function(config){
this.name = config.name;
this.addEvents({
" fired" : true,
"quit" : true
});

// Copy configured listeners into *this* object so that the base class's
// constructor will add them.
this.listeners = config.listeners;

// Call our superclass constructor to complete construction process.
Employee.superclass.constructor.call(config)
}
}) ;This could then be used like this:
var newEmployee = new Employee({
name: employeeName,
listeners: {
quit: function() {
// By default, " this" will be the object that fired the event.
alert(this.name " has quit!");
}
}
});

i I think there is an article in the example on the official website. Its overloaded item contains the constructor attribute, which gives the impression that the constructor of the parent class is overloaded, and then the subclass will call this constructor to create it. In fact, it is not Yes, it changes the behavior of Javascript itself. This is related to the few lines of code I marked above that I did not understand. More discussion next time.
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn