微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Dojo concept for javascript developer

Introduction

If you're a Java programmer 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 writing — it is still in its infancy(version 1.0 was only released in February 2008) and thedocumentation available is still somewhat limited. This articlehelps you bridge the gap from Java code to Dojo so that you can getup to speed quickly and use the toolkit when developing yourapplications.

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.

The JavaScripthash

One of the first challenges is to understand the Syntax that isused when invoking Dojo functions,in particular the use of the"hash" or JavaScript object. A hash is expressed as a set ofattributes delimited by commas between curly braces. A simpleexample is shown in Listing 1,declaring a hash consisting 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() {}
};                      
                

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 initialstr_attrattributecannot 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 Listing 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";

The first four attributes ofmyHashshouldbe self-explanatory. The fact that a hash can have attributes thatare also hashes should be no surprise. (This can be thought of asanalogous to Java classes referencing both primitives and objects.)It is the final attribute that is most important to understand.

Functions areobjects

Although in Java code there is ajava.reflection.Methodclass,it essentially acts as wrapper to a method. In JavaScript thefunction is an object like any other that can be set,referenced,and passed as an argument to other functions. Often it is necessaryto declare new functions in function calls in much the same way asan anonymous inner class can be declared in a Java method call.

Another important difference between Java methods and JavaScriptfunctions is that JavaScript functions can be run in differentcontexts. In Java programming the use of the keywordthisrefersto the current instance of the class where it is used. When used ina JavaScript function,thisrefersto the context in which that function is running. A function willrun in the closure that defines it unless otherwise specified.

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 usethistoaccess any variable declared in the main body of that file,but afunction declared inside a hash can only usethistoreference variables declared inside that hash,unless it isprovided with an alternative context to work in.

Because enclosed functions are often required as arguments to Dojofunctions,understanding how to set their context will save a lotof unnecessary debugging.

The main Dojo function that is used to assign contextisdojo.hitch.You may never usedojo.hitch,but it is important to understand that it is one of thecornerstones of Dojo,and many other functions are invoking itunder the covers.

Listing 3 shows how context hitching works (its output is shown infigure 1):

  • A variable is defined at the global context (globalContextvariable)and another variable is declared in the context of a hash(enclosedVariable).
  • The functionaccessGlobalContext()cansuccessfully accessglobalContextvariableanddisplay its value.
  • But,enclosedFunction()canonly access its local variableenclosedVariable(notethat the value ofglobalContextvariableisdisplayed as "undefined").
  • Usingdojo.hitchto"hitch"enclosedFunction()tothe global context allowsglobalContextvariabletobe displayed (note however thatenclosedVariableisNow 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

How context hitching works

Declaringclasses

Class declaration tips

  • WhilemyClassisa 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(FireFox),but others will blow-up (Internet Explorer). This rulealso applies to declarations of hash objects anywhere.

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.connectfunctionand the built-in pub/sub model.

Declaring a class requires three objects:

  1. A unique name for the class
  2. A parent class to extend function from (plus any "mix-in" classesto simulate multiple inheritance)
  3. A hash defining all the attributes and functions.

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();

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 requirepreamble,as it allows you to manipulate yourconstructorargumentsbefore they are actually passed to the extended and mixed-inclasses.
  • postscriptdrivesthe Dojo widget life cycle methods,but provides no benefit to astandard Dojo class.

It is not essential to declare any of them,but to pass any valuesinto an instance of the class theconstructorfunctionmust be declared as a minimum. If theconstructorargumentsare 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 itsconstructorargumentsto 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

Output from assigning constructor arguments

Complex attributerules

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

Class attribues

Overridingmethods

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 theinheritedmethod(this.inherited(arguments);).Listing 8 shows two classes declared,wherechildextendsparent,overriding itshelloWorldmethod,but callsinheritedtoaccess 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

Output from invoking superclass method in Dojo

Setting methodcontext

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 oftargetArrayinthe constructor function to prevent it being global.)Unfortunately,it will result in the error message shown in figure5,because the function declared in thedojo.forEachmethodcall creates a closure that definesthisasreferring 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

