Implementation of Qomolangma (iv): Basic Feature Enhancement and multi-vote Event System

Source: Internet
Author: User

========================================================== ==========================================================
Qomolangma openproject V1.0

Category: rich Web Client
Key words: JS Oop, JS framwork, rich Web Client, Ria, Web component,
Dom, dthml, CSS, JavaScript, JScript

Project Initiation: aimingoo (aim@263.net)
Project Team: aimingoo, Leon (pfzhou@gmail.com)
Contributor: Jingyu (zjy@cnpack.org)
========================================================== ==========================================================

I. Enhancement of basic JS features by Qomolangma
~~~~~~~~~~~~~~~~~~

To implement richer OOP features, qomo enhances some basic features of JavaScript. This is mainly manifested in:
-Enhancements to basic JS type systems (methods)
-Support for multi-vote events

In this regard, the enhancement of basic types of systems will strictly abide by one principle:The object () object prototype is not modified.

In addition to common enhancements such as array. indexof (), array. Remove (), and string. Trim (), qomo has
Several features are inconsistent with other possible features. These items are described in the following topic:
-Array. Prototype. insert
-String. Prototype. Format
-Function. Prototype. tostring

In addition, qomo will provide the same visual editing features as ALTAS Based on vs.net in the future.
This feature extension references or copies the ALTAS code. However, these codes are currently only available in jsenhance. js.
Is not enabled. You can ignore them.

In the Mozilla Browser environment, a uneval () function is provided, which is used to serialize scripts.
Objects are of great value in future development. But it is stored in compat/common_ie6.js. Here we only mention
And it, without analyzing its implementation.

Ii. Enhanced features in jsenhance. js
~~~~~~~~~~~~~~~~~~

First, remember that the main feature of jsenhance. JS is "It can be used out of qomo framework ". This
The unit does not depend on any features of qomo. It uses natural and original Javascript methods to expand JS features.
Therefore, it can be used in any framework.

Array. Prototype. insert
----------
Qomo provides more powerful capabilities for array. insert (), allowing it to insert arrays
Element. This is different from some other frameworks: they generally only provide the ability to insert a single element.

String. Prototype. Format
----------
The string. Format () in qomo is implemented by referring to Delphi. Therefore, you will get the matching characters "% s" and "% N ".
Here, "s (case sensitive)" is used to indicate a replaced element, while "N (0 .. n)" is used to indicate the nth replaced element.

Because there is no explicit type in JS, there is no matching character such as "% d.

As a habit, I provide a global function: Format ().

For how to use string. Format (), see documents/testcase/t_stringformat.html.

Function. Prototype. tostring
----------
In JavaScript, anonymous function (immediate value) Declaration, function object construction, and function standard syntax Declaration are all
A valid function can be declared. However, the tostring () of these functions is inconsistent. In order to solve the function name
And make the following syntax have a definite meaning:
Function func (){/*...*/};
Foo = eval (func. tostring ());
Qomo re-writes function. tostring (). So that it always returns a string of an anonymous function. For example ):
Function (){/*...*/};

Iii. Multi-vote Event System in jsenhance. js
~~~~~~~~~~~~~~~~~~

