📜 ⬆️ ⬇️

Template + jQuery + MVC = jsMVC

When developing websites I always wanted to make my life easier, so I became acquainted with jQuery. Everything would be fine if the projects were not immersed in a shifting mix of UI and js code. The next step was the fact that we selected the UI Templates into separate files, the code became more clean, but, damn it, you still had to write a bunch of UI code, such as inserting and setting additional components into the template, event bind, labels, etc. And only after all this, the output was the component we needed. There were, of course, a lot of problems, especially when the designer changed the pattern, but all this is solved.
I always wanted designers to paint the world, and programmers revived it. And it is desirable that these worlds practically do not overlap and give freedom to both. And so on to the point.
jsMVC consists of three things:


Component



- slide 3 -
The component consists of a Template + CSS, js "class" + declarative description.
js "class" is defined in the jsMVC.Components namespace. and looks something like this:
jsMVC.Components.Button = {
Init: function (){ //
jsMVC.Components.Component.Init.call( this ); // ...
//<>
},
SetEnable: function (flag){...}, // Enable
GetEnable: function () {...}
//< ...>
}


* This source code was highlighted with Source Code Highlighter .
jsMVC.Components.Button = {
Init: function (){ //
jsMVC.Components.Component.Init.call( this ); // ...
//<>
},
SetEnable: function (flag){...}, // Enable
GetEnable: function () {...}
//< ...>
}


* This source code was highlighted with Source Code Highlighter .
jsMVC.Components.Button = {
Init: function (){ //
jsMVC.Components.Component.Init.call( this ); // ...
//<>
},
SetEnable: function (flag){...}, // Enable
GetEnable: function () {...}
//< ...>
}


* This source code was highlighted with Source Code Highlighter .


It is desirable to begin methods with a capital letter, it will be clear below why

Further we declare properties and events:

- slide 5 -
jsMVC.CreateCompileInfoByObject(
{
Name: 'Button' ,
Properties: {
Enable: {
Type: 'Boolean' ,
Access: 'GETSET'
},
Text: {}
},
Events: {
onClick: {}
}
});


* This source code was highlighted with Source Code Highlighter .
jsMVC.CreateCompileInfoByObject(
{
Name: 'Button' ,
Properties: {
Enable: {
Type: 'Boolean' ,
Access: 'GETSET'
},
Text: {}
},
Events: {
onClick: {}
}
});


* This source code was highlighted with Source Code Highlighter .
jsMVC.CreateCompileInfoByObject(
{
Name: 'Button' ,
Properties: {
Enable: {
Type: 'Boolean' ,
Access: 'GETSET'
},
Text: {}
},
Events: {
onClick: {}
}
});


* This source code was highlighted with Source Code Highlighter .


The type and access of properties is optional.
Declaring is needed for compilation and editor.

Template


Templates consist of HTML tags, other components, event instructions, property settings.
For example Expander
jsMVC.Templates.Expander =
' < div > '+
' < div name ="content" /> '+
' < div class ="expander-control" > '+
' < component name ="bToggle" type ="Button" class ="cExpander-cButton-bToggle" > '+
' < properties > '+
' < key name ="Text" value ="*" ></ key > '+// Text
' </ properties > '+
' < events > '+
' < key name ="onClick" value ="Toggle" /> '+//
' </ events > '+
' </ component > '+
' </ div > '+
' </ div > ';


* This source code was highlighted with Source Code Highlighter .
jsMVC.Templates.Expander =
' < div > '+
' < div name ="content" /> '+
' < div class ="expander-control" > '+
' < component name ="bToggle" type ="Button" class ="cExpander-cButton-bToggle" > '+
' < properties > '+
' < key name ="Text" value ="*" ></ key > '+// Text
' </ properties > '+
' < events > '+
' < key name ="onClick" value ="Toggle" /> '+//
' </ events > '+
' </ component > '+
' </ div > '+
' </ div > ';


* This source code was highlighted with Source Code Highlighter .
jsMVC.Templates.Expander =
' < div > '+
' < div name ="content" /> '+
' < div class ="expander-control" > '+
' < component name ="bToggle" type ="Button" class ="cExpander-cButton-bToggle" > '+
' < properties > '+
' < key name ="Text" value ="*" ></ key > '+// Text
' </ properties > '+
' < events > '+
' < key name ="onClick" value ="Toggle" /> '+//
' </ events > '+
' </ component > '+
' </ div > '+
' </ div > ';


* This source code was highlighted with Source Code Highlighter .


You can do this
jsMVC.Templates.TestComponent = ' < div > '+
' < component type ="Expander" > '+
' < content > '+ // into="content", Expander "content"?
' < div > Test TEXT </ div > '+
' < component type ="Button" > '+
' < properties > '+
' < key name ="Text" > Click Me </ key > '+// Text
' </ properties > '+
' < events > '+
' < key name ="onClick" value ="Clear" /> '+//
' </ events > '+
' </ component > '+
' </ content > '+
' < content into ="bToggle" > '+//
' < div > Test 2 </ div > '+
' </ content > '+
' </ component > '+
' </ div > ';


