使用 JQuery Mobile & XML 创建 CRUD Web 应用





0/5 (0投票)
演示如何创建 JQuery Mobile 应用程序并使用 XML 作为后端 - 通过使用 xml2json.js 和 json2xml.js 实现单个 XML 记录方法。
引言
本文旨在演示如何使用 JQuery Mobile 和 XML 单文件记录作为后端来存储记录,从而创建 CRUD Web 应用程序。我将假设一个非常简单的图书馆系统,其中存储图书详细信息。这些将是每本书的书名、作者和 ISBN。
该应用程序本身将通过阅读和列出每本书来列出可用的已存储图书,并具有添加、更新和删除图书的功能。
所应用的原理与此文章中的相同,但是由于使用 XML 作为后端,代码已进行了一些调整以创建和读取此类文件。其中包括在应用程序中添加 JavaScript 文件以将 XML 转换为 JSON,以及将 JSON 转换为 XML,分别是 xml2json.js 和 json2xml.js。
用作后端的 XML 文件只是基本文件,其中每条记录都存储在 <modelname> 属性中。
一些愚蠢的假设:您熟悉我的文章JQuery Mobile & JSON。源代码的结构与我们使用 Ajax 调用 PHP 文件从数据库中读取、更新和删除记录相同,但这次不是 JSON 文件,而是 XML 文件。我假设您也熟悉用于 UI 创建的 JQuery Mobile HTML 定义。
顺便说一句,xml2json.js 是一个 JQuery 插件,可以将您的 XML 转换为 JSON 对象。由于在我们的应用程序中操作 JSON 对象很容易,所以我采用了这种方法。它是在这里获得的。在我的应用程序中读取每条记录时使用它。
json2xml.js 用于保存我的 XML 记录。您会记得我之前的 CRUD 应用程序,我将用户输入的屏幕内容设置为 JSON 对象,并将此对象保存到所选的后端。所以这个脚本基本上就是这样做的,它接收我的 JSON 对象并将其转换为 XML,这样我就可以将其保存。这个脚本是在这里获得的。
背景
在过去的几周里,我一直在讨论使用 JQuery Mobile 为各种后端创建 CRUD 应用程序。您可以在此处查看我的文章以获得更清晰的说明。我将在此处遵循的方法是相同的。我的应用程序仅用于简单的 CRUD 操作,它们仅提供基本操作。在本练习结束时,我们希望拥有一个看起来像这样的应用程序。
图 1:启动板(JQuery Mobile 图书馆应用程序的主菜单)
图 2:图书列表(应用程序中所有图书的列表视图)
图 3:添加图书(向图书馆添加图书的屏幕)
图 4:更新/删除图书(更新或删除图书详细信息的屏幕)
图 5:图书报告(列出我们图书馆中所有图书的表格小部件)
图 6:图书报告 - Excel (我们图书馆的 Excel 报告)
我将在此处深入探讨 CRUDV 操作,因为您可以参考我之前的文章了解本文的其他部分,例如报告、导出到 Excel 等。
使用代码
CR - 创建图书
使用应用程序创建和记录的图书将存储在服务器上名为 Book 的文件夹中。这基于我们定义的模型名称。每本书的书名是每本书的主键,XML 文件名将是书名的一个清理版本,带有一个 .xml 扩展名。
添加图书:HTML 定义
<div data-model="Book" id="pgAddBook" data-role="page">
<div data-position="left" data-display="reveal" data-position-fixed="true" id="pgAddBookPnl" data-role="panel">
<ul data-role="listview" id="pgAddBookPnlLV">
<li data-icon="plus"><a data-transition="slide" href="#pgAddBook">New</a></li>
<li data-icon="eye"><a data-transition="slide" href="#pgRptBook">Report</a></li>
<li data-icon="carat-l"><a data-transition="slide" href="#pgBook">Back</a></li>
</ul>
</div>
<header id="pgAddBookHdr" data-role="header" data-position="fixed">
<h1>Library</h1>
<a data-role="button" id="pgAddBookMenu" href="#pgAddBookPnl" data-icon="bars" class="ui-btn-left">Menu</a>
</header>
<div id="pgAddBookCnt" data-role="content">
<h3>Add Book</h3><form action="#" method="post" id="pgAddBookForm" name="pgAddBookForm">
<div data-role="fieldcontain">
<label for="pgAddBookTitle">Title<span style='color:red;'>*</span></label>
<input required title="Enter title here." type="text" name="pgAddBookTitle" id="pgAddBookTitle" placeholder="Enter title here." autocomplete="off" data-clear-btn="true"></input>
</div>
<div data-role="fieldcontain">
<label for="pgAddBookAuthor">Author<span style='color:red;'>*</span></label>
<input required title="Enter author here." type="text" name="pgAddBookAuthor" id="pgAddBookAuthor" placeholder="Enter author here." autocomplete="off" data-clear-btn="true"></input>
</div>
<div data-role="fieldcontain">
<label for="pgAddBookISBN">ISBN<span style='color:red;'>*</span></label>
<input required title="Enter isbn here." type="text" name="pgAddBookISBN" id="pgAddBookISBN" placeholder="Enter isbn here." autocomplete="off" data-clear-btn="true"></input>
</div>
</form>
</div>
<footer id="pgAddBookFtr" data-role="footer" data-position="fixed">
<div id="pgAddBookFtrNavBar" data-role="navbar">
<ul>
<li><a id="pgAddBookBack" data-icon="carat-l">Cancel</a>
</li>
<li><a type="submit" id="pgAddBookSave" data-icon="action">Save</a>
</li>
</ul>
</div>
</footer></div>
我们只为图书使用三个输入控件。屏幕上有一个取消按钮,用于将用户带回图书列表,还有一个保存按钮。
添加图书:保存按钮点击事件
// Save click event on Add page
$('#pgAddBookSave').on('click', function (e) {
e.preventDefault();
e.stopImmediatePropagation();
//get form contents into an object
var BookRec = pgAddBookGetRec();
//save object to XML
app.addBook(BookRec);
});
输入的图书详细信息由 pgAddBookGetRec() 读取并存储为 BookRec。
//read contents of each form input
function pgAddBookGetRec() {
//define the new record
var BookRec = {};
BookRec.Title = $('#pgAddBookTitle').val().trim();
BookRec.Author = $('#pgAddBookAuthor').val().trim();
BookRec.ISBN = $('#pgAddBookISBN').val().trim();
return BookRec;
}
然后调用 app.addBook(BookRec);,将图书的 JSON 记录传递给此函数。
// add a new record to server storage.
app.addBook = function (BookRec) {
// define a record object to store the current details
var Title = BookRec.Title;
// cleanse the record key of spaces.
Title = Title.split(' ').join('-');
BookRec.Title = Title;
//convert record to xml to write to server
var recordXML = json2xml(BookRec, "Book");
// we are using a single profile approach, then append xml header
recordXML = "<?xml version='1.0' encoding='utf-8'?>" + recordXML;
// save the data to a server file, use the post method as it has 8MB minimum data limitation
var req = Ajax("xmlSaveBook.php", "POST" , recordXML);
if (req.status == 200) {
//show a toast message that the record has been saved
toastr.success('Book record saved.', 'Library');
//find which page are we coming from, if from sign in go back to it
var pgFrom = $('#pgAddBook').data('from');
switch (pgFrom) {
case "pgSignIn":
$.mobile.changePage('#pgSignIn', {transition: pgtransition});
break;
default:
// clear the edit page form fields
pgAddBookClear();
//stay in the same page to add more records
}
} else {
//show a toast message that the record has not been saved
toastr.error('Book record not saved. Please try again.', 'Library');
}
};
书名被清理以删除任何空格,这些空格被转换为 -。然后,输入的图书内容从 JSON 对象转换为 XML 字符串。
//convert record to xml to write to server
var recordXML = json2xml(BookRec, "Book");
然后,此图书 XML 记录被格式化为具有 XML 标头。
recordXML = "<?xml version='1.0' encoding='utf-8'?>" + recordXML;
然后发出 POST ajax 调用,从而使用书名将图书记录作为 XML 文件保存到服务器的 Book 文件夹。
var req = Ajax("xmlSaveBook.php", "POST" , recordXML);
然后根据调用的成功情况,我们会在 toast 中告知最终用户。查看 xmlSaveBook.php,这就是发生的情况
<?php
// Get the data from the client.
$record = file_get_contents('php://input');
// we want to parse the XML elements
$xmlrec = new SimpleXMLElement($record);
// read the primary key
$Title = $xmlrec->Title;
//write the data out to a file on the server
//make sure permissions are all OK!
//create the parent folder
if (!is_dir('./Book/')) {
mkdir('./Book/');
}
//define the file
$xmlFile = "Book/" . $Title . ".xml";
$f = fopen($xmlFile, 'w') or die("Error: Can't open file. Got write permission?");
fwrite($f, $record);
fclose($f);
?>
这会获取传递到服务器的 XML 内容,并使用 SimpleXMLElement 在 PHP 文件中解析它。读取书名,如果服务器中不存在 Book 目录,则创建它。然后定义 xmlFile 以包含完整路径,然后将 XML 记录的内容保存到文件中。
Ajax 函数存储在 remoteserver.js 文件中,并显示如下
function Ajax(URL, method, data, callback) {
if (typeof(method) !== 'object') {
var settings = new Object;
if(!method || method === null || typeof(method) === 'undefined') method = "GET";
settings.type = method.toUpperCase()
if(!data || data === null || typeof(data) === 'undefined') data = "";
settings.data = data;
if (!callback) {
settings.async = false;
} else {
settings.success = callback;
settings.fail = callback}
}
return $.ajax(URL, settings);
}
U - 更新图书
更新图书需要从可用图书列表中选择一本图书,然后会出现编辑屏幕。然后,可以更新图书详细信息(书名除外),然后点击“更新”。
更新图书:HTML 定义
<div data-url="Title" data-model="Book" id="pgEditBook" data-role="page">
<div data-position="left" data-display="reveal" data-position-fixed="true" id="pgEditBookPnl" data-role="panel">
<ul data-role="listview" id="pgEditBookPnlLV">
<li data-icon="plus"><a data-transition="slide" href="#pgAddBook">New</a></li>
<li data-icon="eye"><a data-transition="slide" href="#pgRptBook">Report</a></li>
<li data-icon="carat-l"><a data-transition="slide" href="#pgBook">Back</a></li>
</ul>
</div>
<header id="pgEditBookHdr" data-role="header" data-position="fixed">
<h1>Library</h1>
<a data-role="button" id="pgEditBookMenu" href="#pgEditBookPnl" data-icon="bars" class="ui-btn-left">Menu</a>
</header>
<div id="pgEditBookCnt" data-role="content">
<h3>Edit Book</h3><form action="#" method="post" id="pgEditBookForm" name="pgEditBookForm">
<div data-role="fieldcontain">
<label for="pgEditBookTitle">Title<span style='color:red;'>*</span></label>
<input required readonly="readonly" data-clear-btn="true" autofocus="true" title="Enter title here." type="text" name="pgEditBookTitle" id="pgEditBookTitle" placeholder="Enter title here." autocomplete="off"></input>
</div>
<div data-role="fieldcontain">
<label for="pgEditBookAuthor">Author<span style='color:red;'>*</span></label>
<input required title="Enter author here." type="text" name="pgEditBookAuthor" id="pgEditBookAuthor" placeholder="Enter author here." autocomplete="off" data-clear-btn="true"></input>
</div>
<div data-role="fieldcontain">
<label for="pgEditBookISBN">ISBN<span style='color:red;'>*</span></label>
<input required title="Enter isbn here." type="text" name="pgEditBookISBN" id="pgEditBookISBN" placeholder="Enter isbn here." autocomplete="off" data-clear-btn="true"></input>
</div>
</form>
</div>
<footer id="pgEditBookFtr" data-role="footer" data-position="fixed">
<div id="pgEditBookFtrNavBar" data-role="navbar">
<ul>
<li><a data-transition="slide" id="pgEditBookBack" href="#pgBook" data-icon="carat-l">Cancel</a>
</li>
<li><a type="submit" id="pgEditBookUpdate" data-icon="action">Update</a>
</li>
<li><a id="pgEditBookDelete" data-icon="delete">Delete</a>
</li>
</ul>
</div>
</footer></div>
更新/删除屏幕的页脚有取消、更新、删除按钮,以确保图书得到更新或删除。当用户选择更新图书时,详细信息将从每个图书的此 HTML 定义输入属性中读取,然后保存到 JSON 对象,该对象稍后保存到服务器。让我们看看这个。
更新图书:更新按钮点击事件
// Update click event on Edit Page
$('#pgEditBookUpdate').on('click', function (e) {
e.preventDefault();
e.stopImmediatePropagation();
//get contents of Edit page controls
var BookRec = pgEditBookGetRec();
//save updated records to XML
app.updateBook(BookRec);
});
当点击“更新”按钮时,表单中输入的详细信息由 pgEditBookGetRec 读取并分配给 BookRec,然后将其传递给 app.updateBook 以保存到服务器。
//read contents of each form input
function pgEditBookGetRec() {
//define the new record
var BookRec = {};
BookRec.Title = $('#pgEditBookTitle').val().trim();
BookRec.Author = $('#pgEditBookAuthor').val().trim();
BookRec.ISBN = $('#pgEditBookISBN').val().trim();
return BookRec;
}
我们的 AddPage 输入控件是 pgAddBookTitle,对于更新页面,它们是 pgEditBookTitle。我们使用了两个屏幕进行添加和更新,以确保代码易于维护。然后调用 app.updateBook,将 BookRec 传递给它以保存。
// update an existing record and save to server.
app.updateBook = function (BookRec) {
// define a record object to store the current details
var Title = BookRec.Title;
// cleanse the record key of spaces.
Title = Title.split(' ').join('-');
BookRec.Title = Title;
//convert record to XML to write to server
var recordXML = json2xml(BookRec, "Book");
// we are using a single profile approach, then append xml header
recordXML = "<?xml version='1.0' encoding='utf-8'?>" + recordXML;
// save the data to a server file, use the post method as it has 8MB minimum data limitation
var req = Ajax("xmlSaveBook.php", "POST" , recordXML);
if (req.status == 200) {
//show a toast message that the record has been saved
toastr.success('Book record updated.', 'Library');
// clear the edit page form fields
pgEditBookClear();
// show the records listing page.
$.mobile.changePage('#pgBook', {transition: pgtransition});
} else {
//show a toast message that the record has not been saved
toastr.error('Book record not updated. Please try again.', 'Library');
}
};
就像上述方法一样,编辑记录被转换为 XML 并包含一个标头,然后使用与添加记录相同的 xmlSaveBook.php 向服务器执行 POST 操作。请记住,记录已更改,但保存方法未更改,因此使用相同的 PHP 文件。您还会注意到,在附加的 zip 文件中,只有三个 PHP 文件,用于保存、获取和删除。
D - 删除图书
在图书更新屏幕中,可以选择“删除”以删除图书。
当用户选择删除图书时,会弹出一个提示,询问用户是否真的要删除该图书。从服务器删除图书是无法撤消的操作。书名从更新屏幕读取,并传递到 msgbox 页面。
更新页面:删除按钮点击事件
$('#pgEditBookDelete').on('click', function (e) {
e.preventDefault();
e.stopImmediatePropagation();
//read the record key from form control
var Title = $('#pgEditBookTitle').val().trim();
//show a confirm message box
$('#msgboxheader h1').text('Confirm Delete');
$('#msgboxtitle').text(Title.split('-').join(' '));
$('#msgboxprompt').text('Are you sure that you want to delete this book? This action cannot be undone.');
$('#msgboxyes').data('method', 'deleteBook');
$('#msgboxno').data('method', 'editBook');
$('#msgboxyes').data('id', Title.split(' ').join('-'));
$('#msgboxno').data('id', Title.split(' ').join('-'));
$('#msgboxyes').data('topage', 'pgEditBook');
$('#msgboxno').data('topage', 'pgEditBook');
$.mobile.changePage('#msgbox', {transition: 'pop'});
});
这会将我们的 msgbox 属性传递给一个像这样定义的 msgbox 屏幕:一个对话框弹出屏幕
<div data-dismissible="false" data-transition="pop" data-model="msgbox" id="msgbox" data-role="dialog">
<header id="msgboxHdr" data-role="header" data-position="fixed">
<h1>Confirm</h1>
</header>
<div id="msgboxCnt" data-role="content">
<div id="msgboxtitle">
</div>
<br><div id="msgboxprompt">
<p>Are you sure you want to delete this record?</p>
</div>
<br><div style="text-align: center;" id="msgboxbuttons" class="ui-grid-a">
<div class="ui-block-a">
<a data-method="" data-id="" data-topage="" id="msgboxyes" data-role="button" data-icon="check">Yes</a>
</div>
<div class="ui-block-b">
<a data-method="" data-id="" data-topage="" id="msgboxno" data-role="button" data-icon="delete" data-theme="b">No</a>
</div>
</div>
</div>
</div>
我之前的文章详细讨论了这种消息框方法,您可以参考它,但是,当点击“是”按钮时,该按钮定义为
$('#msgboxyes').data('method', 'deleteBook');
app.deleteBook 方法被触发,传递图书的 ID,保存方式如下
$('#msgboxyes').data('id', Title.split(' ').join('-'));
MsgBox:“是”按钮点击事件
$('#msgboxyes').on('click', function (e) {
e.preventDefault();
e.stopImmediatePropagation();
var yesmethod = $('#msgboxyes').data('method');
var yesid = $('#msgboxyes').data('id');
app[yesmethod](yesid);
});
“是”按钮读取方法的传递数据属性和要删除记录的 ID,然后调用
app[yesmethod](yesid);
删除记录。让我们看看 app.deleteBook 函数。
//delete a record from XML using record key
app.deleteBook = function (Title) {
Title = Title.split(' ').join('-');
var req = Ajax("xmlDeleteBook.php/?Title=" + Title);
if (req.status == 200) {
toastr.success('Book record deleted.', 'Library');
} else {
toastr.error('Book record not deleted.', 'Library');
}
// show the page to display after a record is deleted, this case listing page
$.mobile.changePage('#pgBook', {transition: pgtransition});
};
它清理书名并调用 xmlDeleteBook.php,将书名传递给它。如果您注意到,此处未完成图书记录的扩展名。当图书被删除时,系统会通过 toast 通知用户。
xmlDeleteBook.php 的内部
<?php
//delete the xml record file from the server
$Title = $_GET['Title'];
unlink('./Book/'.$Title.'.xml');
?>
这会获取传递的书名,然后使用 unlink php 方法删除带有完整路径的文件。到此,我们的 XML CRUD 操作就结束了,让我们看看如何获取并列出列表视图中的所有图书。
V - 查看图书
从服务器获取所有可用图书和获取单本图书都使用 xmlGetBook.php。它看起来像这样
<?php
//get the file contents from the server
If (isset($_REQUEST['file'])) {
$file = basename($_REQUEST['file']);
echo file_get_contents('./Book/'.$file);
} Else {
If (is_dir('./Book') && $handle = opendir('./Book/')) {
While (False !== ($entry = readdir($handle))) {
If (!is_dir($entry)) {
echo basename($entry)."\n";
}
}
closedir($handle);
} Else {
header("HTTP/1.0 404 Not Found");
}
}
?>
当没有 file 参数地调用 Ajax() 时,文件夹中的所有文件都将返回,并由 CRLF(即 \n)分隔。然后,这些文件在运行时提取并列在列表视图中。当指定文件名时,将读取单个文件。让我们详细看看这个。
图书列表:HTML 定义
<div data-model="Book" id="pgBook" data-role="page">
<div data-position="left" data-display="reveal" data-position-fixed="true" id="pgBookPnl" data-role="panel">
<ul data-role="listview" id="pgBookPnlLV">
<li data-icon="plus"><a data-transition="slide" href="#pgAddBook">New</a></li>
<li data-icon="eye"><a data-transition="slide" href="#pgRptBook">Report</a></li>
<li data-icon="carat-l"><a data-transition="slide" href="#pgMenu">Back</a></li>
</ul>
</div>
<header id="pgBookHdr" data-role="header" data-position="fixed">
<h1>Library</h1>
<a data-role="button" id="pgBookMenu" href="#pgBookPnl" data-icon="bars" data-transition="slide" class="ui-btn-left">Menu</a>
<a data-role="button" id="pgBookNew" data-icon="plus" data-theme="b" class="ui-btn-right">New</a>
</header>
<div id="pgBookCnt" data-role="content">
<h3>Books</h3><ul data-role="listview" data-inset="true" id="pgBookList" data-filter="true" data-filter-placeholder="Search Books">
<li data-role="list-divider">Your Books</li>
<li id="noBook">You have no books</li>
</ul>
</div>
</div>
上面定义了列出图书馆中所有可用图书的列表视图页面。列表视图的名称是 pgBookList。此列表视图在运行时更新,因此可点击,以确保当用户选择每本书时,应用程序将打开更新屏幕。在显示图书列表页面之前,Web 应用程序会运行一些操作。
app.BookBindings = function () {
// code to run before showing the page that lists the records.
//run before the page is shown
$(document).on('pagebeforechange', function (e, data) {
//get page to go to
var toPage = data.toPage[0].id;
switch (toPage) {
case 'pgBook':
$('#pgRptBookBack').data('from', 'pgBook');
// restart the storage check
app.checkForBookStorage();
break;
在这种情况下,app.checkforBookStorage。定义如下。
//display records if they exist or tell user no records exist.
app.checkForBookStorage = function () {
//get records from XML.
var BookObj = app.getBook();
// are there existing Book records?
if (!$.isEmptyObject(BookObj)) {
// yes there are. pass them off to be displayed
app.displayBook(BookObj);
} else {
// nope, just show the placeholder
$('#pgBookList').html(BookHdr + noBook).listview('refresh');
}
};
此方法调用应用程序中大量使用的方法 app.getBook()。该方法执行的任何内容都存储在变量 BookObj 中。然后检查此 BookObj 是否为空,如果为空,列表视图将不显示任何记录,但是,如果有记录,将调用 app.displayBook 方法并传递 BookObj。
app.getBook = function () {
// get Book records
var BookObj = {};
var icnt, itot;
//get the list of files under directory
var req = Ajax("xmlGetBook.php");
if (req.status == 200) {
var recFiles = req.responseText;
recFiles = recFiles.split('\n');
itot = recFiles.length - 1;
for (icnt = 0; icnt <= itot; icnt++) {
var recFile = recFiles[icnt];
if (recFile.length > 0) {
// read the file contents and display them
var req = Ajax("xmlGetBook.php?file=" + encodeURIComponent(recFile));
if (req.status == 200) {
// convert to json
var BookRec = $.xml2json(req.responseText);
var Title = BookRec.Title;
Title = Title.split('-').join(' ');
BookRec.Title = Title
BookObj[Title] = BookRec;
}
}
}
//sort the objects
var keys = Object.keys(BookObj);
keys.sort();
var sortedObject = Object();
var i;
for (i in keys) {
key = keys[i];
sortedObject[key] = BookObj[key];
}
BookObj = sortedObject;
return BookObj;
}
};
如上所述,app.getBook 首先不传递 file 属性调用 xmlGetBook.php。这会返回此应用程序服务器的 Book 文件夹中所有可用的文件。它作为 responseText 返回。然后,它使用指定的 CRLF 字符进行解析,然后进行另一个 ajax 调用以读取每个文件,现在传递文件名。
第一种方法
var req = Ajax("xmlGetBook.php");
第二种方法
var req = Ajax("xmlGetBook.php?file=" + encodeURIComponent(recFile));
然后,对于找到的每个图书记录,BookObj 都会更新,然后按书名排序,并返回最终传递给 app.displayBook 的内容。
BookObj[Title] = BookRec; (updates of the BookObj)
return BookObj; (return of the BookObj to be passed for display)
app.displayBook 接收从服务器读取的所有图书,并将其显示到列表视图中,如下所示
//display records in listview during runtime.
app.displayBook = function (BookObj) {
// create an empty string to contain html
var html = '';
// make sure your iterators are properly scoped
var n;
// loop over records and create a new list item for each
//append the html to store the listitems.
for (n in BookObj) {
//get the record details
var BookRec = BookObj[n];
// clean the primary key
var pkey = BookRec.Title;
pkey = pkey.split('-').join(' ');
BookRec.Title = pkey;
//define a new line from what we have defined
var nItem = BookLi;
nItem = nItem.replace(/Z2/g,n);
//update the title to display, this might be multi fields
var nTitle = '';
//assign cleaned title
nTitle = n.split('-').join(' ');
//replace the title;
nItem = nItem.replace(/Z1/g,nTitle);
//there is a description, update the list item
var nDescription = '';
nDescription += BookRec.Author;
nDescription += ', ';
nDescription += BookRec.ISBN;
//replace the description;
nItem = nItem.replace(/DESCRIPTION/g,nDescription);
html += nItem;
}
//update the listview with the newly defined html structure.
$('#pgBookList').html(BookHdr + html).listview('refresh');
};
如您在列表屏幕中注意到的,我们希望在每本书的描述中显示作者和 ISBN。对于读取的每本书,然后读取这些属性,然后更新列表视图项并对列表视图进行一次更新。这有助于加快 DOM 操作。
图书表格报告:HTML 定义
图书表格报告最初是空白的,并在运行时填充图书列表。它定义如下。
<div data-model="Book" id="pgRptBook" data-role="page">
<header id="pgRptBookHdr" data-role="header" data-position="fixed">
<h1>Library</h1>
<a data-role="button" id="pgRptBookBack" data-icon="carat-l" class="ui-btn-left">Back</a>
<a data-role="button" id="pgRptBookNew" href="#pgAddBook" data-icon="plus" data-theme="b" data-transition="slide" class="ui-btn-right">New</a>
</header>
<div id="pgRptBookCnt" data-role="content">
<table id="RptBook" data-column-btn-text="Columns To Display" data-column-btn-theme="b" data-role="table" data-mode="columntoggle" data-column-popup-theme="a" class="ui-responsive table-stroke table-stripe ui-shadow">
<caption>Books Report</caption>
<thead>
<tr class="ui-bar-a">
<th class="ui-bar-a">Title</th>
<th data-priority="2" class="ui-bar-a">Author</th>
<th data-priority="3" class="ui-bar-a">ISBN</th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr><td></td></tr>
<tr><td colspan="3">Powered by JQM.Show - https://play.google.com/store/apps/details?id=com.b4a.JQMShow</td></tr></tfoot>
</table>
<div data-role="fieldcontain">
<a download="Book.xls" onclick="return ExcellentExport.excel(this, 'RptBook', 'Book');" id="pgRptBookExport" data-corners="true" href="#" class="ui-btn ui-corner-all ui-shadow">Export to Excel</a></div>
</div>
</div>
该表也在运行时生成,通过执行上面讨论的 app.getBook 方法,然后循环遍历每本书并生成一行表格,如下所示。然后将其填充到上面 HTML 中定义的表格中。
//display records in table during runtime.
app.BookRpt = function () {
//clear the table and leave the header
$('#RptBook tbody tr').remove();
// get Book records.
var BookObj = app.getBook();
// create an empty string to contain all rows of the table
var newrows = '';
// make sure your iterators are properly scoped
var n;
// loop over records and create a new row for each
// and append the newrows with each table row.
for (n in BookObj) {
//get the record details
var BookRec = BookObj[n];
//clean primary keys
n = n.split('-').join(' ');
//create each row
var eachrow = '<tr>';
eachrow += '<td class="ui-body-c">' + n + '</td>';
eachrow += '<td class="ui-body-c">' + BookRec.Author + '</td>';
eachrow += '<td class="ui-body-c">' + BookRec.ISBN + '</td>';
eachrow += '</tr>';
//append each row to the newrows variable;
newrows += eachrow;
}
// update the table
$('#RptBook').append(newrows);
// refresh the table with new details
$('#RptBook').table('refresh');
};
此外,为了加快 DOM 操作,在所有行生成后,通过将 eachrow 附加到 newrows,表格会更新一次。
至此,我们文章的关键点就总结完毕了。祝您阅读愉快。
关注点
上一篇文章讨论了如何使用 JSON 单记录作为后端创建 JQuery Mobile Web 应用程序。本文旨在遵循相同的方法,但使用 XML 作为后端记录。借助 xml2json 和 json2xml 这两个库,XML 文件的操作变得可能且容易,我将功劳归于开发这两个脚本的团队。
PHP 类 SimpleXMLElement 在 PHP 文件中操作 XML 以获取书名时也很有帮助。这有助于我了解 PHP 的强大功能。