Home >Web Front-end >JS Tutorial >I found a little bit of information about dojo, thank you author! _javascript skills
介绍:
这里将给你对于dojo的启蒙课程。你可能会跟自己说"这段可以跳过了,因为我已经很了解javascript并且对网站开发很了解了。“不过这里有个机会让你认识到其实你的知识并不是那么扎实,还有很多基础的东西需要学习。
当 我们给人们介绍dojo的时候,遇到了两种难题。有些用户已经使用DHTML很久,并且对javascript有了很深的理解,他们清楚 javascript能作什么,不能做什么,在脑海里存在定型思维,有些时候,更难让这些人明白dojo。第二种难题就是对于那些新手,他们太缺乏经验和 对javascript的了解了。
我鼓励这两种朋友都读一下介绍内容,甚至你可以不全看。
什么是Dojo?
其实总结Dojo到底是什么是非常困难的。我说总结Dojo是很困难的,是因为Dojo是一个可扩展的代码集合 (expandable collection of code)。扩展不只是来自于众多开发者,并且你会发现你可以根据你自己的需要扩展自己的一套东西。就是说,你把目光放在Dojo身上的原因是因为 Dojo可以和javascript取长补短。
在开发客户端(client-side development)总共有3个主要部分:events,重复使用DHTML blocks,客户端和服务器传递信息。Dojo在这三方面都很在行,并且使他们变的很容易。
历史
译者注:历史我是真不想翻译了,如果有人很感兴趣的话,可以给我留言,我有时间会翻译的。
。。。。。。。。。。。。
什么是工具(Toolkit)?
很多人认为结构(framework),库(library),工具是同一个意思。但是弄清楚它们之间的区别,对于以后的理解很有帮助。
Framework
在软件开发中,为了让其他的项目可以分享和合作,通常定义一个结构(framework)。一个结构通常包含支持程序(support programs),库和一个脚本程序。你可能认识到Dojo就是framework的一个部分,但并不是framework的本身。
Library
库文件定义了很多可以引用的方法(function),它们是在任何位置都可以运行的,并不是我们平常自己在程序中定义的方法。看了这些,你可能会说“嘿!dojo就是库的集合!”。你应该是对的,但是,dojo比一个库的集合要包含得多很多。
Toolkit
看 过前文,你可能还在琢磨到底dojo是作什么的。很明显,他不是一个结构(framework),它是一个工具(toolkit)或者是一个库?最后让我 来解答一下,通常库都是之前定义好的,你可以引用到你的程序中并使用它们,但是在dojo中,我们在这个库外面加了一层封包系统。这样就使它跟一般的库有 些不一样。
在这个系统中,我们把库分成很多部分。有核心方法(core functions),还有很多其他不常用的子库(sub library)。这就使你使用dojo的时候感觉它很简洁。下面会有更具体的分析,会让你更加明白dojo。
Dojo会给你什么
曾经,Netscape盛行一时,大部分人都在使用,所以当时Netscape给出了一个网站制作的标准。好景不长,后来出现了微软的IE,IE当时强过Netscape,成为了新的标准。但是这个标准跟W3C有一定的差别,所以在人们制作网站时,开始向IE新标准靠拢。
很多年过去了,IE依旧不败,而且并没有更新很多。一样多的bug,缺少标准化。慢慢的网虫们开始使用firefox,opera,safari,它们为了跟上W3C的标准,所以更新得很快。
很多同样的功能,但是对于不同的浏览器需要写不同的代码,这对我们来说意味着什么?意味着我们要做出一个完美的网站是很苦难的。这时一个程序员会去做什么呢?
知识补充
如果光使用静态html制作网站,当然不会出现上面的问题,但是这也意味这网站不可能具有交互性,最多的也只是提供一个表单(form)让用户提交,然后再返回一个新的页面显示数据。
Javascript的出现正是为了解决这些难题。
解决所有问题
Dojo不仅是存在于抽象层,并且也是独立存在的。不只是提供一些库,一些方法,一些功能,而且让的代码更加简洁,保证你的代码只包含所需要的部分。
Dojo会让你的生活更加简单,因为他替你链接了很多东西,把你的复杂项目分成一些小问题,让你的代码更简洁,更有效率,并且可以更好的重复使用。
第一章:开始使用Dojo
Dojo有很多版本,你可以一下子不知道该选择哪个,这里可以让你放心,无论你使用的是什么版本,本书中的例子你都可以运行。
下载Dojo
(译者注:这个是我使用的版本,zip文件,你也可以自己到Dojoa主页进行下载。)
Dojo模块(Modules)
Dojo的库定义使用了模块,就像JAVA一样。这样可以让你只引用自己需要的部分,而不是全部,保证了浏览速度。
例如Dojo的event包定义在模块dojo.event中。
(译者注:此部分原著甚是啰嗦,我给精简了一下,有兴趣的朋友可以参见原文。)
引用模块格式:
dojo.require("dojo.module[.sub module]");
例如我们想引用lite effects systems,
dojo.require("dojo.lfx");
这会引入所有lfx下的子模块,当然你也可以使用dojo.lfx.*,如果想单独引用lfx下的toggle模块:
dojo.require("dojo.lfx.toggle");
Widgets
什么是widget呢?一个按钮 ,一个图片,这都是widget,最常见的html widget有链接,按钮,输入框。
使用Dojo可以改变widget ,例如在日期输入框旁边加上一个彩色日历,让用户可以选择日期,与此同时Dojo并不会破坏你原始的输入框,因为Dojo是扩展了你的html而不是替换了它。
使用widget的优势主要三点:
跨平台:使用Dojo widget,无论使用任何浏览器,都会准确的得到正确效果。
自动退化:一些老浏览器可能对javascript支持并不是那么完美,Dojo也可以让它们显示出正确的内容,例如前面彩色日历的例子,如果浏览器不支持,那么Dojo会自动将日历退化到一个简单的选择框,或者其他(根据不同widget而定)。
扩展性:你可以利用Dojo提供的widget创造出新的widget,在这个过程中你并不需要从库中复制任何代码或者修改库中的代码。
如何使用Widget
Widget有很多使用方法。Widget会搜索整个网页框架,然后自动把应该添加的内容加入到当中。
下面是个简单的例子,我们也可以看出WIdget是怎样自动退化的,因为我们并没有给ComboBox定义选择项,而只是一个value,而且所以最后显示出来的只象是一个简单的inputbox,如果用户禁用了javascript,显示结果也会一样。
但是如果我们只想使用W3C标准(译者注:没有那些额外的tag,例如dojoType),我们可以用下面的方法。
你可能注意到了dataUrl,他的作用是把comboBoxData.js中的内容加到comboBox中,但是现在comboBoxData.js中没用任何内容。(译者注:当然你可以随意改变dataUrl的内容,名字不是固定的。)
下面是一个select的例子:
从上面的例子中,你知道了很多事情,但却好像没什么用处,这里只是想告诉你其实dojo并没有那么复杂。
后退和前进
动态网页程序(dynamic web application)避免了频繁的刷新页面,不过通常也带来后退和前进按钮会失去作用。更多的,有的时候,用户可能很难把网页加入收藏夹。
Dojo提供了一个解决办法,让网页程序处理浏览器的后退和前进,并且提供给浏览器一个唯一的地址。这个解决办法就是使用dojo.undo.browser。
使用dojo.undo.browser
在dojo 0.2.2版本中,并没有dojo.undo.browser,这是在0.3以后的版本中才加入的。
首先,需要使用dojo.undo.browser.setInitialStae(state)设定当浏览器第一次载入网页的状态。
理论
动 态网页程序会调用XMLHTTPRequest和DOM来更新网页内容而避免了刷新,更新浏览历史,并且也不会改变浏览器的地址栏。这就意味着当用户点击 了后退按钮,整个网页程序丢失了当前运行的状态(state)。而且即使用户想把当前的网页内容加入收藏夹,也是不可能的,因为收藏夹不会记录网页程序运 行的状态,而只会简单的记录下网页程序的地址(URL)。
开发者可以使用dojo.undo.browser包得到用户点击后退和前进的事件(event),然后根据这些事件来更新页面内容。 dojo.undo.browser通过使用一个隐藏的表单(hidden IFRAME)或者一个唯一的标签(fragment identifier)传递浏览的历史记录。(译者注:可以想像成一个cookie或者一个session,但是这个session信息是存储在hidden IFRAME或者标签中) 例如:
http://some.domain.com/my/path/to/page.html#fragmentIdentifier
(译者注:#fragmentIdentifier就是标签记录)
因为当改变标签的时候并不会使网页刷新,所以非常适合记录当前网页程序的状态。当然开发者可以自定义一个更容易读懂的标签,并且使用户可以把它加入收藏夹。
dojo.undo.browser允许开发者创建一个相对于运行状态的对象(state object),这个对象会得到回叫(callback)当用户点击后退或者前进按钮。
开发
下面是使用dojo.undo.browser之前必须作的一些事情:
1:在djConfig中设置preventBackButtonFix: false。这样保证了隐藏的表单(hidden IFRAME)将会添加到页面当中,如果不加入这段,dojo.undo.browser不会正常工作。
译者注:设置方法就是在header中加入如下代码:
2: 加入dojo.require("dojo.undo.browser");
设定网页程序的初始状态:
dojo.undo.browser.setInitialState(state);
当用户每次点击前进或者后退,state对象都会被调用。
然后我们需要给state对象创建几个方法(function)
得到后退提示:back(),backButtion()或者handle(type),type可以是“back”或者是“forward”。
得到前进提示:forward(),forwardButton()或者handle(type),type如上。
下面是个简单的例子:
var state = {
back: function() { alert("Back was clicked!"); },
forward: function() { alert("Forward was clicked!"); }
};
注册一个state对象使用下面的方法:
dojo.undo.browser.addToHistory(state);
如 果向改变浏览器的地址(URL),引用state对象的changeUrl属性。如果changeUrl是true,dojo.undo.browser 就将产生一个唯一的标签,如果changeUrl被定义为任何其他的值(不包括undefined,null,0和空string),那么这个值就会被使 用为标签。这样用户就可以把当前页加入收藏夹了。
提示
如果你要使用changeUrl,即使你不设定自己的标签,也至少定义为true。
如果你要在本机测试,不要使用IE。因为当IE访问本地文件时不会创建历史列表ifram_history.html。请把网页上传到服务器上测试。
Safari2.0.3+:只有后退按钮可以正常工作,并且只有当changeUrl没用使用的时候。
Opera 8.5.3:不会正常运行。
这里有一个网上的例子:
http://archive.dojotoolkit.org/nightly/tests/undo/test_browser.html
发布Dojo
译者注:此部分的英文版还没有完成,所以暂不翻译了,以后一定会补上。
6月27日更新:
I/O
dojo.io.blind介绍
在我们制作dojo的时候,目的是让用户和开发者都能享受到DHTML程序。在很多朋友的支持下,特别是Aaron Boodman和Mark Anderson,我们已经找到了解决可用性的方法。我们提供了一个单独的易用的API和一个包装类,这个类只需要两个文件。dojo.io包提供了对XMLHTTP和一些其他更复杂的传输结构的支持。
在dojo.io 包中我们一般最常使用的是dojo.io.bind()方法。dojo.io.blind()是一个标准的异步的请求API,它包含了各种传输层 (transport layers),包括queues of iFrames,XMLHTTP,mod_pubsub,LivePage等等。Dojo会试图为当前的请求选择最合适的传输方法,因为在做网站时一般不 会使用到其他传输,所以我们只用到XMLHTTP。dojo接受一个匿名的类,但是在知道这个类的属性的情况下,把它作为方法参数(function argument)。下面的代码是创建一个请求(request),这个请求会从URL返回原始的字符串。
dojo.io.bind({
url: " http://foo.bar.com/sampleData.txt " ,
load: function (type, data, evt){ /* do something w/ the data */ },
mimetype: " text/plain "
});
这就是全部,你提供了一个数据地址,还有一个当你得到返回值时要执行的function。但是如果在请求过程中出错了怎么办呢?我们再来创建一个register来解决:
dojo.io.bind({
url: "http://foo.bar.com/sampleData.txt",
load: function(type, data, evt){ /*do something w/ the data */ },
error: function(type, error){ /*do something w/ the error*/ },
mimetype: "text/plain"
});
同样也可以只创建一个单独的handler来解决:
dojo.io.bind({
url: "http://foo.bar.com/sampleData.txt",
handle: function(type, data, evt){
if(type == "load"){
// do something with the data object
}else if(type == "error"){
// here, "data" is our error object
// respond to the error here
}else{
// other types of events might get passed, handle them here
}
},
mimetype: "text/plain"
});
下面的代码提交一段javascript程序段,然后让服务器运行它,一般我们这么做是为了加速程序运行,注意mimetype:
dojo.io.bind({
url: "http://foo.bar.com/sampleData.js",
load: function(type, evaldObj){ /* do something */ },
mimetype: "text/javascript"
});
如果你想确保程序使用XMLHTTP,可以这样写:
dojo.io.bind({
url: "http://foo.bar.com/sampleData.js",
load: function(type, evaldObj){ /* do something */ },
mimetype: "text/plain", // get plain text, don't eval()
transport: "XMLHTTPTransport"
});
Being a jack-of-all-trades, bind() also supports the submission of forms via a request (with the single caveat that it won't do file upload over XMLHTTP):
作为一个jack-of-all-trades(万事通),bind()同样支持来自于表单提交的数据。
dojo.io.bind({
url: "http://foo.bar.com/processForm.cgi",
load: function(type, evaldObj){ /* do something */ },
formNode: document.getElementById("formToSubmit")
});
以上只是一些最基本的,其实这些可以不用全部由开发者自定义。
RPC
你可以看到,Dojo通过dojo.io.bind提供了简单,强大的方法使用多种多样的I/O functions。但是在开发过程中,程序员会调用很多很多I/O,这同时会给服务器和客户端加重负担。Dojo的RPC服务就是为了减少负担,易用,精简代码而生的。
RPC 的全名是Remote Procedre Calls,或者Remote Method Invocation,(译者:远程method调用)。最基本的,RPC允许开发者调用在远程服务器上的方法(method)。Dojo不仅提供了基本 的RPC client包,而且还扩展了它,使它支持JSON-RPC服务和YAHOO服务。同时你也可以自己写出相对于其他服务的类。
我们假定有一个需要调用服务器端程序的小程序,假设要调用add(x,y)和subtract(x,y)。在没有特殊情况的条件下,我们的客户端会这样写:
add = function(x,y) {
request = {x: x, y: y};
dojo.io.bind({
url: "add.php",
load: onAddResults,
mimetype: "text/plain",
content: request
});
}
subtract = function(x,y) {
request = {x: x, y: y};
dojo.io.bind({
url: "subract",
load: onSubtractResults,
mimetype: "text/plain"
content: request
});
}
Look, it’s not that hard. But whether we let the server run add and subtract or let the client calculate it itself, this is just a very simple program. What if we want to call 30 different methods on the server? I guess we might have to write almost the same code over and over again, each time creating a request object, setting the URL, setting variables, etc. Not only is this error-prone, it's also tedious.
Dojo's RPC client simplifies this process:
{
"serviceType": "JSON-RPC",
"serviceURL": "rpcProcessor.php",
"methods": [
{
"name": "add",
"parameters":[
{"name": "x"},
{"name": "}
: "x"},
": "y"}
]
}
The above is the definition of server. Once the definition is created, other things are simple. We can also create a class:
var myObject = new dojo.rpc.JsonService?(defintion);
To use the server method:
I bet you're thinking "I don't just call the method, I also get the result of the calculation." You're right, but it's also very easy. MyObject.add() on the server side will return a deferred object. Twisted Python users may be familiar with deferred objects, which allow developers to attach one or more callbacks and errbacks depending on the type of data returned. Here is a simple example:
myDeferred.addCallback(myCallbackMethod);
We add mycallbackmethod as a callback to our deferred class mydeferred. At this time, 8 will be passed into mycallbackmethod. On the other hand, we can also add an errback method to handle the error message returned by the server. We can add as many callbacks as we want, and they will be called in the order we define.
Reprinted from
http://www.blogjava.net/burnet
Original address
http://www.blogjava.net/burnet/articles/54186.html