* This source code was highlighted with Source Code Highlighter .
jsMVC.Templates.TestComponent = ' < div > '+
' < component type ="Expander" > '+
' < content > '+ // into="content", Expander "content"?
' < div > Test TEXT </ div > '+
' < component type ="Button" > '+
' < properties > '+
' < key name ="Text" > Click Me </ key > '+// Text
' </ properties > '+
' < events > '+
' < key name ="onClick" value ="Clear" /> '+//
' </ events > '+
' </ component > '+
' </ content > '+
' < content into ="bToggle" > '+//
' < div > Test 2 </ div > '+
' </ content > '+
' </ component > '+
' </ div > ';


* This source code was highlighted with Source Code Highlighter .
jsMVC.Templates.TestComponent = ' < div > '+
' < component type ="Expander" > '+
' < content > '+ // into="content", Expander "content"?
' < div > Test TEXT </ div > '+
' < component type ="Button" > '+
' < properties > '+
' < key name ="Text" > Click Me </ key > '+// Text
' </ properties > '+
' < events > '+
' < key name ="onClick" value ="Clear" /> '+//
' </ events > '+
' </ component > '+
' </ content > '+
' < content into ="bToggle" > '+//
' < div > Test 2 </ div > '+
' </ content > '+
' </ component > '+
' </ div > ';


* This source code was highlighted with Source Code Highlighter .


Compilation


When you first create an object, the Template is compiled and the “class” Js in the js function that creates the object. In this case, using the component declaration, the names of properties, events, etc. are checked.

- slide 7 -
By calling this function, on output we get a jQuery object, which contains:

')
Next, placing the object in the DOM page, you need to call the Init () method, by default this method will call the Init () method on all nested components.

Performance


So what about performance? For tests, a simple object was taken:
< div class =" menu>
< div class ="menu-background" />
< span name ="text" class ="menu-text" />
</ div >


* This source code was highlighted with Source Code Highlighter .
< div class =" menu>
< div class ="menu-background" />
< span name ="text" class ="menu-text" />
</ div >


* This source code was highlighted with Source Code Highlighter .
< div class =" menu>
< div class ="menu-background" />
< span name ="text" class ="menu-text" />
</ div >


* This source code was highlighted with Source Code Highlighter .


The essence of the test is to create 1000 - for objects, set the text "TEST" in the span.menu-text.
The test was conducted on FF3.0.3, AMD 64x2 4800+, 2.51GHz, 2Gb RAM, WinXP SP2


- slide 9 -
jsMVC, SetText () - got high performance, because the SetText method sets text via innerHTML.
DOM, innerHTML - create all elements via createElement, etc.,
jQuery + innerHtml - creating the main element and filling it through innerHTML, the result almost coincides with the full creation of the template via jQuery
Full statistics:
Time: 700 ms Name: " jQuery ", $ (Template), $ (TAG.class [@atr = "..."]), $ (). Text ()
Time: 591 ms Name: " jQuery ", $ (Template), $ (. Class), $ (). Text ()
Time: 441 ms Name: " jQuery ", $ (Template), $ (obj [0] .childNodes []), $ (). Text ()
Time: 463 ms Name: " jQuery ", $ () [0] .innerHtml, $ (obj [0] .childNodes []), $ (). Text ()
Time: 680 ms Name: " jQuery ", $ () [0] .innerHtml, $ (TAG.class [@atr = "..."]), $ (). Text ()
Time: 565 ms Name: " jQuery ", $ () [0] .innerHtml, $ (. Class), $ (). Text ()
Time: 383 ms Name: " jQuery ", $ () [0] .innerHtml, $ (. Class), obj [0] .innerHTML
Time: 471 ms Name: " jQuery ", $ () [0] .innerHtml, $ (# id), obj [0] .innerHTML
Time: 484 ms Name: " DOM ", createElement (), $ (TAG.class [@atr = "..."]), $ (). Text ()
Time: 391 ms Name: " DOM ", createElement (), $ (. Class), $ (). Text ()
Time: 297 ms Name: " DOM ", createElement () + innerHtml, $ (obj.childNodes []), $ (). Text ()
Time: 261 ms Name: " DOM ", createElement (), $ (DOMElement), $ (). Text ()
Time: 357 ms Name: " DOM ", createElement (), $ (DOMElement), $ (). Html ()
Time: 101 ms Name: " DOM ", createElement (), $ (DOMElement), innerHTML
Time: 113 ms Name: " DOM ", createElement (), $ (DOMElement), innerHTML, cache element
Time: 303 ms Name: " jsMVC ", $ (). Text ()
Time: 129 ms Name: " jsMVC ", SetText () - spec object method

Total




The project is distributed under the GPLv3
I will be glad to criticism, bugs, ideas and suggestions.
The current version is 1.0alpha, there are still flaws and bugs.

At the end of the week, the WYSIWYG component designer (80% ready) will be released, written entirely in jsMVC.

Sources

PS: I think there are a lot of similar ideas, I just want to offer one of the implementations.
PS.2: From ang. I have problems with the language, I would be very happy if somebody would help me to translate this note if it would interest people.

Source: https://habr.com/ru/post/43898/


All Articles