- 浏览: 415150 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
liyuanhoa_:
...
struts2.0中struts.xml配置文件详解 -
chenmingde:
...
Velocity应用(一) -
weizhikai_ai:
第二十六,当一个线程进入一个对象的一个synchronized ...
Java常见面试题(含答案) -
Aurora_lr:
...
Spring宠物商店学习笔记(一) - -
zs911zs:
all copy from http://www.iteye ...
Mule入门文档
声明类并设置上下文
文档选项
打印本页
将此页作为电子邮件发送
英文原文
级别: 中级
Dave Draper, WebSphere Application Server Administrative Console 开发人员, IBM
2008 年 11 月 03 日
Dojo 在基于 Web 的应用程序中越来越受到欢迎。很多开发人员是 Java™ 编程方面的能手,但是在 JavaScript 方面却缺乏经验。从强类型、面向对象的编译语言转向动态的、弱类型脚本语言,开发人员需要经历概念跃迁带来的困难。这种混乱使开发人员很难正确地声明 Dojo 类。本文将帮助梳理这种混乱,解释为何必须设置上下文,以及如何实现它。
简介
如果您是一名只有很少或根本没有 JavaScript 经验的开发人员,在接触 Dojo 时可能需要掌握一些必要的概念。Dojo 的一个主要问题是(在撰写本文之际),它仍然处于其婴儿期(版本 1.0 在 2008 年 2 月份才发布),并且可用的文档仍然非常有限。本文将帮助您理解 Dojo 和 Java 代码之间的联系,使您在开发应用程序时可以快速入手并掌握这个工具箱。
本文并没有介绍如何获得 Dojo 工具箱或一些必要的使用指令,因为已经有大量的资源提供了此类信息。本文主要针对从 servlet 开发转向 Dojo 的 Web 开发人员。
Ajax 资源中心
请访问 Ajax 资源中心,这是有关 Ajax 编程模型信息的一站式中心,包括很多文档、教程、论坛、blog、wiki 和新闻。任何 Ajax 的新信息都能在这里找到。
JavaScript hash
需要面对的主要挑战之一就是理解在调用 Dojo 函数时使用的语法,特别是 “hash” 或 JavaScript 对象。hash 被表示为使用逗号间隔的一组属性,并且使用大括号括起。清单 1 显示了一个简单的例子,它声明了一个包含 6 个属性的 hash:一个字符串、一个整数、一个布尔值、一个未定义的属性、另一个 hash 和一个函数。
清单 1. 示例 JavaScript hash
var myHash = {
str_attr : "foo",
int_attr : 7,
bool_attr : true,
undefined_attr : null,
hash_attr : {},
func_attr : function() {}
};
注意,JavaScript 是弱类型的,因此尽管每个属性被初始化为一个与其名称相关的值,但仍然需要把 str_attr 属性设置为一个整数或布尔值(或其他任何类型)。使用 dot 操作符可以访问或设置 hash 中的每个属性(参见清单 2)。
清单 2. 访问和设置 hash 属性
// Accessing a hash attribute...
console.log(myHash.str_attr);
// Setting a hash attribute...
myHash.str_attr = "bar";
myHash 的前四个属性的含义不言自明。事实上,hash 可以拥有 hash 属性,这并不奇怪。(可以将这看作类似于原语和对象的 Java 类)。这是需要理解的最后一个重要属性。
函数和对象
尽管 Java 代码中有一个 java.reflection.Method 类,但它实际上只充当方法的包装器。在 JavaScript 中,该函数可以是任何可设置、引用和作为参数传递给其他函数的对象。通常,像在 Java 方法调用中声明匿名 inner 类一样,也需要在函数调用中声明新函数。
Java 方法和 JavaScript 函数之间的另一个重要区别是 JavaScript 函数可以运行在不同的上下文中。在 Java 编程中,使用 this 关键字引用所使用类的当前实例。当在 JavaScript 函数中使用时,this 引用该函数运行的上下文。如果没有指定,函数将在定义它的闭包中运行。
在最简单的情况下,闭包可以被看作是使用大括号({})包含的任意 JavaScript 代码。JavaScript 文件内部声明的函数可以使用 this 访问在文件主体中声明的任何变量,但是在 hash 内声明的函数只能使用 this 引用在 hash 内部声明的变量,除非提供其他上下文。
由于经常需要使用封闭的函数作为 Dojo 函数的参数,因此理解如何设置上下文将省去大量的调试工作。
用于指定上下文的主要 Dojo 函数是 dojo.hitch。您可能从不使用 dojo.hitch,但必须了解它是 Dojo 的关键部分,很多函数都在内部调用它。
清单 3 展示了上下文连接的工作原理(其输出显示在图 1 中):
在全局上下文(globalContextVariable)中定义一个变量,在一个 hash 上下文(enclosedVariable)中声明另一个变量。
函数 accessGlobalContext() 可以成功访问 globalContextVariable 并显示其值。
但是,enclosedFunction() 只可以访问其本地变量 enclosedVariable(注意 globalContextVariable 的值显示为 “未定义”)。
使用 dojo.hitch 将 enclosedFunction() 连接到全局上下文,这样就可以显示 globalContextVariable(注意,enclosedVariable 现在为 “未定义”,因为它不是在运行 enclosedFunction() 的上下文中声明的)。
清单 3. 闭包和上下文
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();
图 1. 上下文连接的工作原理
声明类
声明类的技巧
尽管 myClass 是一个有效的名称,但是最好使用完全限定类名的形式声明名称,例如 com.ibm.dojo.myClass。这并不表示应当把类部署到相对路径 “./com/ibm/dojo/” 下的文件系统;它只是减少了与其他类名冲突的几率。
在最后一个属性之后绝不会出现 ,(逗号),因为一些浏览器将忽略它(FireFox),但是其他浏览器(Internet Explorer)会将它弹出。这条规则也适用于 hash 对象的声明。
为什么连接如此重要?您将在声明 Dojo 类或创建自己的部件时体验到它的重要性。Dojo 的一大功能就是能够通过使用 dojo.connect 函数和内置的 pub/sub 模型将对象 “连接” 起来。
类的声明需要三个对象:
一个惟一的类名
用于扩展函数的父类(以及模拟多个继承的 “混合” 类)
定义所有属性和函数的 hash
清单 4 展示了最简单的类声明方式,清单 5 展示了该类的实例化。
清单 4. 基本的类声明
dojo.declare(
"myClass",
null,
{}
);
清单 5. 基本的类实例化
var myClassInstance = new myClass();
如果希望声明一个 “真正的”(即有用的)Dojo 类,那么一定要理解构造函数。在 Java 代码中,您可以通过使用各种不同的签名声明多个重载的构造函数,从而支持实例化。在一个 Dojo 类中,可以声明一个 preamble、一个 constructor 和一个 postscript,但是在大多数情况下,您只需要声明一个构造函数。
除非混合使用了其他类来模拟多个继承,否则不需要用到 preamble,因为它允许您在 constructor 参数传递给扩展类和混合类之前对其进行处理。
postscript 产生了 Dojo 小部件生命周期方法,但对标准 Dojo 类没有什么用处。
不一定要全部都声明,但是要将所有值传递到类的实例中,就必须将 constructor 函数声明为 minimum。如果 constructor 参数将被该类的其他方法访问,必须将它们赋值给已声明的属性。清单 6 展示了一个类,它只将其中一个 constructor 参数赋值给一个类属性,并尝试在另一个方法中引用它们。
清单 6. 赋值构造函数参数
dojo.declare(
"myClass",
null,
{
arg1 : "",
constructor : function(arg1, arg2) {
this.arg1 = arg1;
},
myMethod : function() {
console.log(this.arg1 + "," + this.arg2);
}
}
);
var myClassInstance = new myClass("foo", "bar");
myClassInstance.myMethod();
图 2. 赋值构造函数参数的结果
复杂的属性规则
类属性可以在声明时进行初始化,但是如果使用复杂对象类型(例如 hash 或数组)初始化属性,该属性将类似于 Java 类中的公共静态变量。这意味着任何实例无论在何时更新它,修改将反映到所有其他实例中。为了避免这个问题,应当在构造函数中初始化复杂属性;然而,对于字符串、布尔值等简单属性则不需要这样做。
清单 7. 全局类属性
dojo.declare(
"myClass",
null,
{
globalComplexArg : { val : "foo" },
localComplexArg : null,
constructor : function() {
this.localComplexArg = { val:"bar" };
}
}
);
// Create instances of myClass A and B...
var A = new myClass();
var B = new myClass();
// Output A's attributes...
console.log("A's global val: " + A.globalComplexArg.val);
console.log("A's local val: " + A.localComplexArg.val);
// Update both of A's attributes...
A.globalComplexArg.val = "updatedFoo";
A.localComplexArg.val = "updatedBar";
// Update B's attributes...
console.log("A's global val: " + B.globalComplexArg.val);
console.log("A's local val: " + B.localComplexArg.val);
图 3. 类属性
覆盖方法
超类的方法可以通过使用相同的名称声明属性来扩展。这里和重载无关,因为 JavaScript 将忽略任何意外的参数并使用 null 代替任何缺失的参数。在 Java 代码中,如果要调用被覆盖的方法,就必须在超类上调用该方法(即 super().methodName(arg1, arg1);),但在 Dojo 中,将使用 inherited 方法(this.inherited(arguments);)。清单 8 展示了两个已声明的类,其中 child 扩展了 parent,覆盖了它的 helloWorld 方法,但是调用 inherited 来访问 parent 的函数。
清单 8. 在 Dojo 中调用超类方法
dojo.declare(
"parent",
null,
{
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();
图 4. 在 Dojo 中调用超类方法的输出
设置方法上下文
清单 9 展示了一个实例化后的 Java 类,它将字符串数组中的元素复制到一个字符串 ArrayList。显然,使用清单 10 的代码可以在 Dojo 中提供相同的功能(注意,在构造函数中实例化 targetArray,防止它变成全局性的)。不幸的是,它将导致图 5 所示的错误消息,因为在 dojo.forEach 方法调用中声明的函数创建了一个闭包,该闭包将 this 定义为引用它本身。
清单 9. 在 Java 代码中访问类的作用域变量
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);
}
}
}
清单 10. 在 Dojo 中缺失上下文
dojo.declare(
"myClass",
null,
{
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"]);
图 5. 在 Dojo 中缺失上下文的输出
管 targetArray 并不是在函数包围的上下文中定义的,但是可以将上下文定义为参数传递给 Dojo 函数。这意味着 this 关键字可以访问在该上下文中声明的任何对象(包括函数)。清单 11 显示了正确的实现(注意,增加的代码用粗体表示)。
清单 11. 在 Dojo 中设置正确的上下文
dojo.declare(
"myClass",
null,
{
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);
},
}
);
上下文并不总是作为 Dojo 函数签名中的相同参数传递的:
在 dojo.subscribe 中,上下文是在函数声明之前传递的(参见清单 12)。
在 dojo.connect 中,应该分别提供定义 trigger 方法和 target 方法的上下文。清单 13 展示了一个例子,其中 obj1 定义 methodA 的上下文,而 obj2 定义 methodB 的上下文。对 obj1 调用 methodA 将导致对 obj2 调用 methodB。
清单 12. 在 dojo.subscribe 中设置上下文
dojo.declare(
"myClass",
null,
{
subscribe : function() {
dojo.subscribe("publication",
this,
function(pub) {
this.handlePublication(pub);
});
},
handlePublication : function(pub) {
console.log("Received: " + pub);
}
}
);
清单 13. 在 dojo.connect 中设置上下文
dojo.connect(obj1, "methodA", obj2, "methodB");
结束语
已习惯构化 Java 代码环境的开发人员将很难适应 JavaScript。但是 Dojo 提供了类声明功能,使向客户端开发过渡变得非常简单。充分理解上下文,以及何时、如何设置上下文,将为 Java 开发人员省去很多麻烦,并帮助他们自信地将 JavaScript 添加到自己的工具箱中。
参考资料
您可以参阅本文在 developerWorks 全球网站上的 英文原文。
在 DojoToolkit.org 中可以找到所有入门信息和资源。
通过 developerWorks 文章 JavaScript Development Toolkit 简介(developerWorks,2008 年 5 月)了解更多基于 Eclipse 工具的信息,这有助于编写 JavaScript。
浏览 技术书店,查找有关本文所述主题和其他技术主题的图书。
在 developerWorks Ajax 资源中心 找到更多有关其他 Ajax 技术(包括 Dojo)的信息。
还可以获得有关 Dojo API 的全部参考资料。
从 Dojo 专区 获得一些优秀的 Dojo 编程示例。
关于作者
在过去六年,Dave Draper 一直担任 WebSphere Application Server Administrative Console 的开发。他是经过 Sun 认证的 Web Component 开发人员,在基于 Web 的工具开发方面具有丰富的经验。
文档选项
打印本页
将此页作为电子邮件发送
英文原文
级别: 中级
Dave Draper, WebSphere Application Server Administrative Console 开发人员, IBM
2008 年 11 月 03 日
Dojo 在基于 Web 的应用程序中越来越受到欢迎。很多开发人员是 Java™ 编程方面的能手,但是在 JavaScript 方面却缺乏经验。从强类型、面向对象的编译语言转向动态的、弱类型脚本语言,开发人员需要经历概念跃迁带来的困难。这种混乱使开发人员很难正确地声明 Dojo 类。本文将帮助梳理这种混乱,解释为何必须设置上下文,以及如何实现它。
简介
如果您是一名只有很少或根本没有 JavaScript 经验的开发人员,在接触 Dojo 时可能需要掌握一些必要的概念。Dojo 的一个主要问题是(在撰写本文之际),它仍然处于其婴儿期(版本 1.0 在 2008 年 2 月份才发布),并且可用的文档仍然非常有限。本文将帮助您理解 Dojo 和 Java 代码之间的联系,使您在开发应用程序时可以快速入手并掌握这个工具箱。
本文并没有介绍如何获得 Dojo 工具箱或一些必要的使用指令,因为已经有大量的资源提供了此类信息。本文主要针对从 servlet 开发转向 Dojo 的 Web 开发人员。
Ajax 资源中心
请访问 Ajax 资源中心,这是有关 Ajax 编程模型信息的一站式中心,包括很多文档、教程、论坛、blog、wiki 和新闻。任何 Ajax 的新信息都能在这里找到。
JavaScript hash
需要面对的主要挑战之一就是理解在调用 Dojo 函数时使用的语法,特别是 “hash” 或 JavaScript 对象。hash 被表示为使用逗号间隔的一组属性,并且使用大括号括起。清单 1 显示了一个简单的例子,它声明了一个包含 6 个属性的 hash:一个字符串、一个整数、一个布尔值、一个未定义的属性、另一个 hash 和一个函数。
清单 1. 示例 JavaScript hash
var myHash = {
str_attr : "foo",
int_attr : 7,
bool_attr : true,
undefined_attr : null,
hash_attr : {},
func_attr : function() {}
};
注意,JavaScript 是弱类型的,因此尽管每个属性被初始化为一个与其名称相关的值,但仍然需要把 str_attr 属性设置为一个整数或布尔值(或其他任何类型)。使用 dot 操作符可以访问或设置 hash 中的每个属性(参见清单 2)。
清单 2. 访问和设置 hash 属性
// Accessing a hash attribute...
console.log(myHash.str_attr);
// Setting a hash attribute...
myHash.str_attr = "bar";
myHash 的前四个属性的含义不言自明。事实上,hash 可以拥有 hash 属性,这并不奇怪。(可以将这看作类似于原语和对象的 Java 类)。这是需要理解的最后一个重要属性。
函数和对象
尽管 Java 代码中有一个 java.reflection.Method 类,但它实际上只充当方法的包装器。在 JavaScript 中,该函数可以是任何可设置、引用和作为参数传递给其他函数的对象。通常,像在 Java 方法调用中声明匿名 inner 类一样,也需要在函数调用中声明新函数。
Java 方法和 JavaScript 函数之间的另一个重要区别是 JavaScript 函数可以运行在不同的上下文中。在 Java 编程中,使用 this 关键字引用所使用类的当前实例。当在 JavaScript 函数中使用时,this 引用该函数运行的上下文。如果没有指定,函数将在定义它的闭包中运行。
在最简单的情况下,闭包可以被看作是使用大括号({})包含的任意 JavaScript 代码。JavaScript 文件内部声明的函数可以使用 this 访问在文件主体中声明的任何变量,但是在 hash 内声明的函数只能使用 this 引用在 hash 内部声明的变量,除非提供其他上下文。
由于经常需要使用封闭的函数作为 Dojo 函数的参数,因此理解如何设置上下文将省去大量的调试工作。
用于指定上下文的主要 Dojo 函数是 dojo.hitch。您可能从不使用 dojo.hitch,但必须了解它是 Dojo 的关键部分,很多函数都在内部调用它。
清单 3 展示了上下文连接的工作原理(其输出显示在图 1 中):
在全局上下文(globalContextVariable)中定义一个变量,在一个 hash 上下文(enclosedVariable)中声明另一个变量。
函数 accessGlobalContext() 可以成功访问 globalContextVariable 并显示其值。
但是,enclosedFunction() 只可以访问其本地变量 enclosedVariable(注意 globalContextVariable 的值显示为 “未定义”)。
使用 dojo.hitch 将 enclosedFunction() 连接到全局上下文,这样就可以显示 globalContextVariable(注意,enclosedVariable 现在为 “未定义”,因为它不是在运行 enclosedFunction() 的上下文中声明的)。
清单 3. 闭包和上下文
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();
图 1. 上下文连接的工作原理
声明类
声明类的技巧
尽管 myClass 是一个有效的名称,但是最好使用完全限定类名的形式声明名称,例如 com.ibm.dojo.myClass。这并不表示应当把类部署到相对路径 “./com/ibm/dojo/” 下的文件系统;它只是减少了与其他类名冲突的几率。
在最后一个属性之后绝不会出现 ,(逗号),因为一些浏览器将忽略它(FireFox),但是其他浏览器(Internet Explorer)会将它弹出。这条规则也适用于 hash 对象的声明。
为什么连接如此重要?您将在声明 Dojo 类或创建自己的部件时体验到它的重要性。Dojo 的一大功能就是能够通过使用 dojo.connect 函数和内置的 pub/sub 模型将对象 “连接” 起来。
类的声明需要三个对象:
一个惟一的类名
用于扩展函数的父类(以及模拟多个继承的 “混合” 类)
定义所有属性和函数的 hash
清单 4 展示了最简单的类声明方式,清单 5 展示了该类的实例化。
清单 4. 基本的类声明
dojo.declare(
"myClass",
null,
{}
);
清单 5. 基本的类实例化
var myClassInstance = new myClass();
如果希望声明一个 “真正的”(即有用的)Dojo 类,那么一定要理解构造函数。在 Java 代码中,您可以通过使用各种不同的签名声明多个重载的构造函数,从而支持实例化。在一个 Dojo 类中,可以声明一个 preamble、一个 constructor 和一个 postscript,但是在大多数情况下,您只需要声明一个构造函数。
除非混合使用了其他类来模拟多个继承,否则不需要用到 preamble,因为它允许您在 constructor 参数传递给扩展类和混合类之前对其进行处理。
postscript 产生了 Dojo 小部件生命周期方法,但对标准 Dojo 类没有什么用处。
不一定要全部都声明,但是要将所有值传递到类的实例中,就必须将 constructor 函数声明为 minimum。如果 constructor 参数将被该类的其他方法访问,必须将它们赋值给已声明的属性。清单 6 展示了一个类,它只将其中一个 constructor 参数赋值给一个类属性,并尝试在另一个方法中引用它们。
清单 6. 赋值构造函数参数
dojo.declare(
"myClass",
null,
{
arg1 : "",
constructor : function(arg1, arg2) {
this.arg1 = arg1;
},
myMethod : function() {
console.log(this.arg1 + "," + this.arg2);
}
}
);
var myClassInstance = new myClass("foo", "bar");
myClassInstance.myMethod();
图 2. 赋值构造函数参数的结果
复杂的属性规则
类属性可以在声明时进行初始化,但是如果使用复杂对象类型(例如 hash 或数组)初始化属性,该属性将类似于 Java 类中的公共静态变量。这意味着任何实例无论在何时更新它,修改将反映到所有其他实例中。为了避免这个问题,应当在构造函数中初始化复杂属性;然而,对于字符串、布尔值等简单属性则不需要这样做。
清单 7. 全局类属性
dojo.declare(
"myClass",
null,
{
globalComplexArg : { val : "foo" },
localComplexArg : null,
constructor : function() {
this.localComplexArg = { val:"bar" };
}
}
);
// Create instances of myClass A and B...
var A = new myClass();
var B = new myClass();
// Output A's attributes...
console.log("A's global val: " + A.globalComplexArg.val);
console.log("A's local val: " + A.localComplexArg.val);
// Update both of A's attributes...
A.globalComplexArg.val = "updatedFoo";
A.localComplexArg.val = "updatedBar";
// Update B's attributes...
console.log("A's global val: " + B.globalComplexArg.val);
console.log("A's local val: " + B.localComplexArg.val);
图 3. 类属性
覆盖方法
超类的方法可以通过使用相同的名称声明属性来扩展。这里和重载无关,因为 JavaScript 将忽略任何意外的参数并使用 null 代替任何缺失的参数。在 Java 代码中,如果要调用被覆盖的方法,就必须在超类上调用该方法(即 super().methodName(arg1, arg1);),但在 Dojo 中,将使用 inherited 方法(this.inherited(arguments);)。清单 8 展示了两个已声明的类,其中 child 扩展了 parent,覆盖了它的 helloWorld 方法,但是调用 inherited 来访问 parent 的函数。
清单 8. 在 Dojo 中调用超类方法
dojo.declare(
"parent",
null,
{
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();
图 4. 在 Dojo 中调用超类方法的输出
设置方法上下文
清单 9 展示了一个实例化后的 Java 类,它将字符串数组中的元素复制到一个字符串 ArrayList。显然,使用清单 10 的代码可以在 Dojo 中提供相同的功能(注意,在构造函数中实例化 targetArray,防止它变成全局性的)。不幸的是,它将导致图 5 所示的错误消息,因为在 dojo.forEach 方法调用中声明的函数创建了一个闭包,该闭包将 this 定义为引用它本身。
清单 9. 在 Java 代码中访问类的作用域变量
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);
}
}
}
清单 10. 在 Dojo 中缺失上下文
dojo.declare(
"myClass",
null,
{
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"]);
图 5. 在 Dojo 中缺失上下文的输出
管 targetArray 并不是在函数包围的上下文中定义的,但是可以将上下文定义为参数传递给 Dojo 函数。这意味着 this 关键字可以访问在该上下文中声明的任何对象(包括函数)。清单 11 显示了正确的实现(注意,增加的代码用粗体表示)。
清单 11. 在 Dojo 中设置正确的上下文
dojo.declare(
"myClass",
null,
{
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);
},
}
);
上下文并不总是作为 Dojo 函数签名中的相同参数传递的:
在 dojo.subscribe 中,上下文是在函数声明之前传递的(参见清单 12)。
在 dojo.connect 中,应该分别提供定义 trigger 方法和 target 方法的上下文。清单 13 展示了一个例子,其中 obj1 定义 methodA 的上下文,而 obj2 定义 methodB 的上下文。对 obj1 调用 methodA 将导致对 obj2 调用 methodB。
清单 12. 在 dojo.subscribe 中设置上下文
dojo.declare(
"myClass",
null,
{
subscribe : function() {
dojo.subscribe("publication",
this,
function(pub) {
this.handlePublication(pub);
});
},
handlePublication : function(pub) {
console.log("Received: " + pub);
}
}
);
清单 13. 在 dojo.connect 中设置上下文
dojo.connect(obj1, "methodA", obj2, "methodB");
结束语
已习惯构化 Java 代码环境的开发人员将很难适应 JavaScript。但是 Dojo 提供了类声明功能,使向客户端开发过渡变得非常简单。充分理解上下文,以及何时、如何设置上下文,将为 Java 开发人员省去很多麻烦,并帮助他们自信地将 JavaScript 添加到自己的工具箱中。
参考资料
您可以参阅本文在 developerWorks 全球网站上的 英文原文。
在 DojoToolkit.org 中可以找到所有入门信息和资源。
通过 developerWorks 文章 JavaScript Development Toolkit 简介(developerWorks,2008 年 5 月)了解更多基于 Eclipse 工具的信息,这有助于编写 JavaScript。
浏览 技术书店,查找有关本文所述主题和其他技术主题的图书。
在 developerWorks Ajax 资源中心 找到更多有关其他 Ajax 技术(包括 Dojo)的信息。
还可以获得有关 Dojo API 的全部参考资料。
从 Dojo 专区 获得一些优秀的 Dojo 编程示例。
关于作者
在过去六年,Dave Draper 一直担任 WebSphere Application Server Administrative Console 的开发。他是经过 Sun 认证的 Web Component 开发人员,在基于 Web 的工具开发方面具有丰富的经验。
发表评论
-
使用 Dojo 开发支持 Accessibility 的 Web 应用
2008-12-18 18:11 1320简介 Accessibility,又经 ... -
掌握 Dojo 工具包,第 5 部分: Dojo 的 UI 组件库 - Dijit
2008-12-18 18:10 2211http://www.ibm.com/developerwor ... -
掌握 Dojo 工具包,第 3 部分: Dojo 事件机制
2008-12-18 18:09 1260DOM 事件模型 事件是用户与浏览器交互的基础,用户在界面的 ... -
掌握 Dojo 工具包,第 2 部分: XHR 框架与 Dojo
2008-12-18 18:08 2220XmlHttpRequest 对象的思考 ... -
掌握 Dojo 工具包,第 1 部分: Dojo 入门简介
2008-12-18 18:07 20252008 年 9 月 18 日 随着 ... -
掌握 Dojo 工具包,第 4 部分: Dojo 中的拖拽
2008-12-18 17:59 1666拖拽,是目前较为常见的 Ajax 技术。当前以 Ajax 技术 ... -
prototype.js 1.4版开发者手册
2008-11-21 17:04 1140Lyn-事繁勿慌,事闲勿荒,取象于取,外圆内方 曲则全,缓应急 ...
相关推荐
很多开发人员是 Java™ 编程方面的能手,但是在 JavaScript 方面却缺乏经验。从强类型、面向对象的编译语言转向动态的、弱类型脚本语言,开发人员需要经历概念跃迁带来的困难。这种混乱使开发人员很难正确地声明 ...
例如,Ajax版和Widget版分别针对不同的应用场景,它们的`dojo.js`文件包含不同的模块集合。用户可以根据项目需求选择适合的版本。 为了获取Dojo的最新源代码,你需要安装Subversion(SVN)。通过以下命令,你可以从...
5. **性能优化**:讨论如何针对Dojo应用程序进行性能调优。 总之,Dojo Toolkit是一个功能强大且易于使用的Web开发框架,它不仅提供了丰富的功能库,还拥有活跃的开发者社区作为支持,非常适合用于构建现代化的Web...
这一阶段的目标是建立起软件开发的基本思维,能够正确配置Java开发环境,并熟练使用基本软件。 2. **面向对象编程**:进一步学习Java类的编码,理解封装、继承和多态等面向对象设计方法,巩固面向对象的概念和编程...
Jetty Dojo 是一个针对Jetty服务器的工具集,它主要设计用于开发和测试Web应用程序。Jetty是一款轻量级的开源HTTP服务器和Servlet容器,它以其高效、灵活和易于集成的特点,在Java社区中广受欢迎。Tomcat则是另一个...
- 针对基于Dojo的Web应用的安全性问题进行讨论 - 探讨如何保护Web应用免受常见的网络攻击 #### 6. **国际化与本地化支持** - 如何为Dojo应用添加多语言支持 - 最佳的国际化与本地化策略 综上所述,《Practical ...
#### 一、Dojo基本概念 Dojo是一个强大的JavaScript库,旨在简化复杂的Web应用程序开发过程。它由三个主要部分组成:`dojo`、`dijit`和`dojox`。 1. **Dojo基础**: - **概述**:Dojo的核心库提供了构建其他功能...
### DOJO-API中文参考手册附加注解实例:深入解析Dojo框架的核心概念与应用 Dojo框架,作为一款先进的开源JavaScript库,旨在简化富互联网应用(RIA)的开发过程,尤其在处理复杂的用户界面和跨浏览器兼容性问题上...
Schutta和Ryan Asleson撰写,是针对Java开发者深入了解和应用Ajax技术的权威指南。Ajax(Asynchronous JavaScript and XML)是一种用于创建快速动态网页的技术,它使用JavaScript、XMLHttpRequest以及其他标准如CSS...
IBM JAVA培训计划是一项专门针对JAVA技术的高级培训方案,旨在通过一系列完整的项目实践和技术课程学习,帮助学员在短时间内掌握JAVA项目的开发和设计技能。整个培训周期约为4个月,共计650个课时,主要通过以下三个...
Eclipse是Java开发者常用的IDE,而MyEclipse则是其针对企业级Java应用的扩展,支持Web开发,包括AJAX。 文件"ajax.sql"可能是数据库脚本文件,用于创建或填充数据库表。在Ajax应用中,通常会有一个后端服务器,负责...
- **李刚**:拥有近10年的Java EE应用开发经验。曾任LITEON公司的J2EE技术主管,负责企业信息平台的架构设计。在广州电信、广东龙泉科技等公司担任过技术培训导师。2007年3月26日被《电脑报》专访。创立了疯狂Java实...
Struts 2是Java Web开发中的一个非常重要的框架,它基于Model-View-Controller(MVC)设计模式,为开发者提供了构建可维护性高、结构清晰的Web应用程序的工具。Struts 2的2.3.16.3版本是最新的稳定版本之一,此版本...
《深入浅出Struts 2》是一本针对Java Web开发框架Struts 2的专业指南,旨在帮助开发者深入了解和熟练运用这一强大的MVC框架。Struts 2是Apache软件基金会下的一个开源项目,它继承了Struts 1的优点,并且吸取了其他...
7. **Ch13 - Ajax框架与库**:介绍了流行的Ajax库如Prototype、jQuery、Dojo等,以及如何利用它们简化Ajax开发,提高开发效率。 8. **Ch15 - JSON与Ajax**:这一章可能详细讨论了JSON作为数据交换格式在Ajax中的...
这个“Struts2_张冰_视频教程课件_PPT”资源是专门针对Struts2框架的学习资料,由知名讲师张冰制作,旨在帮助学习者深入理解并掌握Struts2的核心概念和技术。 首先,我们来探讨一下Struts2框架的基础知识。Struts2...
8. **struts2-java8-time-plugin.jar**:针对Java 8引入的新时间日期API,此插件提供了对这些API的支持,便于在Struts2中进行日期和时间的处理。 9. **struts2-plugins.jar**:这是一个包含所有可用Struts2插件的...
Struts2是Apache软件基金会开发的一个开源MVC框架,它基于Model-View-Controller(模型-视图-控制器)架构模式,旨在简化Java Web应用程序的开发。《Struts2权威指南》这本书是深入理解并掌握Struts2框架的重要参考...