📜 ⬆️ ⬇️

10 reasons why your project should use the Dojo Toolkit

The Dojo Toolkit is both the most powerful and least used JavaScript framework. While almost every JavaScript framework or toolkit promises to do everything, and even more, the Dojo Toolkit provides the most convincing arguments to prove its functionality. This post will cover many of the important features of the Dojo Toolkit, and will also explain why you should use it in your next project.

1. Modularity and AMD bootloader


Client JavaScript code, like any code, tends to grow in size. Modularity is the key that makes our code easy to maintain and efficient. The days of using libraries using a one-time, non-asynchronous download, are in the past. The Dojo Toolkit is a prime example of a framework using modules. It uses dojo.require to dynamically pull only those resources that the page needs at the moment.

Initially, the resource loading method was synchronous, although there was also a cross-domain version with asynchronous loading capability. Dojo now uses an asynchronous loader, written by Rawld Gill, who masterfully loads all resources asynchronously and much faster than before. To download multiple javascript resources you can write something like this:

//  require  ,       //       ,       require( //     ["dojo/on", "dojo/touch", "dijit/form/Button", "dojo/domReady!"], // ,       , //        . //        ,      function(on, touch, Button) { //        . }); 

')
The module is declared very simple:

 //  'define'  'require' ,      define( //  ,     ["dojo/aspect", "dojo/_base/declare", "dijit/layout/BorderContainer"], //   ,     function(aspect, declare, BorderContainer) { //          //     (  ) return declare("mynamespace.layout.CustomBorderContainer", [BorderContainer], { //       . }); }); 


This simple way to declare a module, used by almost all AMD loaders, is incredibly simple and structured.

The modules listed in the dependencies are loaded before the callback function is run. The function itself usually returns a function or object representing the module. This is a simple template that loads quickly, supports modularity and allows developers to download only what they need.

Multifunctional Dojo loader also provides the ability to use plugins. Such as DOM readiness definitions (dojo / domReady!) And definition functions (hasJS). In addition, the bootloader is smart enough to load different modules depending
from external conditions:

 //     dojo/Deferred  define([ "./has", "./_base/lang", "./errors/CancelError", "./promise/Promise", "./has!config-deferredInstrumentation?./promise/instrumentation" ], function(has, lang, CancelError, Promise, instrumentation){ // ... }); 


Dojo is not just a maximum modularity, but also a ready module loader for your tasks.

2. Classes and extensibility with dojo / declare


While JavaScript does not provide a real class system, the Dojo Toolkit provides a class-like inheritance pattern based on the use of the dojo / declare. Declare is implemented in a framework in such a way that it allows developers to:


The Dojo class system uses prototype inheritance. Using dojo / declare is incredibly simple:

 // ,    define    define([ //    dojo/declare "dojo/declare", //    ,     "dijit/form/Button", "dojo/on", "mynamespace/_MyButtonMixin" //      "_" ], function(declare, Button, on, _MyButtonMixin) { //    declare(),      return declare( //     .      "mynamespace.CustomButton", //     . //      . [ Button, _MyButtonMixin ], // , ,      ,  //        { myCustomProperty: true, value: "Hello!", myCustomMethod: function() { //  - ! }, methodThatOverridesParent: function(val) { this.myCustomMethod(val); //  "this.inherited(arguments)"   //       return this.inherited(arguments); } }); }); 


The example does not solve any practical problem, but illustrates the reuse of code through the chain of inheritance and admixture, and also shows how the class can call the method of the parent class.

Another advantage of using the Dojo class system is that all properties and methods are customizable. Everything can be easily changed and expanded throughout the entire class creation process.

3. Aspects and “function to event function”


Aspects are one of the most powerful and important new developments in web development ... and the Dojo Toolkit has been providing them for many years. Instead of starting the function after a normal user event: “click”, “mouseover”, “keyup” - aspects allow you to call function B before or after function A is executed. In fact, you can connect functions to functions — and that’s cool!

Running one function after another looks like this:

 // after(,  ,  ,  ); aspect.after(myObject, "someMethod", function(arg1, arg2) { // ,       myObject.doSomething }, true); 


