📜 ⬆️ ⬇️

New look at old MS Ajax

Just over a year ago, I saw one site. At first glance, it was no different from hundreds of similar sites, but my colleague noticed a multiple update of small modules when clicking on functional elements. A further discovery was that it works without overload. To date, each of us will not cause much impression, but this site has been operating for more than 5 years.
After a two-day analysis of the site, we found the answer to the question - “How does it work? ". The center of this site was a file called msajax.js, which prompted us to search the Internet. Information was little, but enough to start experiments.

This library provides a set of classes for creating small elements, from which you can then assemble a full-fledged website.
To connect it, it is enough to add to the ScriptManager page and register a ScriptReference for all of our files.
Let's start creating a small element.

Type.registerNamespace('MyNamespace'); // ctor MyNamespace.Widget = function (element, someData) { var t = this; t.template = "<span><label></label></span>"; if (!element) { element = $(t.template); } MyNamespace.Widget.initializeBase(t, [element]); }; //methods MyNamespace.Widget.prototype = { initialize: function () { var t = this; MyNamespace.Widget.callBaseMethod(t, 'initialize'); }, dispose: function () { var t = this; MyNamespace.Widget.callBaseMethod(t, 'dispose'); }, someMethod: function(){ var t = this; } }; MyNamespace.Widget.registerClass('MyNamespace.Widget', Sys.UI.Control); 

')
Our element consists of a constructor and a set of methods. The constructor is called when trying to create an instance of an element and always takes the first parameter as element , which is the DOM element in which it will be displayed. Further initialization of base class is caused. In this case, it is Sys.UI.Control , which we specified when calling registerClass . This method can accept the third parameter of the interface, but more on that next time, if someone is interested in this post.
There are always two methods in the set of methods: initialize and dispose by name are clear what they do and I see no point in describing them, I can say that I usually create event handlers in initialize and fill in the elements I need, and in dispose I describe the logic of removing an element from DOM and unsubscribe from various events. We can also describe our various methods that will be available through the created instance. You can pass an element using the $ get method, which takes the name of the id attribute of the html element.

  Global.widget = new MyNamespace.Widget($get("ID")); Global.widget.initialize(); 


The biggest advantage I consider is the get_element () method of the Sys.UI.Control class , it allows us to work with our element as a separate entity:

  initialize: function () { var t = this; ... $("label",t.get_element()).html("Hello world!"); } 


We work not with the whole DOM , but with a small part of it, which only positively affects the speed of the site.
This library has another great Sys.EventHandlerList class that can be used as a repository for callback functions.

 BaseControl = function (element) { var t = this; BaseControl.initializeBase(t, [element]); t.handlers = new Sys.EventHandlerList(); }; BaseControl.prototype = { initialize: function () { var t = this; BaseControl.callBaseMethod(t, "initialize"); }, dispose: function () { var t = this; t.handlers = null; BaseControl.callBaseMethod(t, "dispose"); }, addEventHandler: function (name, h) { var t = this; t.handlers.addHandler(name, h); }, removeEventHandler: function (name, h) { var t = this; if (t.handlers) { t.handlers.removeHandler(name, h); } }, raiseEventHandler: function (name, args) { var t = this; var h = t.handlers.getHandler(name); if (h) h(args); } }; BaseControl.registerClass("BaseControl", Sys.UI.Control); 


Inheriting from this class, we allow our element to inform all subscribers about a change in its state. Subscribers calling the addEventHandler method subscribe to the event of interest to them, passing its name. There are some difficulties, you can not just pass a reference to the method, you must create a delegate using Function.createDelegate and pass it. If we do not do this, all the elements of this class will receive a message about the change in the state of the object, and we do not pursue such a goal. And finally, these delegates need to be deleted, or you will observe strange behavior of elements on your website.

Using this library, my team implemented a site with very rich functionality, and we got very decent results.

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


All Articles