首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

从 XML 生成可与 Ajax 共同使用的 JSON(3)

从 XML 生成可与 Ajax 共同使用的 JSON(3)

细化函数调用技术我很喜欢函数调用这一技术,但我并不赞同将所有图书数据都放入一个块中。另一种方式是为每条记录采用一个调用,如  所示。
清单 10. Function2.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
AddBook( {
id: 1,
name: 'Code Generation in Action',
first: 'Jack',
last: 'Herrington',
publisher: 'Manning'
}  );
AddBook( {
id: 2,
name: 'PHP Hacks',
first: 'Jack',
last: 'Herrington',
publisher: 'O\'Reilly'
}  );
...




对 .html 页面只需做少许修改,如  所示。
清单 11. Function2.html
1
2
3
4
5
6
...
<script>
var g_books = [];
function AddBook( book ) { g_books.push( book ); }
</script>
...




这里更改了 XSLT,以使函数调用驻留在 for-each 循环体内。                        显示了更新后的样式表。
清单 12. function2.xsl
1
2
3
4
5
6
7
8
9
10
11
12
...
<xsl:template match="/">
<xsl:for-each select="books/book">
AddBook( {
id: <xsl:value-of select="@id" />,
name: '<xsl:value-of select="js:escape(title)" />',
first: '<xsl:value-of select="js:escape(author/first)" />',
last: '<xsl:value-of select="js:escape(author/last)" />',
publisher: '<xsl:value-of select="js:escape( publisher )" />'
}  );</xsl:for-each>
</xsl:template>
...




对这个给定示例来说,这种更改看起来有些随意。但如果原始的 XML 数据集有多种数据类型,要为每种类型分配一个单独的函数调用会使 XSL 和页面上的 JavaScript 代码更为简单、更易于维护。
编码对象对小的页面来讲,使用 JavaScript 函数没有问题。但对于大型项目,就需要使用 JavaScript 语言的一些面向对象特性。是的,JavaScript 语言可以处理对象而且可以处理得很好。
显示了如何创建带有数据的对象。
清单 13. Object1.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
g_books.push( new Book( {
id: 1,
name: 'Code Generation in Action',
first: 'Jack',
last: 'Herrington',
publisher: 'Manning'
}  ) );
g_books.push( new Book( {
id: 2,
name: 'PHP Hacks',
first: 'Jack',
last: 'Herrington',
publisher: 'O\'Reilly'
}  ) );




在本例中,我只简单地向名为 g_books 的数组添加了 Book 对象。JavaScript 的对象创建与 Java™、C# 或 C++                        编程语言的对象创建十分相似。都是一个 new 操作符后跟一个类名。参数放到随后的括号内。在本例中,我传入了一个带值的单一散列表,并将其分割成单独的一些参数。
创建此对象的代码如  所示。
清单 14. Object1.xsl
1
2
3
4
5
6
7
8
9
10
<xsl:template match="/">
<xsl:for-each select="books/book">
g_books.push( new Book( {
id: <xsl:value-of select="@id" />,
name: '<xsl:value-of select="js:escape(title)" />',
first: '<xsl:value-of select="js:escape(author/first)" />',
last: '<xsl:value-of select="js:escape(author/last)" />',
publisher: '<xsl:value-of select="js:escape( publisher )" />'
}  ) );</xsl:for-each>
</xsl:template>




此页面内最值得注意的是定义 Book 类的那部分代码。                        显示了该页面。
清单 15. object1.html
1
2
3
4
5
6
7
8
9
...
<script>
var g_books = [];
function Book( data )
{
  for( var d in data ) { this[d] = data[d]; }
}
</script>
...




Book 类的构造函数循环访问散列表的所有数据。对于每个键,会在对象上创建一个具有对象名称和数据的实例变量。不需要对                        drawbooks 函数做任何修改,因为对象都有与原始的散列表相同的键和值。JavaScript 语言并不区分访问的是散列表内的命名值还是对象上的命名值。
当然,Book 类应该有像 set 和 get 这样的访问程序。  显示了我是如何对 JavaScript 数据进行编码的。
清单 16. Object2.js
1
2
3
4
5
6
7
8
9
10
11
12
var  b1  = new Book();
b1.setId ( 1 );
b1.setTitle ( 'Code Generation in Action' );
b1.setFirst ( 'Jack' );
b1.setLast ( 'Herrington' );
b1.setPublisher ( 'Manning' );
g_books.push( b1 );

var  b2  = new Book();
b2.setId ( 2 );
b2.setTitle ( 'PHP Hacks' );
...




没错,这有些大同小异。它也是先创建一个对象,设置其值,然后将它添加到数组,等等。首先,我对样式表做了一些较大的修改,如  所示。
清单 17. Object2.xsl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
<xsl:function name="js:createbook">
<xsl:param name="book" />
<xsl:variable name="b" select="concat( 'b', $book/@id )" />
var <xsl:value-of select="$b" /> = new Book();
<xsl:value-of select="concat( $b, '.setId' )" />
( <xsl:value-of select="$book/@id" /> );
<xsl:value-of select="concat( $b, '.setTitle' )" />
( '<xsl:value-of select="js:escape( $book/title )" />' );
<xsl:value-of select="concat( $b, '.setFirst' )" />
( '<xsl:value-of select="js:escape( $book/author/first )" />' );
<xsl:value-of select="concat( $b, '.setLast' )" />
( '<xsl:value-of select="js:escape( $book/author/last )" />' );
<xsl:value-of select="concat( $b, '.setPublisher' )" />
( '<xsl:value-of select="js:escape( $book/publisher )" />' );
</xsl:function>
     
<xsl:template match="/">
<xsl:for-each select="books/book">
<xsl:value-of select="js:createbook(.)" />
g_books.push( b<xsl:value-of select="@id" /> );
</xsl:for-each>
</xsl:template>
...




我定义了一个新的名为 createbook 的函数,该函数构建 book 对象,并由用于每本书的模板调用。createbook 函数还是调用 escape 函数来确保字符串被正确编码。
考虑到 HTML 方面,我必须向 Book 类添加更多方法以便编码后的 JavaScript 代码能够调用它们。这些新方法如  所示。
清单 18. Object2.html
1
2
3
4
5
6
7
8
9
10
11
...
<script>
var g_books = [];
function Book() { }
Book.prototype.setId = function( val ) { this.id = val; }
Book.prototype.setTitle = function( val ) { this.name = val; }
Book.prototype.setFirst = function( val ) { this.first = val; }
Book.prototype.setLast = function( val ) { this.last = val; }
Book.prototype.setPublisher = function( val ) { this.publisher = val; }
</script>
...




原型机制是 JavaScript 语言所特有的。该语言中的每个对象都是具有其自己的数据和函数的单独实体,可独立设置。某个类的每个对象都有相同的原型。所以,为了创建可由所有类共享的方法,我在原型之上设置了函数,而不仅仅是在对象上。
返回列表