I Love China

技术·人生

技术服务生活
繁體

Archive for 8月, 2008

[AIR]连续使用SQLStatement查询的问题

星期日, 8月 31st, 2008

AIR[关于AIR-SQLITE的问题]
[问题描述]
使用SQLStatement的实例stmt查询数据库,并在结果事件处理函数中再次使用stmt查询时,上次查询的结果会累计到下次查询中。比如考虑下面的例子:

private function initList():void
{
	stmt.addEventListener(SQLEvent.RESULT,getCategory);
	stmt.addEventListener(SQLErrorEvent.ERROR,getCategoryErr);
	stmt.text = "select category from foods group by category";
	stmt.execute();
}
private function getCategoryErr(e:SQLErrorEvent):void
{
	trace("err");
}
private function getCategory(e:SQLEvent):void
{

	var str:String = "";
	stmt.removeEventListener(SQLEvent.RESULT,getCategory);
	var result:SQLResult = stmt.getResult();
	var len:uint = result.data.length;
	//trace(len);
	for(var i:uint = 0; i < len; i++)
	{
		str += "";
	}
	str +="";
	//trace(str);
	categoryXML = new XML(str);
	categoryTree.labelField = "@label";
	categoryTree.dataProvider = categoryXML;
	categoryTree.showRoot = false;
	categoryTree.selectedIndex = 0;
	initFood(categoryXML.child(0).@label);
}
private function initFood(str:String):void
{
	//trace(str);

	stmt.addEventListener(SQLEvent.RESULT,getFood);
	stmt.text = "select foodName from foods where category='" + str + "'";
	stmt.execute();
}
private function getFood(e:SQLEvent):void
{
	var str:String = "";
	stmt.removeEventListener(SQLEvent.RESULT,getFood);
	var result:SQLResult = stmt.getResult();
	var len:uint = result.data.length;
	for(var i:uint = 0; i < len; i++)
	{
		str += "";
	}
	str +="";
	//trace(str);
	foodXML = new XML(str);
	foodTree.labelField = "@label";
	foodTree.dataProvider = foodXML;
	foodTree.showRoot = false;

}

其中方法initList将开始一个SQLStatement查询,并使用getCategory处理查询结果,在getCategory中,首先注销了事件监听,并使用getResult取出序列中的查询结果,然后使用结果构建了一个XML对象,作为Tree组件的dataProvider,紧接着又通过调用initFood,开始了一个新的查询,并使用getFood处理查询结果,并将结果构造成foodXML的内容,问题出现了,上次查询,也就是getCategory中的结果一直保留着,出现在了getFood查询的结果中。如果不在getCategory里直接调用initFood,而是过一段时间后再调用initFood,则不会出现这样的问题。
[简单分析]
Flex帮助文档中说,SQLStatement的查询的结果一直保存在序列中,直到调用一次getResult,才会清除一次。但是上面描述的问题中,尽管我调用了getResult,但是结果依然没有被清理掉。看来它的清理也是需要一段时间才执行的。
[解决办法]
可以使用Timer,过一段时间后再执行,或者重构stmt,即在getCategory方法体内调用initFood前,加上
stmt = new SQLStatement();
stmt.sqlConnection = conn;

另外还有一个问题,就是关于分页的问题,SQLite似乎不支持类似 select top(10) …这样的查询,如果要取前几条数据,可以这样stmt.execute(10),这样就是取前10条数据,但是,如果10条之后的数据,你不想用的话别忘了在getResult后调用stmt.cancel().否则不能进行下一次查询

[Flex]Tree与DataGrid绑定XML的不同之处

星期六, 8月 30th, 2008

FlexFlex中Tree组件和DataGrid都可以直接绑定XML数据。Tree有labelField属性,而DataGridItem的是dataField,这不仅仅是名称上的差别,它们对XML格式的要求也不一样。比如

var testXML:XMLList =
<parts>
    <part label="t1" />
    <part label="t2" />
</parts>

我们可以将它绑定到Tree组件上,指定labelField为label,但是却无法将它绑定到DataGrid上,尽管指定dataField为label。只有下面的格式才行

<parts>
    <part>
      <label>t1</label>
    </part>
    <part>
      <label>t2></label>
     </part>
</parts>