您的位置:首页 > Web前端 > JavaScript

在QML应用中使用JSONListModel来帮我们解析JSON数据

2015-05-28 14:48 381 查看
我们知道JSON数据在很多web service中被广泛使用。它在我以前的文章中都有被提到:

- 如何读取一个本地Json文件并查询该文件展示其内容

- 如何在QML应用中使用Javascript解析JSON

在今天的这篇文章中,我来介绍一种类似像XmlListModel(解析XML)的方法来解析我们的JSON。这个方法更加简单直接。关于JSONListModel的介绍可以参照地址https://github.com/kromain/qml-utils

我们今天就利用JSONListModel的网址提供的例程来做说明。

我们首先来看一看JSONListModel的写法:

JSONListModel.qml

/* JSONListModel - a QML ListModel with JSON and JSONPath support
*
* Copyright (c) 2012 Romain Pokrzywka (KDAB) (romain@kdab.com)
* Licensed under the MIT licence (http://opensource.org/licenses/mit-license.php)
*/

import QtQuick 2.0
import "jsonpath.js" as JSONPath

Item {
property string source: ""
property string json: ""
property string query: ""

property ListModel model : ListModel { id: jsonModel }
property alias count: jsonModel.count

onSourceChanged: {
var xhr = new XMLHttpRequest;
xhr.open("GET", source);
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE)
json = xhr.responseText;
}
xhr.send();
}

onJsonChanged: updateJSONModel()
onQueryChanged: updateJSONModel()

function updateJSONModel() {
jsonModel.clear();

if ( json === "" )
return;

var objectArray = parseJSONString(json, query);
for ( var key in objectArray ) {
var jo = objectArray[key];
jsonModel.append( jo );
}
}

function parseJSONString(jsonString, jsonPathQuery) {
var objectArray = JSON.parse(jsonString);
if ( jsonPathQuery !== "" )
objectArray = JSONPath.jsonPath(objectArray, jsonPathQuery);

return objectArray;
}


在这里,我们可以学习一些如何包装一个模块并使得我们的model被外界所使用。这个模块的写法很值得推荐。对于一些大型的软件来说,我们可以通过这样的方法来独立完成我们的model,并被其它模块而使用。可以实现UI和数据的分割。

首先,这个模块定义了一个source属性。当source一旦被设置后,onSourceChanged将被自动调用,从而发出请求去得到数据。当数据得到后, json的数值发生改变,进而onJsonChanged将被自动调用。最终在updateJSONModel()中,模块所定义的jsonModel将被更新,以被外面的ListView或其它的Control所使用。同样,每当query发生改变后,model的数据也将被重新修改。

就像我之前的例子一样,它使用了jsonpath.js模块来实现xpath的查询功能。

在例程里,我们可以直接使用JSONListModel来为我们的ListView填充数据:

import QtQuick 2.0
import Ubuntu.Components 1.1

/*!
\brief MainView with a Label and Button elements.
*/

MainView {
// objectName for functional testing purposes (autopilot-qt5)
objectName: "mainView"

// Note! applicationName needs to match the "name" field of the click manifest
applicationName: "test1.liu-xiao-guo"

/*
This property enables the application to change orientation
when the device is rotated. The default is false.
*/
//automaticOrientation: true

// Removes the old toolbar and enables new features of the new header.
useDeprecatedToolbar: false

width: units.gu(100)
height: units.gu(75)

Page {
title: i18n.tr("test1")

Column {
spacing: units.gu(1)
anchors {
margins: units.gu(2)
fill: parent
}

Label {
id: label
objectName: "label"

text: i18n.tr("Hello..")
}

Button {
objectName: "button"
width: parent.width

text: i18n.tr("Tap me!")

onClicked: {
label.text = i18n.tr("..world!")
}
}
}
}
}


jsonData.txt

{ "store": {
"book": [
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{ "category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{ "category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
}
}


通过不同的查询,我们可以得到JSON数据中不同条件下的数据。应用的展示效果如下:



项目的源码在:https://github.com/liu-xiao-guo/jsonlistmodeltest
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: