@H_
618_1@
Introduction
@H_
618_1@If you're a Java progr
AMMer coming to Dojo with little or noexperience of JavaScript,chances are you're going to struggle withsome of the concepts that enable it to work. The main concerns withDojo are that — at the time of wri
Ting —
it is still in its infancy(version 1.0 was only released in February 2008)
and thedocumentation available is still some@R_
616_10112@ limited. This article
Helps you bridge the gap from Java code to Dojo so that you can getup to speed quickly and use the toolkit when developing yourapplication
s.
@H_
618_1@This article does not describe how to obtain the Dojo toolkit orthe necessary statements needed to use it,because there are manyother
resources available that provide that information. Thearticle is written for Web developers who are coming to Dojo from aservlet development
BACkground.
@H_
618_1@
The JavaScripthash
@H_
618_1@One of the first ch
ALLENges is to underst
and the
Syntax that isused when invoking Dojo functions,in particular the use of the"hash" or JavaScript ob
ject. A hash is expressed as a set ofattributes delimited by commas
between curly brace
s. A simpleexample is shown in Lis
Ting 1,declaring a hash consis
Ting of 6attributes: a
String,an
Integer,a
Boolean,an undefinedattribute,another hash,and a function.
Listing 1. Example JavaScript hash
var myHash = {
str_attr : "foo",int_attr : 7,bool_attr : true,undefined_attr : null,hash_attr : {},func_attr : function() {}
};
|
@H_
618_1@
it is important to remember that JavaScript is weakly typed,soalthough each attribute has been initialized to a value linked toits name,there is no reason why the initial
str_attr
attributec
Annot be subsequently set to an
Integer or
Boolean (or any othertype for that matter). Each attribute in the hash can be accessedor set using the dot operator (as shown in Lis
Ting 2).
Listing 2. Accessing and setting hash attributes
// Accessing a hash attribute...
console.log(myHash.str_attr);
// SetTing a hash attribute...
myHash.str_attr = "bar";
|
@H_
618_1@The first four attributes of
@H_174_28
@myHash
shouldbe self-explanatory. The fact that a hash can have attributes thatare also hashes should be no surprise. (This can be thought of asana
logous to Java classes referencing both primitives and ob
ject
s.)
it is the final attribute that is most important to understand.
@H_
618_1@
Functions areobjects
@H_
618_1@Although in Java code there is a
java.reflection.Method
class,it essentially acts as wrapper to a method. In JavaScript thefunction is an ob
ject like any other that can be set,referenced,and passed as an argument to other function
s. Often
it is necessaryto declare new functions in function calls in much the same way asan anon
ymous inner class can be declared in a Java method cal
l.
@H_
618_1@Another important difference
between Java methods and JavaScriptfunctions is that JavaScript functions can be run in differentco
ntext
s. In Java progr
AMMing the use of the keyword
this
refersto the current instance of the class where
it is used. When used ina JavaScript function,
this
refersto the co
ntext in which that function is running. A function willrun in the closure that defi
nes it unless otherwise specified.
@H_
618_1@In the simplest terms,a closure can be considered to be anyJavaScript code contained within curly braces (
{}
).A function declared inside a JavaScript file can use
this
toaccess any variable declared in the main body of that file,but afunction declared inside a hash can only use
this
toreference variables declared inside that hash,unless
it isprovided with an alternative co
ntext to work in.
@H_
618_1@Because enclosed functions are often
required as arguments to Dojofunctions,understanding how to set
their co
ntext will save a lotof unnecessary debugging.
@H_
618_1@The main Dojo function that is used to assign co
ntextis
dojo.hitch
.You may never use
dojo.hitch
,but
it is important to underst
and that
it is one of thecornersto
nes of Dojo,and many other functions are invoking itunder the cover
s.
@H_
618_1@Lis
Ting 3 shows how co
ntext hitching works (its output is shown in
figure 1):
- A variable is defined at the global context (
globalContextVariable
)and another variable is declared in the context of a hash(enclosedVariable
).
- The function
accessGlobalContext()
cansuccessfully accessglobalContextVariable
anddisplay its value.
- But,
enclosedFunction()
canonly access its local variableenclosedVariable
(notethat the value ofglobalContextVariable
isdisplayed as "undefined").
- Using
dojo.hitch
to"hitch"enclosedFunction()
tothe global context allowsglobalContextVariable
tobe displayed (note however thatenclosedVariable
isNow undefined because it is not declared in the contextthatenclosedFunction()
isrunning.
Listing 3. Closures and context
var globalContextVariable = "foo";
function accessGlobalContext() {
// This will successfully output "foo"...
console.log(this.globalContextVariablE);
};
var myHash = {
enclosedVariable : "bar",enclosedFunction : function() {
// Display global context variable...
console.log(this.globalContextVariablE);
// Display enclosed context variable...
console.log(this.enclosedVariablE);
}
};
console.log("Calling accessGlobalContext()...");
accessGlobalContext();
console.log("Calling myHash.enclosedFunction()...");
myHash.enclosedFunction();
console.log("Switch the context using dojo.hitch...");
var switchContext = dojo.hitch(this,myHash.enclosedFunction);
switchContext();
|
Figure 1. How contect hitching works
title="Dojo concept for javascript developer" alt="Dojo concept for javascript developer" src="http://code.js-code.com/res/2019/05-28/09/46c8b054896ebdc032eacc833610af5e.png" height="212" width="452" "Dojo
concepts
forJavadevelopers" style="" src="http://simg.sinajs.cn/blog7style/images/common/sg_trans.gif">
@H_618_1@Declaringclasses
Class declaration tips
- While@H_174_28@myClassisa perfectly valid name,it is a better practice to declare namesusing a fully qualified class name style,for example,
com.ibm.dojo.myClass
.This does not mean that the class should be deployed to the filesystem under the relative path of "./com/ibm/dojo/"; it simplyreduces the chances of there being naming collisions with any otherclasses.
- There must never be a
,
(comma)after the last attribute because some browsers will ignore it(@R_801_4979@,but others will blow-up (Internet Explorer). This rulealso applies to declarations of hash objects anywhere.
@H_618_1@The reason why this hitching is so important will become apparentas soon as you start to declare Dojo classes or to create your ownwidgets. One of the greatest powers of Dojo is the ability to"wire" objects together through the use of thedojo.connect
functionand the built-in pub/sub model.
@H_618_1@Declaring a class requires three objects:
- A unique name for the class
- A parent class to extend function from (plus any "mix-in" classesto simulate multiple inheritancE)
- A hash defining all the attributes and functions.
@H_618_1@The simplest possible class that can be declared in shown inLisTing 4,and its instantiation in LisTing 5.
Listing 4. Basic class declaration
dojo.declare(
"myClass",null,{}
);
|
Listing 5. Basic class instantiation
var myClassInstance = new myClass();
|
@H_618_1@If you want to declare a "real" (that is,useful) Dojo class,it'simportant to understand constructors. In Java code you can declaremultiple overloaded constructors to enable the instantiation of theclass by a variety of different signatures. In a Dojo class you candeclare apreamble
,aconstructor
,and apostscript
,but in the majority of cases you will only need to declare aconstructor.
- Unless you're mixing-in other classes to simulate multipleinheritances,you are unlikely to require
preamble
,as it allows you to manipulate yourconstructor
argumentsbefore they are actually passed to the extended and mixed-inclasses.
-
postscript
drivesthe Dojo widget life cycle methods,but provides no benefit to astandard Dojo class.
@H_618_1@it is not essential to declare any of them,but to pass any valuesinto an instance of the class theconstructor
functionmust be declared as a minimum. If theconstructor
argumentsare to be accessed by any other method of the class,they must beassigned to declared attributes. LisTing 6 shows a class thatassigns only one of itsconstructor
argumentsto a class attribute and then attempts to reference both in anothermethod.
Listing 6. Assigning constructor arguments
dojo.declare(
"myClass",{
arg1 : "",constructor : function(arg1,arg2) {
this.arg1 = arg1;
},mymethod : function() {
console.log(this.arg1 + "," + this.arg2);
}
}
);
var myClassInstance = new myClass("foo","bar");
myClassInstance.mymethod();
|
Figure 2. Output from assigning constructorarguments
title="Dojo concept for javascript developer" alt="Dojo concept for javascript developer" src="http://code.js-code.com/res/2019/05-28/09/46c8b054896ebdc032eacc833610af5e.png" height="91" width="454" "Dojo
conceptsforJavadevelopers" style="" src="http://simg.sinajs.cn/blog7style/images/common/sg_trans.gif">
@H_618_1@Complex attributerules
@H_618_1@Class attributes can be initialized when declared,but if theattribute is initialized with a complex object type (such as a hashor an array) that attribute becomes analogous to a public staticvariable in a Java class. This means that whenever any instanceupdates it,the change will be reflected in all other instances. Toavoid this problem,complex attributes should be initialized in theconstructor; however,this is not necessary for simple attributessuch as Strings,Booleans,and so on.
Listing 7. Global class attributes
Figure 3. Class attributes
title="Dojo concept for javascript developer" alt="Dojo concept for javascript developer" src="http://code.js-code.com/res/2019/05-28/09/46c8b054896ebdc032eacc833610af5e.png" height="142" width="452" "Dojo
conceptsforJavadevelopers" style="" src="http://simg.sinajs.cn/blog7style/images/common/sg_trans.gif">
@H_618_1@Overridingmethods
@H_618_1@A method of a superclass can be extended by declaring an attributewith the same name. There is no concept of overloading,asJavaScript ignores any unexpected arguments and substitutes nullfor any that are missing. In Java code,to invoke the overriddenmethod you call the method on super (that is,super().methodName(arg1,arg1);
),but in Dojo you use theinherited
@H_316_27@method(this.inherited(arguments);
).LisTing 8 shows two classes declared,wherechild
extendsparent
,overriding itsHelloWorld
@H_316_27@method,but callsinherited
toaccess the function ofparent
.
Listing 8. Invoking superclass method in Dojo
dojo.declare(
"parent",{
HelloWorld : function() {
console.log("parent says 'Hello world'");
}
}
);
dojo.declare(
"child",parent,{
HelloWorld : function() {
this.inherited(arguments); // Call superclass method...
console.log("child says 'Hello world'");
}
}
);
var child = new child();
child.HelloWorld();
|
Figure 4. Output from invoking superclass method inDojo
title="Dojo concept for javascript developer" alt="Dojo concept for javascript developer" src="http://code.js-code.com/res/2019/05-28/09/46c8b054896ebdc032eacc833610af5e.png" height="107" width="453" "Dojo
conceptsforJavadevelopers" style="" src="http://simg.sinajs.cn/blog7style/images/common/sg_trans.gif">
@H_618_1@@L_944_27@
@H_618_1@LisTing 9 shows a Java class that,upon instantiation,copies theelements from the supplied String array to an ArrayList of Strings.It would not be unreasonable to assume that the same functionalitycan be provided in Dojo with the code in LisTing 10. (Note theinstantiation oftargetArray
inthe constructor function to prevent it being global.)Unfortunately,it will result in the error message shown in figure5,because the function declared in thedojo.forEach
@H_316_27@methodcall creates a closure that definesthis
asreferring to its own body.
Listing 9. Accessing class scoped variable in Javacode
import java.util.ArrayList;
public class MyClass
{
// Declare an ArrayList of Strings...
private ArrayList<String> targetArray = new ArrayList<String>();
public MyClass(String[] sourceArray)
{
// Copy each element of a String[] into the ArrayList...
for (String val: sourceArray)
{
this.targetArray.add(val);
}
}
}
|
Listing 10. Missing context in Dojo
dojo.declare(
"myClass",{
targetArray: null,constructor: function(sourcE) {
// Initialise in constructor to avoid making global
this.targetArray = [];
// Copy each element from sourcE into target...
dojo.forEach(source,function(item) {
this.targetArraY[this.targetArray.length] = item;
});
},}
);
// This will cause an error!
var myClass = new myClass(["item1","item2"]);
|
Figure 5. Output from missing context in Dojo
title="Dojo concept for javascript developer" alt="Dojo concept for javascript developer" src="http://code.js-code.com/res/2019/05-28/09/46c8b054896ebdc032eacc833610af5e.png" height="105" width="452" "Dojo
conceptsforJavadevelopers" style="" src="http://simg.sinajs.cn/blog7style/images/common/sg_trans.gif">
@H_618_1@AlthoughtargetArray
isnot defined at the context enclosed by the function,it is possibleto pass the context where it is defined as an argument to the Dojofunction. This means thethis
keywordcan then access any objects (including functions) that have beendeclared at that context. The correct implementation is shown inLisTing 11 (note the additional code in bold).
Listing 11. Setting correct context in Dojo
dojo.declare(
"myClass",function(item) {
this.targetArraY[this.targetArray.length] = item;
},this);
},}
);
|
@H_618_1@Context is not always passed as the same argument in a Dojofunctions signature:
- In
dojo.subscribe
thecontext is passedbeforethe functiondeclaration (LisTing 12).
- In
dojo.connect
boththe context where the trigger method is defined and the contextwhere the target method is defined should be supplied. LisTing 13shows an example whereobj1
isthe context where@H_174_28@methodAisdefined andobj2
isthe context where@H_174_28@methodBisdefined. Calling@H_174_28@methodAonobj1
willresult in@H_174_28@methodBbeinginvoked onobj2
.
Listing 12. Setting context in dojo.subscribe
dojo.declare(
"myClass",{
subscribe : function() {
dojo.subscribe("publication",this,function(pub) {
this.handlePublication(pub);
});
},handlePublication : function(pub) {
console.log("Received: " + pub);
}
}
);
|
Listing 13. Setting context in dojo.connect
dojo.connect(obj1,"methodA",obj2,"methodB");
|
@H_618_1@Conclusion
@H_618_1@JavaScript will never come naturally to developers who have becomeused to the more structured environment of Java code. Yet theimplementation of Dojo,with its class declaration capabilities,does make the leap to client-side development considerably easier.A good understanding of context,and when and how to set it,willsave a lot of pain for the Java developer and Help them confidentlyadd JavaScript to their toolBox.