Create an extjs (1) system manually

Source: Internet
Author: User

I recently read several javascrpt books (JavaScript advanced programming and JavaScript design patterns). I have mentioned many object-oriented development and many excellent JavaScript frameworks,
I can hardly understand why I have never mentioned extjs. is Yui so big as extjs ?.

I especially like the class system of extjs4, so I wrote one by myself. I just learned a little about extjs and didn't go deep into it, in some cases, we may not want to point it out.

In my class system, you can declare interfaces, abstract classes, and classes. The declaration method is similar to extjs.

The following is the class declaration of extjs.
Ext. Define ('ext. Panel. Panel ',{
Extend: 'ext. Panel. abstractpanel'
//.....
})

The following code is used: classmanager. js

VaR design = design | |{}; (function (class) {/* First defines some tool Methods */var widgetmap = {}; vaR util = {/* Copy object attributes if they do not exist */applyif: function (C1, C2) {If (typeof C1 = "object" & typeof C2 = "object") {for (var key in C2) {If (! C1 [Key]) {c1 [Key] = c2 [Key] ;}},/* copying object attributes */apply: function (C1, C2) {If (typeof C1 = "object" & typeof C2 = "object") {for (var key in C2) {c1 [Key] = c2 [Key] ;}} return C1 ;}, isobject: function (o) {return (typeof o = "object") ;}, isarray: function (o) {return (O instanceof array) ;}, isfunction: function (o) {return (typeof o = "function") ;}, isstring: function (o) {return (typeof o = "string") ;}, isnumber: Function (o) {return (typeof o = "Number") ;},/* obtain a Class Based on the string type */getclass: function (name) {If (typeof name! = "String") return namevar v = Name. split ('. '), O = Window [V [0], I = 1, Len = v. length; For (; I <Len; I ++) {If (! O) return oo = O [V [I];} return o ;},/* define the namespace */namespace: function (name) {If (typeof name! = "String") return namevar v = Name. split ('. '), O = Window [V [0] = Window [V [0] | |{}, I = 1, Len = v. length; For (; I <Len; I ++) {o = O [V [I] = O [V [I] | {};} return O;}, NS: function () {return this. namespace. apply (this, arguments) ;}}/* interface class the following interface class is a copy of the example in the design pattern book */var interface = function (name, methods) {var I = 0, Len = methods. length; this. name = Name; this. methods = []; for (; I <Len; I ++) {This. metho DS. push (methods [I]);}/* check whether the interface method is implemented */interface. ensureimplements = function (object) {var I = 1, Len = arguments. length, j = 0, menthodslen; For (; I <Len; I ++) {for (methodslen = arguments [I]. methods. length; j <methodslen; j ++) {VaR method = arguments [I]. methods [J]; If (! Object [Method] | typeof object [Method]! = 'Function') {Throw new error ("class" + object. classname + "not implemented" + arguments [I]. name + "interface method" + method) ;}}}/* class inheritance */function extend (subclass, superclass) {var F = function () {}; F. prototype = superclass. prototype; subclass. prototype = new F (); util. applyif (subclass. prototype, new F () subclass. prototype. constructor = subclass; If (superclass. prototype. constructor = object. prototype. constructor) {superclas S. prototype. constructor = superclass;}/* adds a static attribute for the subclass. superclass points to the parent class */subclass. superclass = superclass. prototype;/* Add a method for the subclass callparent to call the current function of the parent class */subclass. prototype. callparent = function (CFG) {VaR method, methodname; method = This. callparent. caller; For (var key in this) {If (this [Key] = method) {methodname = key} superclass. prototype [methodname]. apply (this, CFG)}/* Add the alias to the widgetmap object */function setwi DGET (name, CLS) {var n = Name; If (name. indexof ('widget. ')>-1) {n = Name. substring (7, name. length);} widgetmap [N] = CLS;} var pub = {/* use a string format name to create a class */create: function (name, CFG) {var clazz = util. getclass (name); return New clazz (CFG) ;},/* use an alias to create a class */Widget: function (name, CFG) {var clazz = widgetmap [name]; return new clazz (CFG) ;},/* declare a class */define: function (name, CFG) {/* Get the variable of the current string name */var namearr = ('win Dow. '+ name ). split ('. '), lastname = namearr. pop (), beginname = namearr. join ('. '), thatclass = util. NS (beginname), parentclass = util. NS (CFG. extend), implement = cfg. implement;/* Create an interface when the current type is interface and return */If (CFG. classtype = "interface") {thatclass [lastname] = new interface (name, CFG. methods); return;}/* Create object cfg. constructor is the constructor */If (CFG. constructor! = Object) {thatclass = thatclass [lastname] = cfg. constructor; Delete cfg. constructor;} else {thatclass = thatclass [lastname] = function () {If (parentclass) {parentclass. prototype. constructor. apply (this, arguments) }};}/* inherit from the parent class configured in CFG */If (parentclass) {If (parentclass. prototype. events & cfg. events) {util. applyif (CFG. events, parentclass. prototype. events);} extend (thatclass, parentclass);} util. apply (thatc Lass. prototype, CFG); thatclass. prototype. classname = Name;/* when the interface is configured, check whether there are any implemented methods. If there are unimplemented methods, an exception will be thrown */If (implement) {If (! Util. isarray (implement) {implement = [implement]} var I = 0, Len = implement. length; For (; I <Len; I ++) {If (typeof implement [I] = 'string') {interface. ensureimplements (thatclass. prototype, util. NS (implement [I]);} else if (typeof implement [I] = 'object') {interface. ensureimplements (thatclass. prototype, implement [I]);} else {Throw new error ("interface error implements type string and object"); }}/ * act as the parent When the class is an abstract class, check whether there is any implemented Method */If (parentclass & parentclass. classtype = "abstract") {for (VAR I = 0, Len = parentclass. methods. length; I <Len; I ++) {VaR method = parentclass. methods [I]; If (! CFG [Method] | typeof CFG [Method]! = 'Function') {Throw new error (name + "not implemented" + method + "method, abstract class" + parentclass. classname) ;}}/ * when the current class is an abstract class, add several static attributes as the test class and use */If (CFG. classtype = "abstract") {thatclass. classtype = "abstract"; thatclass. methods = cfg. methods;}/* When the alias attribute is configured for the current class, call setwidget (name, class) to add the alias and current class to map */If (CFG. alias) {If (util. isarray (CFG. alias) {cfg. alias. foreach (function (IT) {If (util. isstring (IT) {setwidget (it, thatclass);} else {Throw new error ("define argument 'Alias' type error ");}});} else if (util. isstring (CFG. alias) {setwidget (CFG. alias, thatclass);} else {Throw new error ("define argument 'Alias' type error") ;}}} util. applyif (class, pub); util. applyif (class, util) ;}( design );

HTML page

<SCRIPT src = "classmanager. JS "> </SCRIPT> <SCRIPT> design. define ('Design. interface. component ', {classtype: 'interface', Methods: ['initcomponent', 'getitems']}); design. define ('Design. panel. abstractpanel ', {classtype: 'abstract', getelement: function () {return document. createelement ('div ');}, Methods: ['getvalue', 'setvalue']}); design. define ('Design. panel. panel ', {alias: 'panel',/* alias */extend: 'Design. panel. abstractpanel ',/* inherit the abstract class */implement: 'Design. interface. component ',/* inherited interface */constructor: function (CFG) {/* constructor */This. name = cfg. name;}, getname: function () {/* Class Method */return this. name;}, initcomponent: function () {/* required interface method without this method will throw an exception */}, getitems: function () {/* required interface method without this method will throw an exception */}, getvalue: function () {/* the required abstract method will throw an exception if this method is not used */}, setvalue: function () {/* an exception will be thrown if the required abstract method is not implemented */});/* create panel class */var Panel = new design. panel. panel ({Name: 'zwl '});/* create with string class name */Panel = design. create ('Design. panel. panel ', {Name: 'zwl'});/* create with alias */Panel = design. widget ('panel ', {Name: 'zwl'}); alert (panel. getname (); </SCRIPT>

Now this class system has completed the above is a test example. There is another problem. If you detach design. interface. component, design. Panel. abstractpanel design. Panel. Panel to the JS file,
We also need to import the following files on the page.
<SCRIPT src = "app/interface/component. js"> </SCRIPT>
<SCRIPT src = "app/panel/abstractpanel. js"> </SCRIPT>
<SCRIPT src = "app/panel. js"> </SCRIPT>

If the number of classes increases, many JS files will be imported. In this case, my class system is too weak. Next I will add a function to dynamically import JS files.

The following code creates a JS file named Loader:

(Function (class) {/* file path and conversion name */var Path = {Name: 'design', replacename: ''};/**/var requirecount = 0; vaR addevent = function (El, type, FN) {If (window. addeventlistener) {el. addeventlistener (type, FN, false);} else if (window. attachevent) {el. attachevent ('on' + type, FN) ;}} class. onready = function (callback) {addevent (window, 'load', function () {/* check whether the class file is still being loaded. Call the callback after loading. */var intervalid = setinte Rval (function () {If (requirecount = 0) {clearinterval (intervalid); callback () ;}, 5 )});}; /* import Class Method */var require = function (URLs, onload) {If (! Class. isarray (URLs) {URLs = [URLs];} var URL, Count = 0, I = 0, Len = URLs. length; For (; I <Len; I ++) {(function (I) {count ++; url = URLs [I]; requirecount ++; If (URL. indexof (path. name) = 0) {url = path. replacename + URL. substring (path. name. length, URL. length);} var script = document. createelement ('script'); script. type = 'text/JavaScript '; script. src = URL. replace (/\. /g, '/') + '. js'; script. onload = function () {count --;/* checks whether the class in this file has been declared at intervals. If the object exists, call the callback */var intervalid = setinterval (function () {If (class. getclass (URLs [I]) {requirecount --; clearinterval (intervalid); If (COUNT = 0 & onload) {onload. call (window) ;}}}, 5)}; script. onerror = function () {Throw new error ("require errors url =" + URL) ;}; script. onreadystatechange = function () {If (this. readystate = 'loaded' | this. readystate = 'complete') {}}; document. getelementsbytagname ('head') [0]. appendchild (SCRIPT) ;}) (I) }}; var pub ={/ * set path */setpath: function (O, N) {path. name = O; Path. replacename = n ;}} class. loader = pub; Class. require = require;}) (Design );

Finally, add a piece of code at the beginning of the define method.

VaR pub = {define: function (name, CFG) {/* If the parent class and interface do not exist, the declared class will be blocked from loading the parent class and interface before declaring the class */var requirelist = []; If (CFG. extend &&! Util. getclass (CFG. Extend) {requirelist. Push (CFG. Extend);} If (CFG. Implement &&! Util. getclass (CFG. implement) {requirelist = requirelist. concat (CFG. implement);} var loadercount = requirelist. length; For (VAR I = 0, Len = requirelist. length; I <Len; I ++) {class. require (requirelist [I], function () {loadercount --; If (loadercount = 0) {pub. define (name, CFG) ;}}) ;}if (requirelist. length) {return ;}//........}}

HTML page

<SCRIPT src = "classmanager. JS "> </SCRIPT> <SCRIPT src =" loader. JS "> </SCRIPT> <SCRIPT> design. loader. setpath ('Design ', 'apps'); // configure the path design. panel. the Panel is converted to apps/panel. JS file path design. require (['Design. panel. panel ']); // three JS files will be loaded before onready. onready (function () {/* create with alias */Panel = design. widget ('panel ', {Name: 'zwl'}); alert (panel. getname () ;}); </SCRIPT>

Csdn cannot upload the link below the attachment download code

Http://junjun16818.iteye.com/admin/blogs/1733447

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.