Output from missing context in Dojo

AlthoughtargetArrayisnot 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 thethiskeywordcan 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); },} );

Context is not always passed as the same argument in a Dojofunctions signature:

  • Indojo.subscribethecontext is passedbeforethe functiondeclaration (Listing 12).
  • Indojo.connectboththe context where the trigger method is defined and the contextwhere the target method is defined should be supplied. Listing 13shows an example whereobj1isthe context wheremethodAisdefined andobj2isthe context wheremethodBisdefined. CallingmethodAonobj1willresult inmethodBbeinginvoked 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");

Conclusion

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.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


我有一个网格,可以根据更大的树结构编辑小块数据.为了更容易知道用户保存了什么,我希望当用户第一次看到网格时,网格处于不可编辑状态.当用户准备好后,他们可以单击编辑按钮,这将使网格的某些部分可编辑.然后,有一个保存或取消按钮可以保存更改或还原.在大多数情况下它是有效的.但
我即将开始开发一款教育性的视频游戏.我已经决定以一种我可以轻松打包为Web,Mobiles和可能的Standalone版本的方式来实现这一目标.我不想使用Flash.因此,我确信(无论如何我会听取建议)使用JavaScript和SVG.我正在对这个问题进行大量研究,但我很难把各个部分放在一起.我知道Raphae
我正在使用带有Grails2.3.9的Dojo1.9.DojoNumberTextBox小部件–我在表单中使用–将固定格式(JavaScript基本格式)的实数值(例如:12.56)设置为HTML表单输入字段(但根据浏览器区域设置显示/编辑它们,所以用户总是看到格式正确的数字).另一方面,Grails期望输入字段根据浏览器
1.引言鉴于个人需求的转变,本系列将记录自学arcgisapiforjavaScript的学习历程,本篇将从最开始的arcgisapiforjavaScript部署开始,个人声明:博文不在传道受业解惑,旨在方便日后复习查阅。由于是自学,文章中可能会出现一些纰漏,请留言指出,不必留有情面哦!2.下载ArcGISforDe
我正在阅读使用dojo’sdeclare进行类创建的语法.描述令人困惑:Thedeclarefunctionisdefinedinthedojo/_base/declaremodule.declareacceptsthreearguments:className,superClass,andproperties.ClassNameTheclassNameargumentrepresentsthenameofthec
我的团队由更多的java人员和JavaScript经验丰富组成.我知道这个问题曾多次被问到,但为了弄清楚我的事实,我需要澄清一些事情,因为我在客户端技术方面的经验非常有限.我们决定使用GWT而不是纯JavaScript框架构建我们的解决方案(假设有更多的Java经验).这些是支持我的决定的事实.>
路由dojo/framework/srcouting/README.mdcommitb682b06ace25eea86d190e56dd81042565b35ed1Dojo应用程序的路由路由FeaturesRoute配置路径参数RouterHistoryManagersHashHistoryStateHistoryMemoryHistoryOutletEventRouterContextInjectionOutl
请原谅我的无知,因为我对jquery并不熟悉.是否有dojo.connect()的等价物?我找到了这个解决方案:http:/hink-robot.com/2009/06/hitch-object-oriented-event-handlers-with-jquery/但是没有断开功能!你知道jquery的其他解决方案吗?有jquery.connect但这个插件在我的测试中不起作用.
与java类一样,在dojo里也可以定义constructor 构造函数,在创建一个实例时可以对需要的属性进行初始化。//定义一个类mqsy_yjvar mqsy_yj=declare(null,{     //thedefaultusername    username: "yanjun",          //theconstructor   
我一直在寻找一些最佳实践,并想知道Dojo是否具有框架特定的最佳实践,还是最好只使用通用的Javascript标准?特别是我主要是寻找一些功能和类评论的指导方针?解决方法:对于初学者来说,这是项目的风格指南:DojoStyleGuide