Running a function before performing another is also absolutely simple:
 aspect.before(myObject, "someMethod", function(arg1, arg2) { // ,       myObject.someMethod }); 


Aspects are extremely useful when creating a user interface using Dijit. Listening to events on one widget or class can cause changes in other widgets. This allows developers to create one large widget from many small ones.

 var self = this; aspect.after(this.submitButton, "onClick", function() { //       self.showAjaxSpinner(); }); 


4. Deferred and unified AJAX transport


Deferreds are object-oriented representations of asynchronous operations, making it easy to transfer operation states from one place to another. One of the most recent and important additions to jQuery was Deferreds. Coincidentally, the Dojo team's mantra is "Dojo did it." The Dojo Toolkit has been implementing the Deferreds implementation for several years now, using them for simple and complex AJAX operations, animation, and more.

Along with being one of the first to implement Deferred objects, Dojo introduced several methods for handling the input-input of the standard XMLHTTPRequest, including the window.name wrapper, the dojo / io / iframe module for asynchronous file downloads, and more. So, when do you use Deferred objects in Dojo? Whenever an asynchronous action occurs. Deferreds are returned from XHR requests, dojo / io requests, animations, and more.

 //  XHR ,    Deferred var def = xhr.get({ url: "/getSomePage" }); //      def.then(function(result) { result.prop = 'Something more'; return result; }).then(function(resultObjWithProp) { // .... }).then(function() { // .... }); 


What does the dojo / io / iframe module API look like?

 require(["dojo/io/iframe"], function(ioIframe){ //   ioIframe.send({ form: "myform", url: "handler.php", handleAs: "json" }).then(function(data){ //    }, function(err){ //   }). then(function() { //    ! }) }); 


The beauty of using Deferred in Dojo is that, regardless of the method, you know that you will always receive a Deferred object in response, speeding up the development and integration of the API. Starting in version 1.8, dojo / request is available in Dojo, which adds new AJAX consolidation methods. Here is an example of how dojo / request can be used:

 require(["dojo/request"], function(request){ request("request.html").then(function(response){ //  -     }, function(err){ //   }, function(evt){ //     }); }); 


A unified API makes development faster and code more compact.

5. Dijit UI Framework




Without a doubt, the biggest advantage of the Dojo Toolkit over other JavaScript frameworks is its Dijit UI framework.

This is an unprecedented set of layouts, forms and other tools:



Dijit allows you to declare widgets declaratively and programmatically. The declarative declaration looks like this:

 <div data-dojo-type="dijit.form.Button" data-dojo-props="label:'Click Me!'"></div> 


The traditional way of declaring widgets is as follows:

 require(["dijit/form/Button"], function(Button) { //    var button = new Button({ label: 'Click Me!' }, "myNodeId"); }); 


There are several dozens of widgets provided by the Dijit package and a few more dozens of those provided in the Dojox package. The Dojo UI framework is not just some useful custom element widgets, such as JQuery UI, it is a complete, tested framework for creating user interfaces.

6. Dojo Mobile




Like almost all Internet problems, Dojo has a solution for mobile web development - dojox / mobile namespace modules.

Dojo mobile solution provides:



Mobile widgets can be created declaratively or programmatically, similarly to Dijit widgets. Mobile screens support lazy rendering and can easily share data. The HTML framework for dojox / mobile is very simple:

 <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/> <meta name="apple-mobile-web-app-capable" content="yes" /> <title>  </title> <!--     --> <!--   dojo/javascript --> </head> <body> <!--    --> </body> </html> 


Using the dojox / mobile / deviceTheme module, we can define the user's device and apply the appropriate styles.

After setting the topic, we will connect the modules necessary for our application:

 require([ "dojox/mobile/ScrollableView", "dojox/mobile/Heading", "dojox/mobile/RoundRectList", "dojox/mobile/TabBar", "dojox/parser" ]); 


After everyone has connected, we declare declaratively our widgets and screens:

 <!--    Dojo's TweetView: http://dojotoolkit.org/documentation/tutorials/1.7/mobile/tweetview/app/ --> <!--   --> <div id="tweets" data-dojo-type="dojox.mobile.ScrollableView" data-dojo-props="selected: true"> <h1 data-dojo-type="dojox.mobile.Heading"> <!--   --> <div data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props="icon: 'images/refresh.png'" class="mblDomButton tweetviewRefresh" style="float:right;"> </div> Tweets </h1> <ul data-dojo-type="dojox.mobile.RoundRectList"> <li data-dojo-type="dojox.mobile.ListItem"> Tweet </li> </ul> </div> <!--   --> <div id="mentions" data-dojo-type="dojox.mobile.ScrollableView"> <h1 data-dojo-type="dojox.mobile.Heading"> <!--   --> <div data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props="icon: 'images/refresh.png'" class="mblDomButton tweetviewRefresh" style="float:right;"> </div>  </h1> <ul data-dojo-type="dojox.mobile.RoundRectList"> <li data-dojo-type="dojox.mobile.ListItem"> Mention tweet </li> </ul> </div> <!--   --> <div id="settings" data-dojo-type="dojox.mobile.ScrollableView"> <h1 data-dojo-type="dojox.mobile.Heading">Settings</h1> <h2 data-dojo-type="dojox.mobile.RoundRectCategory">Show</h2> <ul data-dojo-type="dojox.mobile.RoundRectList"> <li data-dojo-type="dojox.mobile.ListItem">   . </li> </ul> </div> 


The principles of using dojox / mobile widgets are absolutely identical to the principles of using Dijit widgets. This allows you to quickly get used to those who already have experience with Dijit, while for beginners it provides an easy mastering of the proposed widgets.

7. GFX and Charts


CSS animation is a great visualization tool, like animated images, but inferior in the flexibility and power of vector graphics. Raphael JS has always been the most popular tool for creating vector graphics on the client side, but the Dojo GFX library is undoubtedly more powerful. GFX can be configured to display vector graphics in SVG, VML, Silverlight, Canvas and WebGL. GFX provides a convenient wrapper for creating all forms of vector graphics (ellipse, line, etc.), which speeds up the creation of graphics.

Dojo GFX supports:



Creating a simple set of shapes might look like this:

 require(["dojox/gfx", "dojo/domReady"], function(gfx) { gfx.renderer = "canvas"; //  GFX  // : , ,  surface = gfx.createSurface("surfaceElement", 400, 400); //        curface.createCircle({ cx: 50, cy: 50, rx: 50, r: 25 }).setFill("blue"); //        hex  surface.createCircle({ cx: 300, cy: 300, rx: 50, r: 25 }).setFill("#f00"); //      surface.createRect({x: 180, y: 40, width: 200, height: 100 }). setFill({ type:"linear", x1: 0, y1: 0, //x: 0=>0,     x2: 0, //y: 0=>420,     y2: 420, colors: [ { offset: 0, color: "#003b80" }, { offset: 0.5, color: "#0072e5" }, { offset: 1, color: "#4ea1fc" } ] }); //      surface.createEllipse({ cx: 120, cy: 260, rx: 100, ry: 100 }).setFill({ type: "radial", cx: 150, cy: 200, colors: [ { offset: 0, color: "#4ea1fc" }, { offset: 0.5, color: "#0072e5" }, { offset: 1, color: "#003b80" } ] }); }); 


Dojo contains the dojox / charting library using the Dojo GFX API. Visualization of information using graphs is popular and not in vain - it is difficult to get the full picture just by looking at the numbers.

The dojox / charting library allows you to:


You can create a basic pie chart with the following code:

 <script> // x  y        //        chartData = [ { x: 1, y: 19021 }, { x: 1, y: 12837 }, { x: 1, y: 12378 }, { x: 1, y: 21882 }, { x: 1, y: 17654 }, { x: 1, y: 15833 }, { x: 1, y: 16122 } ]; require([ "dojo/parser", "dojox/charting/widget/Chart", "dojox/charting/themes/Claro", "dojox/charting/plot2d/Pie" ]); </script> <!--     --> <div data-dojo-type="dojox.charting.widget.Chart" data-dojo-props="theme:dojox.charting.themes.Claro" id="viewsChart" style="width: 550px; height: 550px;"> <!--    --> <div class="plot" name="default" type="Pie" radius="200" fontColor="#000" labelOffset="-20"></div> <!--    --> <div class="series" name="Last Week's Visits" array="chartData"></div> </div> 




Although the code above creates only a simple pie chart, dojox / charting is capable of many, many more.

8. Dgrid from SitePen team




SitePen, a company specializing in Dojo consulting, was created by Dojo co-founder Dylan Schiemann. Its employees tried to find a replacement for the overly bloated and awkward dojo / Grid and eventually created a dgrid.

The main features of the resulting package:



SitePen has done an outstanding job of documenting each dgrid component, so it’s incredibly easy to start creating your own multi-functional tables.

9. DOH testing framework


Testing on the client side is very important. Almost more important than on the server side. Given the number of browsers and the variety of functionality of different browser versions, interactive testing becomes mandatory. The DOH framework created for testing Dojo is available with Dojo. Writing tests is incredibly easy, and the tests themselves can be presented in several formats:

 //      ,      dojo.provide("my.test.module"); //   doh.register("MyTests", [ //      function assertTrueTest(){ doh.assertTrue(true); doh.assertTrue(1); doh.assertTrue(!false); }, // ...    : name, setUp, tearDown, and runTest { name: "thingerTest", setUp: function(){ this.thingerToTest = new Thinger(); this.thingerToTest.doStuffToInit(); }, runTest: function(){ doh.assertEqual("blah", this.thingerToTest.blahProp); doh.assertFalse(this.thingerToTest.falseProp); // ... }, tearDown: function(){ } }, // ... ]); 


The above test example is very simple. But what about the more difficult situation, i.e. asynchronous action? The most obvious examples of asynchronous actions are AJAX, animation, and other delayed actions. DOH provides an incredibly easy way to test asynchronous actions using doh.Deffered objects:

 { name: "Testing deferred interaction", timeout: 5000, runTest: function() { var deferred = new doh.Deferred(); myWidget.doAjaxAction().then(deferred.getTestCallback(function(){ doh.assertTrue(true); }); return deferred; } } 


In the example above, the “getTestCallback” function will be launched after the end of the “doAjaxAction” method and returns the test result.

Subsequent tests will not be run until doh.Deferred resolves, so no time need to be noticed and there is no problem with overlapping tests. DOH provides benchmarking capabilities far superior to other other frameworks. DOH also provides a Java robot that fully emulates mouse and keyboard actions for more accurate and realistic testing. If you hear Homer Simpson's “Woohoo!” Scream, then all the tests passed. But if you hear the terrible “DOH!”, Then you need to revise your code in order to correct errors.

10. Dojo build process


When the web application is ready for release, it is extremely important for the sake of optimized loading and caching to create minified and properly divided into JavaScript files. This reduces the load on the site.

The Dojo build system analyzes the declared classes and automatically determines the dependencies during the build. To use the Dojo build system, you create what is called a build profile. The built profile can contain numerous layers and be quite complex. The example ghost below shows the simplest build profile:

 var profile = { releaseDir: "/path/to/releaseDir", basePath: "..", action: "release", cssOptimize: "comments", mini: true, optimize: "closure", layerOptimize: "closure", stripConsole: "all", selectorEngine: "acme", layers: { "dojo/dojo": { include: [ "dojo/dojo", "app/main" ], customBase: true, boot: true } }, resourceTags: { amd: function (filename, mid) { return /\.js$/.test(filename); } } }; 


Dojo build profile allows a developer to customize:



The built profile is launched using the command line (recently rewritten to Node.js) and can be supplemented or corrected with various arguments. A small example of running an assembly profile:

 ./build.sh --profile /path/to/app/app.profile.js --require /path/to/app/boot.js 


The Dojo build process provides an incredible amount of control over the generation of build files and completes the process of optimizing a web application. With minified and layered JavaScript and CSS files, your web application is ready to be shown!

11. Bonus! Dojo Treasure Chest More Dojox


Two very important Dojox libraries have already been mentioned above: Dojox Mobile and GFX, but these are only two of the many hidden treasures presented in Dojo. These treasures include:



Dojo.

Dojo Toolkit JavaScript:


, Dojo. , Dojo (, , XHR ) -.

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


All Articles