在Javascript中解析JSON
下面我们看下如何在Javascript中对JSON进行解析。
定义常量
我们为了设计方便,在Javscirpt中先定义一些常量,以方便代码的书写和阅读,代码如下:
// Constants
var STYLED_IN = '<input type="text" class="ui-input-text ui-body-null ui-corner-all ui-shadow-inset ui-body-c" id="';
var TR_O = '<tr><td>';
var TD_C = '</td></tr>';
var TD_M = '</td><td>';
var VALUE = ' value="';
var WORK_ORG_FRAGMENT_SFX = '">'+TD_C;
var HOME_FRAGMENT_PRX = TR_O+'Home'+TD_M+STYLED_IN;
var MOBILE_FRAGMENT_PRX = TR_O+'Mobile'+TD_M+STYLED_IN;
var WORK_FRAGMENT_PRX = TR_O+'Work'+TD_M+STYLED_IN;
var OTHER_FRAGMENT_PRX = TR_O+'Other'+TD_M+STYLED_IN;
var HOME_PHONE_FRAGMENT_MID = '_1_No"' + VALUE;
var MOBILE_PHONE_FRAGMENT_MID = '_2_No"' + VALUE;
var WORK_PHONE_FRAGMENT_MID = '_3_No"' + VALUE;
var OTHER_PHONE_FRAGMENT_MID = '_7_No"' + VALUE;
...
以上要注意的是在变量 STYLED_IN中,增加了jQuery Mobile中特定的样式。jQuery Mobile允许动态向一个表中增加行,但我们发现目前的版本,在动态增加行后,jQuery Mobile并没有将上一层的<div>标记中的样式自动应用到<input>中去,所以要另外增加。
定义一些变量
下面定义一些初始变量,并进行初始化。
...
var currentContact;
var firstNameVar;
var lastNameVar;
var noteVar;
var contactIdVar;
var phonesTableVar;
...
$(document).ready(function () {
firstNameVar = $('#firstName');
lastNameVar = $('#lastName');
noteVar = $('#note');
contactIdVar = $('#contactId');
phonesTableVar = $('#phonesTable');
...
}
接下来,我们使用jQuery的parseJSON功能去解析后端程序返回的JSON字符串,其中用变量 currentContact保存JSON字符串,而contactId, firstName, lastName和note则可以直接从JSON中解析出来,比较简单,如下所示:
currentContact = $.parseJSON(jsonText);
contactIdVar.val(currentContact.contactId);
firstNameVar.val(currentContact.firstName);
lastNameVar.val(currentContact.lastName);
noteVar.val(currentContact.note.text);
解析对象数组
接下来,我们看下如何解析象Phone,Email,Address这些对象数组类型的JSON元素。这里其实只需要用循环对JSON中的Phone,Email,Address分别进行遍历,然后再用变量保存即可,下面以Phone为例进行说明,分别用 tmpType, tmpRowId, tmpNo保存了解析出来的type,rowId和no。
...
if(phonesArr !== null){
for(i = 0; i < phonesArr.length; i++){
var tmpType = (phonesArr[i]).type;
var tmpRowId = (phonesArr[i]).rowId;
var tmpNo = (phonesArr[i]).no;
...
根据不同的电话类型,我们构建了对应的HTML片断去展示JSON解析出来的电话号码,比如如果是家庭号码,并且tmpRowId为15和值是222333444,则以如下形式展示:
HOME_FRAGMENT_PRX + tmpRowId + HOME_PHONE_FRAGMENT_MID + tmpNo + FRAGMENT_SFX
这实际上出来的效果是如下的HTML代码:
class="ui-input-text ui-body-null ui-corner-all ui-shadow-inset ui-body-c"
id="15_1_No" value="2223334444"></td></tr>
最后,我们综合来看下解析JSON字符串的代码中,其中Phone部分的展示方法如下:
var homePhoneSet = false;
var workPhoneSet = false;
var otherPhoneSet = false;
if(phonesArr !== null){
for(i = 0; i < phonesArr.length; i++){
var tmpType = (phonesArr[i]).type;
var tmpRowId = (phonesArr[i]).rowId;
var tmpNo = (phonesArr[i]).no;
if(tmpType == 1){//home
phonesTableVar.append(HOME_FRAGMENT_PRX + tmpRowId + HOME_PHONE_FRAGMENT_MID + tmpNo + FRAGMENT_SFX);
homePhoneSet = true;
}else if(tmpType == 2){//mobile
phonesTableVar.append(MOBILE_FRAGMENT_PRX + tmpRowId + MOBILE_PHONE_FRAGMENT_MID + tmpNo + FRAGMENT_SFX);
mobilePhoneSet = true;
}else if(tmpType == 3){//work
phonesTableVar.append(WORK_FRAGMENT_PRX + tmpRowId + WORK_PHONE_FRAGMENT_MID + tmpNo + FRAGMENT_SFX);
workPhoneSet = true;
}else if(tmpType == 7){//other
phonesTableVar.append(OTHER_FRAGMENT_PRX + tmpRowId + OTHER_PHONE_FRAGMENT_MID + tmpNo + FRAGMENT_SFX);
otherPhoneSet = true;
}
}
}
要注意的是,假如通讯录中有的联系人并没有所有的电话类型(比如只有工作电话,而没记载家庭电话),则需要用如下代码:
var MOBILE_PHONE_FRAGMENT_LOCAL = TR_O+'Mobile'+TD_M+STYLED_IN+'-1_2_No">'+TD_C;
var WORK_PHONE_FRAGMENT_LOCAL = TR_O+'Work'+TD_M+STYLED_IN+'-1_3_No">'+TD_C;
var OTHER_PHONE_FRAGMENT_LOCAL = TR_O+'Other'+TD_M+STYLED_IN+'-1_7_No">'+TD_C;
...
if(phonesArr !== null){
...
}
if(!homePhoneSet){
phonesTableVar.append(HOME_PHONE_FRAGMENT_LOCAL);
}
if(!mobilePhoneSet){
phonesTableVar.append(MOBILE_PHONE_FRAGMENT_LOCAL);
}
if(!workPhoneSet){
phonesTableVar.append(WORK_PHONE_FRAGMENT_LOCAL);
}
if(!otherPhoneSet){
phonesTableVar.append(OTHER_PHONE_FRAGMENT_LOCAL);
}
解析下上面这段代码,假设某个联系人没工作移动电话,那么 workPhoneSet 为false,上面的代码会变为:
class="ui-input-text ui-body-null ui-corner-all ui-shadow-inset ui-body-c" id="-1_1_No"></td></tr>
这实际上是向DIV区域加了一个空白的文本域而已。
最后,当解析完后端返回的JSON字符串后,就在 setCurrentContact最后,调用showDetail()方法,显示出内容页面即可
...
showDetail();
}
最后,总结下显示已存在的通讯录的页面流向和步骤,如下:
-> DetailPage.html:$(document).ready()
-> ContactsActivity.getContact(id, 'setCurrentContact')
-> DetailPage.html:setCurrentContact(json)