创建RemoteObject之后, dataProvider直接就用啥啥啥.lastResult就好了. 但这个表格组件的列数是固定的: 总共有Name, Phone, Email三列. 我们这里要创建一个完全动态的表格, 由用户自己定义表格的列数和列的标题, 整个表格都是动态地完全自由定义地存到数据库中, 并与前台交互.
动态地记录一张表, 我这里的做法是这样的: 在数据库里面用三个表, 分别记录表的基本属性; 表头(即列名); 具体数据.
具体有这样几个表:
表名: tables
字段:tiduidnamesidadddate
其中tid是这张表的id, uid是创建这张表的用户id, sid是这张表所属的归类(uid和sid与本文关系不大), name和adddate分别是表名和创建日期.
表名: table_lines
字段: idtidlinetitle
id是表头自己的id, tid是它所属的表格id, linetitle是表头的具体名称.
表名: table_rows
字段: idlineidvalue
id是表中每个单元格的id, lineid是这个单元格所属的表头的id, value是具体的值.
当然这未必是最佳的设计方法, 但至少是可行的.table_rows会在循环的控制下往表里填充值. 可以看到,这种记录方法相当于只关心表的X方向的情况, 而不关心Y的方向. Y方向会在循环控制中随着内容的填充而增长.table_rows中必须记录每个单元格的内容, 哪怕是空值, 如果单元格空缺了或者循环有问题将导致整个表格输出错误.
PHP端读取了表格数据以后, 生成一个XML数据, 并通过RemoteObject传到前端. 前端把这个XML数据转换为Flex特有的ArrayCollection类型数据并与DataGrid绑定.
下面先来做读取表格并显示的功能. php的类如下:
tables.php
require_once 'includes/conn.php';
class Tables{
function getTableValue($tid){
$result='';
$sql="select count(id) from table_lines where tid=$tid";
$db=new database();
$rs=$db->query($sql);
$columns=$rs->getRow();
$columns=$columns[0];
$sql="select count(b.value) from table_lines a,table_rows b where a.tid=$tid and b.lineid=a.id";
$rs=$db->query($sql);
$rows=$rs->getRow();
$rows=$rows[0];
$rows=$rows/$columns;
$sql="select id,linetitle from table_lines where tid=$tid";
$rs=$db->query($sql);
$i=0;
while($row=$rs->getAssoc()){
$linehead[$i++]=$row['linetitle'];
}
$sql="select b.value from table_lines a,table_rows b where a.tid=$tid and b.lineid=a.id order by b.id";
$rs=$db->query($sql);
$i=0;
while($row=$rs->getAssoc()){
$getvalue[$i++]=$row['value'];
}
$l=0;
for($j=0;$j
$result.='';
for($k=0;$k
$result.='';
$result.=$getvalue[$l];
$result.=''.$linehead[$k].'>';
$l++;
}
$result.='';
}
$result.='';
return $result;
}
}
?>
includes/conn.php这个文件请自行解决..
下面贴一下前台的代码. 顺便说一下, 由于时间和其它一些问题, 最后在项目中并没使用这种动态表格, 所以本文只能给出如何读取和显示表格的代码, 至于创建和修改表格, 思路基本上差不多, 主要的问题就在于如何将Flex端的ArrayCollection数据源重新解析给PHP并按照我们设计的形式保存到数据库里面. 这个过程可能会比较麻烦, 但肯定是存在变通方法的~
下面的代码不是拷了直接用的, 得连接Flex的DataService, 调用上面那个PHP类.
tableview.mxml(这是一个Flex4的Module组件)
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:tables="services.tables.*"
width="1002" height="653">
import com.subjects.charts.*;
import mx.collections.ArrayCollection;
import mx.collections.XMLListCollection;
import mx.controls.Alert;
import mx.events.CloseEvent;
import mx.events.FlexEvent;
import mx.managers.PopUpManager;
import mx.rpc.events.ResultEvent;
import mx.rpc.xml.SimpleXMLDecoder;
public var viewtid:int;//单独测试时可以直接让它等于1
public var tablevalue:ArrayCollection = new ArrayCollection;
protected function getTableValue(tid:int):void
{
getTableValueResult.token = tables.getTableValue(tid);
}
protected function closeHandler():void
{
this.parent.removeChild(this);
}
protected function getTableValueResult_resultHandler(event:ResultEvent):void
{
var getresult:XML=XML(getTableValueResult.lastResult);
var xmlDoc:XMLDocument = new XMLDocument(getresult);
var decoder:SimpleXMLDecoder = new SimpleXMLDecoder(true);
var resultObj:Object = decoder.decodeXML(xmlDoc);
if(resultObj.root.hasOwnProperty("row"))
{
if(resultObj.root.row is ArrayCollection)
{
tablevalue = resultObj.root.row;
}
else if(resultObj.root.row is Object)
{
tablevalue.addItem(resultObj.root.row);
}
}
MainTable.dataProvider=tablevalue;
}
protected function areachart_clickHandler():void
{
var chartview:areachart = areachart(PopUpManager.createPopUp(this,areachart,false));
chartview.viewtid=viewtid;
}
protected function TableView_creationCompleteHandler(event:FlexEvent):void
{
TableView.isPopUp =true;
}
]]>
fault="Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)"
showBusyCursor="true"/>
creationComplete="getTableValue(viewtid)"/>
这个Module组件本身是其它组件调用出来的. 在其它组件当中的调用代码如下:
private function viewTablesList():void
{
var tid:int=tableslist.selectedItem.data;
var tbview:tableview = tableview(PopUpManager.createPopUp(this,tableview,false));
tbview.viewtid=tid;
}
Module当中的viewtid就是用来设置显示哪一张表格的, 这里这个值由一个列表控件的tableslist.selectedItem.data决定. 如果是单独测试上面那个Module, 可以直接给viewtid指定一个值.
数据库三个字段:
显示效果: