|
锁定老贴子 主题:Spry框架初步入门
该帖已经被评为良好帖
|
|
|---|---|
| 作者 | 正文 |
|
最后更新时间:2006-12-18
Adobe的Ajax框架spry的正式版还没放出,所以文档是少之又少,在这里接合自己使用的情况总结20个spry的知识点给大家,相信会对大家有一定帮助,至少大家也会对spry有个初步的认识了,这个轻量型的框架就一个字:“易用”。
1,使用spry框架,必须引用的两个核心js文件 <script type="text/javascript" src="../../includes/xpath.js"></script> <script type="text/javascript" src="../../includes/SpryData.js"></script> 2,创建一个数据器dataset
var dsPhotos = new Spry.Data.XMLDataSet("/photos.php", "/gallery/photos/photo", { method: "POST", postData: "galleryid=2000&offset=20&limit=10", headers: { "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" } });
var dsPhotos2 = new Spry.Data.XMLDataSet("/photos.php?galleryid=2000", "/gallery/photos/photo");
method:为请求发送方式,POST / GET ;默认为GET postData:为请求参数,可省略,可直接把"/photos.php"换成/photos.php?galleryid=2000&offset=20&limit=10 Content-Type:为头信息 3,不使用缓存
Var dsPhotos = new Spry.Data.XMLDataSet("/photos.php?galleryid=2000", "/gallery/photos/photo", { useCache: false })
这里要重点说明一下,我在应用时,曾经发现设置不用缓存时,页面仍然不是最新数据,我是用一个servlet生成xml,然后对生成的数据进行删除和添加,但页面显示的数据不会自动更新。 后来在adobe的官方论坛上找到了答案,在IE中,使用userCache:false是不够的,还要在生成xml的jsp,php等中设置头不使用cache,如在生成xml的jsp/servlet中是要加上: response.addHeader("Cache-Control","no-cache"); 以上问题只存在IE中,在firefox和opera中不存在。注,spry对opera9版本支持很好,使用版本8的朋友要注意了。 另外,也可以在构造完数据器后,再设置缓存: dsData.useCache = false; dsData.loadData(); 4,获取数据形式 假如我们上面的请求,返回的xml如下:
<gallery id="12345">
<photographer id="4532">John Doe</photographer>
<email>john@doe.com</email>
<photos id="2000">
<photo path="sun.jpg" width="16" height="16" />
<photo path="tree.jpg" width="16" height="16" />
<photo path="surf.jpg" width="16" height="16" />
</photos>
</gallery>
那么“gallery/photos/photo”返回的数据是下面的数组: [ { "@path": "sun.jpg", "@width": 16, "@height": 16 }, { "@path": "tree.jpg", "@width": 16, "@height": 16 }, { "@path": "surf.jpg", "@width": 16, "@height": 16 } ] var rows = dsPhotos.getData(); // 获取所有行. var path = rows[0]["@path"]; // 获取第一行中"@path"的值 dsPhotos.setCurrentRowNumber(2); // 将第3行做为当前处理行,下标以0开始 var id = dsPhotos.getData()[2]["ds_RowID"]; // 获取第3行的ID. dsPhotos.setCurrentRow(id); // 通过第3行的id,将第3行设为当前处理行. 5,排序
dsPhotos.sort("@path"); //以"@path"列的值为关健字对行排序
dsPhotos.sort("@path", "toggle"); //"ascending", "descending"和"toggle",默认是 "ascending"。
var dsPhotos = new Spry.Data.XMLDataSet("/photos.php?galleryid=2000", "/gallery/photos/photo", { sortOnLoad: "@path", sortOrderOnLoad: "descending" });//也可在数据构造器中设置初始排序
dsPhotos.setColumnType("@width", "number");//设置类型
dsPhotos.setColumnType("@height", "number");
...
dsPhotos.sort("@width"); // 对 "@width" 列数据进行排序.
6,去除重复
dsPhotos.distinct(); // Remove all duplicate rows.
//distinct()方法是具有破坏性的,多余的行是被删掉的,如果你想再得到所有的包括重复的原始项就得重新载入XML数据。
var dsPhotos = new Spry.Data.XMLDataSet("/photos.php?galleryid=2000", "/gallery/photos/photo", { distinctOnLoad: true });//可在构造时预设
7,设置过滤器
var myFilterFunc = function(dataSet, row, rowNumber)
{
if (row["@path"].search(/^s/) != -1) //只返回以s开头的行
return row; // Return the row to keep it in the data set.
return null; // Return null to remove the row from the data set.
}
dsPhotos.filterData(myFilterFunc); // Filter the rows in the data set.
dsPhotos.filter(myFilterFunc); // 不破坏数据,是建一个新的数组
dsPhotos.filterData(null); // 取消过滤.
8,自动刷新,以毫秒为单位
var dsPhotos = new Spry.Data.XMLDataSet("/photos.php?galleryid=2000", "/gallery/photos/photo", { useCache: false, loadInterval: 10000 });//在构造器设置
dsPhotos.startLoadInterval(10000); // 设置自动刷新
...
dsPhotos.stopLoadInterval(); // 停止自动刷新
9,把类注册成观察器
var myObserver = new Object;
myObserver.onDataChanged = function(dataSet, data) //可支持:onPreLoad / onPostLoad / onLoadError / onDataChanged / onPreSort / onPostSort / onCurrentRowChanged
//第一个是发送通知的对象,做为数据器观察器,这个值永远都是dataSet对象。第二个参数可以不定义,也可以是一个对象(内置对象)
{
alert("onDataChanged called!";
};
dsPhotos.addObserver(myObserver);
dsPhotos.removeObserver(myObserver);
10,把函数方法注册为观察器
function myObserverFunc(notificationType, dataSet, data) //notfication,是通知器类型,dataSet是数据器对象,data是要观察的数据
{
if (notificationType == "onDataChanged")
alert("onDataChanged called!";
else if (notificationType == "onPostSort")
alert("onPostSort called!";
};
dsPhotos.addObserver(myObserverFunc);
11,动态区域块 所有使用Spry动态区域块的HTML页面都要在它们的<html>标签中加入xmlns:spry=http://ns.adobe.com/spry
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:spry="http://ns.adobe.com/spry">
.... ....
.... ....
<ul spry:region="dsPhotos">
<li>{dsPhotos::path}</li>
</ul>
COL, COLGROUP, FRAMESET, HTML, IFRAME, STYLE, TABLE, TBODY, TFOOT, THEAD, TITLE, TR 不能设为动态区域 12,数据引用 {<数据器名>::<数据器列名>} 如果一个动态区域块只和一个数据器相关联,则你甚至可以省略掉数据器的名字 <li>{@path}</li> ds_RowID - 这是数据器的行id。这个id可以帮我们指定数据器中的一个数据。它和数据是对应的,即使数据执行了排序操作,这个id和数据的对应关系也不会变化。 ds_RowNumber - 这是数据器当前数据的行号。 ds_RowNumberPlus1 - 这个与上面的ds_RowNumber相同,只不过它规定了数据的行号从1开始,而不是从0开始。 ds_RowCount - 它是数据器中数据的行的数量。如果使用了一个非破坏性的过滤器,则它的值是这个过滤器执行后得到的行的数量。 ds_UnfilteredRowCount - 在执行非破坏性过滤器前,数据器中行的数量。 ds_CurrentRowID - 当前行的id。这个值不会改变,除非使用了一个循环的构造。 ds_CurrentRowNumber - 当前行的行号。这个值不会改变,除非使用了一个循环的构造。 ds_SortColumn - 上一次排序所依赖的列名。如果这个数据器的数据还未进行过排序,则返回一个空字符串。 ds_SortOrder - 数据器中数据排序的参数,将返回三种字符串"ascending", "descending", 或空字符串.。 ds_EvenOddRow - 它返回的是"even"或"odd",告诉我们ds_RowNumber的值是奇数还是偶数。 13,循环
//方式一:
<li spry:repeat="dsPhotos">{@path}</li>
//方式二:
<ul spry:repeatchildren="dsPhotos">
<li>{@path}</li>
</ul>
//只输出以s开头的 spry:test属性的值可以是任何等于0或非0值的JavaScript表达示。如果这个表达示返回非0值,这个内容将会被输出,相当于if <>0就输出后面元素。
<li spry:repeat="dsPhotos" spry:test="'{@path}'.search(/^s/) != -1;">{@path}</li>
14,if 条件
<li spry:if="'{@path}'.search(/^s/) != -1;">{@path}</li>
//if/else的形式,要使用"spry:choose"属性
<div spry:choose="spry:choose">
<div spry:when="'{@path}' == 'surf.gif'">{@path}</div>
<div spry:when="'{@path}' == 'undefined'">Path was not defined.</div>
<div spry:default="spry:default">Unexpected value for path!</div>
</div>
15,状态
<div spry:region="dsEmployees">
<div spry:state="loading">正在载入数据 ...</div>
<div spry:state="error">数据载入失败!</div>
<ul spry:state="ready">
<li spry:repeat="dsEmployees">{firstname} {lastname}</li>
</ul>
</div>
16,通过对象将区域注册成观察者
myObserver = new Object;
myObserver.onPostUpdate = function(notifier, data)
{
alert("onPostUpdate called for " + data.regionID);
};
...
// 调用addObserver() 将类注册为观察者.
Spry.Data.Region.addObserver("employeeListRegion", myObserver);
...
//注销
Spry.Data.Region.removeObserver("employeeListRegion", myObserver);
...
<ul id="employeeListRegion" spry:region="dsEmployees">
...
</ul>
17,以函数将区域注册成观察者
function myRegionCallback(notificationState, notifier, data)
{
if (notificationType == "onPreUpdate") //onLoadingData / onPreUpdate / onPostUpdate / onError
alert(regionID + " is starting an update!");
else if (notificationType == "onPostUpdate")
alert(regionID + " is done updating!");
}
...
// 注册
Spry.Data.Region.addObserver("employeeListRegion", MyRegionCallback);
...
// 注销
Spry.Data.Region.removeObserver("employeeListRegion", MyRegionCallback);
...
<ul id="employeeListRegion" spry:region="dsEmployees">
...
</ul>
18,主细节模式,同一数据器
<span spry:region="dsEmployees">
<select spry:repeatchildren="dsEmployees" onchange="dsEmployees.setCurrentRow(this.value)">
<option spry:if="{ds_RowNumber} == 0" value="{ds_RowID}" selected="selected">{username}</option>
<option spry:if="{ds_RowNumber} != 0" value="{ds_RowID}">{username}</option>
</select>
</span>
<span spry:detailregion="dsEmployees">{@id} - {firstname} {lastname} - {phone} </span>
//spry:detailregion"会在接收到"CurrentRowChanged"通知后改变自己的展示形式。
19,主细节模式,多个数据器
var dsStates = new Spry.Data.XMLDataSet("../../data/states/states.xml", "states/state");
var dsCities = new Spry.Data.XMLDataSet("../../data/states/{dsStates::url}", "state/cities/city");
//两个数据器有依赖关系,也可以用:"/webapp/cities.php?stateid={dsStates::@id}".
<form name="selectForm">
//State:
<span spry:region="dsStates" id="stateSelector">
<select spry:repeatchildren="dsStates" name="stateSelect" onchange="document.forms[0].citySelect.disabled = true; dsStates.setCurrentRow(this.value);">
<option spry:if="{ds_RowNumber} == 0" value="{ds_RowID}" selected="selected">{name}</option>
<option spry:if="{ds_RowNumber} != 0" value="{ds_RowID}">{name}</option>
</select>
</span>
//City:
<span spry:region="dsCities" id="citySelector">
<select spry:repeatchildren="dsCities" name="citySelect">
<option spry:if="{ds_RowNumber} == 0" value="{name}" selected="selected">{name}</option>
<option spry:if="{ds_RowNumber} != 0" value="{name}">{name}</option>
</select>
</span>
</form>
20,改变数据源
<select onchange="dsEmployees.setURL(this.value); dsEmployees.loadData();">
<option value="../../data/employees-01.xml" selected>Set 1</option>
<option value="../../data/employees-02.xml">Set 2</option>
</select>
<th scope="col" onclick="dsEmployees.sort('@id');">Employee ID </th>
声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
|
|
| 返回顶楼 | |
|
最后更新时间:2006-12-05
精彩.
这里有demo可以看:http://labs.adobe.com/technologies/spry/demos/index.html |
|
| 返回顶楼 | |
|
最后更新时间:2006-12-05
太酷了!早想找这样的东西。
看了几个DEMO,原来要在服务端编写很多代码来生成界面,被它这么轻松就搞定了,竟然是在浏览器上生成,服务端压力也少了很多。 看起来和Rails也是绝配,有空得把现有的VIEW代码重新编写,这个看起来太诱人了。RJS虽然方便,但对于相同数据格式的不同显示界面来说,还是有不少缺陷的,最主要的问题是服务器端得知道需要更新当前界面上哪些元素,每次修改界面都要处理这2个部分,而且会有不少冗余代码。 |
|
| 返回顶楼 | |
|
最后更新时间:2006-12-05
|
|
| 返回顶楼 | |
|
最后更新时间:2006-12-05
这东西要钱吗?
|
|
| 返回顶楼 | |
|
最后更新时间:2006-12-06
日新月异,B/S应用模式的革命快到了。
|
|
| 返回顶楼 | |
|
最后更新时间:2006-12-08
执行效率是比较大的问题~
|
|
| 返回顶楼 | |
|
最后更新时间:2006-12-08
skyblue1984 写道 执行效率是比较大的问题~
没有用Spry做过项目,也不知道速度怎样. skyblue1984比较清楚的话,贴出一些测试的数据,看一下spry的执行效率怎样也可以啊 |
|
| 返回顶楼 | |
|
最后更新时间:2006-12-11
今天做一个查询.显示查询的结果.如果没有数据显示一个提示.
怎么判断我的数据集是空 我想这样写不行 <tr> <TD colspan="9"> <div spry:if="dsMonthBudget==''">没有数据!</div> </TD> </tr> .请. |
|
| 返回顶楼 | |
|
最后更新时间:2006-12-12
呵呵 收藏!
|
|
| 返回顶楼 | |