First, the most important thing is that qomo's multi-vote Event System is "completely transparent" to any framework! Because
It can be embedded in any other framework like a normal event function (Response handle.
In fact, qomo's multi-vote event and qomo OOP framework are completely removed without any OOP features and framework features.
. -- This design concept fully embodies the objective and purpose of qomo and our awareness of OOP.

The following code demonstrates the features of the Multi-vote Event System in qomo:
----------
E = new muevent ();

Document. writeln (typeof E, '<br> ');
For (I in E)
Document. writeln ('-', I, '<br> ');
----------

Output result:
----------
Function
-Add
-Addmethod
-Clear
-Reset
-Close
----------

This indicates that "Multi-cast event object is actually a function", which provides five methods, such as "add ".

Because the "Multi-cast event object is a function", the following code is true:
----------
Func1 = func2 = function (){/*...*/};

Function myobject (){
This. onexec = new muevent ();

This. Run = function (){
// Do somethings
This. onexec ();
}
}

VaR OBJ = new myobject ();
OBJ. onexec. Add (func1 );
OBJ. onexec. addmethod (window, func2 );
OBJ. Run ();
----------

This example uses the simplest code to demonstrate the use of multi-cast event objects. As you can see, we still need to get through
In some way to make onexec () be executed. However, when it is executed, both func1 and
Func2.

1. Add (), addmethod ()
----------
In the method of multi-cast event objects, addmethod () is the first thing that is hard to understand. But we need
You need to know: using Add () to add the func1, The this object obtained during the execution period will be OBJ itself;
If you use addmethod () to add func2, The this object obtained during the execution period will be a window object.

What is the significance of this?

For example, a function such as setTimeout () can only pass in functions during execution, but cannot pass in object methods.
This allows the code to regularly execute an object method to be written as follows:
----------
Function dotimer (){
Obj1.call ();
Obj2.call ();
}
SetTimeout (dotimer, 1000 );
----------

When muevent () is used, the above Code can be very simple:
----------
VaR E = new muevent ();
E. addmethod (obj1, obj1.call );
E. addmethod (obj2, obj2.call );

SetTimeout (E, 1000 );
----------

Addmethod () is called addaction () in Atlas (). The two have the same meaning. Mature
The advertising event system usually provides this feature.

2. Clear () and reset ()
----------
Qomo provides the clear () method to clear the "event handle list" bound to the multi-cast event object ". While
Reset () adds an "event handle" after it is cleared ". Because the muevent object is also a function
The following code can also add an event delivery list:
----------
VaR e1 = new muevent ();
VaR e2 = new muevent ();

//...
// Add somethings to E1

E2.add (func1 );
E2.add (func2 );
E2.add (func3 );

// Clear E1, and add a list (E2)
E1.reset (E2 );
----------

3. Close ()
----------
Qomo provides a special mechanism to disable the multi-vote feature. -- Note that this is in other frameworks
Are not implemented.

The multi-cast event object of qomo is a common function, except that it has the addition of add (), addmethod (), and so on.
Method. If we delete these methods, the external representation of the object is exactly the same as that of a common function.
No exception. In this case, a third-party framework cannot identify this "Multi-vote feature is disabled ".
Cast event object ', and treat it as a common function.

Therefore, qomo's multi-vote feature can be fully and transparently embedded into a third-party framework. Even browsing like dom
Basic System. For example:
----------
VaR loading = new muevent ();

Loading. Add (loadpicture1 );
Loading. Add (loadpicture2 );
Loading. Add (loadpicture3 );
//...
Loading. Add (loadpicture1000 );

Loading. Close ();
Window. onload = loading;
----------
In this case, the browser's Dom framework does not feel any difference in loading (as a function.

The close () feature provided by qomo is far from effective. In fact, the true value of the close () feature lies in
System design considerations. For example, we create a tlablededit object, that is
Bound together. So we find that our understanding of lable. onclick behavior is definitely
Is "select edit and set the input focus ". This behavioral feature was identified at the beginning of design and should not
Changed. -- Of course, if your design is to be changed, let's talk about it.

In the original tlable design, tlable. onclick is a public method and a multi-vote event.
Even if we write the following code:
----------
Flabled. onclick. addmethod (fedit, fedit. onclick );
----------
In the subsequent and user code, the flabled. onclick behavior can still be changed. For example, add/clear ().

This is obviously not desired by the original designer of the tlablededit component. Therefore, when close () is provided ()
In this case, it can be written in the above Code as follows:
----------
// Call after creation
This. docreate = function (){
Flabled. onclick. addmethod (fedit, fedit. onclick );
Flabled. onclick. Close ();
}
----------
This ensures that the onclick () feature is not changed. In addition, if fedit. onclick is a variable (for example
Such as Add/reset), flabled. onclick can be perceived normally.

 4. Why not del () is provided ()
----------
The Del () feature is not provided for qomo multi-vote events. For two reasons:
-Del () may cause the event activation sequence to be damaged.
-Del () requires reference of the event Method in the internal "event handle list", which destroys encapsulation.

Therefore, qomo does not provide del () as a framework design consideration (in the current version (). However
Yes. Because the del () method is used in the Multi-cast event of Atlas, qomo will implement code embedded into vs.net in the future.
The Del () method may be provided.

IV. Implementation Analysis of the Multi-vote Event System
~~~~~~~~~~~~~~~~~~

1. Basic multi-vote Event System
----------
The most basic implementation method of the Multi-vote event system is as follows:
----------
Function muevent (){
// This is a new OBJ instance
VaR all = this;
All. Length = 0;

Function add (FOO ){/*...*/}
Function addmethod (OBJ, foo ){/*...*/}
Function clear (){/*...*/}
Function reset (FOO ){/*...*/}
Function run (){/*...*/}

VaR E = function () {return run. Call (this, arguments )}
E. Add = add;
E. addmethod = addmethod;
E. Clear = clear;
E. Reset = reset;

Return E;
}
----------

This implementation looks simple and natural. And the object instance constructed by the new () keyword this has been
The internal variable all has a reference to create an event list. This avoids unnecessary overhead. Looks like
Yes. -- Naturally, the implementation of the close () method is also very easy.

However, when comparing multiple event objects, we will find an unacceptable fact:
----------
VaR e1 = new muevent ();
VaR e2 = new muevent ();

Alert (e1.add === e2.add)
----------
You will find that the result is false, that is, how many event objects will be added, clear
Method. The overhead is extremely huge: N * 5.

2. Implementation basis of qomo multi-vote Event System
----------
In qomo, this is all cleverly avoided. I created a handle for each event object. It
Is an index.
----------
Function _ muevent (){
// Get a handle and init muevent object
VaR handle = all. Length ++;

//...
----------
In order to make the add () method a "unique instance", I put it out of _ muevent () for implementation. However
In this case, the handle of the object is invisible to the add () method. Therefore, we need
To expose handle to methods such as add. Here, valueof () is used ().

For the function (Multi-cast event object) Me, its valueof () result points to itself: me. In most
This is meaningless. So we can implement valueof () as follows ():
----------
Me. valueof = function (){
Return handle
};
----------

In add (), valueof () is used as follows ():
----------
VaR all2 = []; // All me () object for recheck.

Function add (FOO ){
VaR I = This. valueof (), E = All [I];
If (E & E = all2 [I]) {
// Add...
}
}
----------

Because we use the second array all2 for review, we can avoid using such code to set
List of multiple-vote events that are retrieved or destroyed:
----------
// If E1's handle is 10, and hide into a object/System
VaR e1 = new muevent ();

// Set the Function
F = function (){};

// Specify the desired handle
F. valueof = function () {return 10}

// Reset (note that the methods of all the multi-cast event objects are the same)
F. Clear = (New muevent (). Clear;

// Crack the E1 event list (returns 10 features using valueof)
F. Clear ();
----------

Therefore, it is necessary to add the array all2 [] for review.

 3. "strong" and "fast" are dilemmas
----------
However, we also find that the "Multi-vote Event System" is not "strong. Why? Because
Valueof () can still be rewritten by external code. -- This will result in dependency on it to get the add () of handle ()
And other methods are invalid. In fact, since we redefine the meaning of valueof (),
Third-party frameworks and systems may be incompatible.

Qomo should be a strong system. The existence of valueof () affects robustness and makes "Transparent"
It becomes an empty talk.

Let's go back to the previous all2 []. In fact, due to the necessity of review, we have stored a copy of all
. Therefore, it is possible not to use handle to find me and event list objects:
----------
Function add (FOO ){
VaR E = all. Search (this );
If (e ){
//...
}
}
----------
In this Code, we need to design an algorithm in all. Search (), which is used in all2 [].
Find this object (that is, the ME () function ). The returned result of search () is "using this object in all2 [].
"," Send event list "found in all ". -- This index is actually handle.

In this way, you do not need to override me (). valueof () to publish handle. However
All will search for all2 [], making the system relatively slow. -- To put it simply: It's strong, but it's slow.

The implementation code of the entire muevent is as follows:
----------
VaR muevent = function (FAST ){

VaR all = {
Length: 0,
Strong :! Fast, // ^. ^
//...
}

Return _ muevent;
} (True );
----------

Simply put, the above line of code actually reflects: Strong is not fast, fast is not strong.

4. Is it really unpleasant?
----------
A Brief Analysis of some of our features when using the event system, we will find that:
-In fact, we usually add an event in batches or a group of events of an object.
-In fact, related objects and events are always processed "in the near time ".

For example, we usually write such code During object initialization:
----------
OBJ. onclick. Add (foo1 );
OBJ. onclick. Add (foo2 );
OBJ. onmouseout. Add (foo3 );
----------

In the multi-cast Event System, the onxxxxx event of the same object is usually created consecutively and has just been completed.
The created event object may be assigned an initial value. In short, these usage habits are as follows:
-Recently created events may always be quickly operated.
-Events near the last operation event (with the same object) may always be quickly operated

Based on these two principles. Qomo designed a method to search for event objects in all2 []: always from the previous
Start forward and backward searches near the event object added or found. For specific algorithms, see all. Search ().

Adding search algorithms greatly speeds up adding and other actions. Of course, this is based on the developer's code line
For analysis, the efficiency of the true "retrieving objects in arrays" method cannot be improved. This is from JS
Unavoidable problems.

However, if hash is referenced or the object attribute name is used for detection, you must give the ME () object a "allowed
The access key/name value ". This is back to the same issue as the "Fast Method" provided by handle.
Therefore, it is unnecessary to discuss such a problem.

In jsenhance. js of qomo, the "Fast = false" configuration is used by default to provide a strong system. However
If you are sure that your system is closed and will not affect third-party frameworks, you can
Turn on the following switch:
----------
VaR muevent = function (FAST ){
//...

Return _ muevent;
} (False); // <-- here, set to true
----------

Finally, the most important note is that qomo's efficiency sacrifice in this multi-vote event system only shows
. It does not affect the execution of the ME () event. Because in the Code:
----------
Function _ muevent (){
// Get a handle and init muevent object
VaR handle = all. Last = all. Length ++;

VaR me = function (){
If (ALL [handle]. length> 0) // <--- directly use handle
Return run. Call (this, handle, arguments)
}

//...
}
----------
Since the ME () execution can directly use the internal handle variable, it will not call all. Search () at all (). Therefore
Qomo only has some performance overhead for search () when "Add/RESET" is used. "Execution
When sending events, the performance is optimized.

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.