oGrid 介绍如何从 server 取的资料
接着前次 oGrid 初探,其中有介绍如何操作local 资料,本次介绍如何从 server 取的资料。
依照 MVC 架构原理以及一条小龙本身经验来看,一个好的架构,必须要有着分工明确的设计层次,让后续接手的人,很清楚知道该处该放哪些资料以及 code。
由此思路 oGrid 应该要能让设计者,可以由后端来处理资料,再传给元件来做处理,而不要一部分逻辑在前端一部分在后端,虽然要把很多逻辑都放到后端来处理,会加深设计的困难度,但如此一来,就可得到前述的分工明确的要求,尽量让前端元件,单纯只做显示地处里或是前端UI与使用者互动的处里,然后把资料相关的逻辑都给后端来处理。
而且如能维持本精神来设计,到后面前端的架构应该是很干净,甚至应该能给不同专案来使用,所以而此可知其实前面设计也许成本变多,但到后面成本反而降低了,这就是一个好的架构,所带来的优点。
下面,先来看一下,oGrid 预计要后端来处理的 JSON 资料的格式,然后就可以思考一下,后端该如何设计来呈现这样的资料格式。
这边资料格式有几个重点,total, rows, columns。
total :是资料总笔数,oGrid 会根据此来进行分页的呈现,第一次 init 时,只需要传回第一分页的资料,等到下一分页时 oGrid 会再发送要求来抓取下一分页的资料。
rows:是资料主体,除了描述资料,还可以再每列上或是在特定的 cell 加注 style,如下面第一列的方式,这个模式可以方便开发人员在特定资料来标注颜色,例如:单价过低 等等。
columns:告诉 oGrid 栏位的定义,以及呈现方式,column 里面属性分别的意义,可以参考官网上的说明。
{"total":30, "rows":[ {"Id":1,"name":"test1","addr":"address - 1","phone":"P1", "cellStyle":[{"field":"phone","className":"error","style":null},{"field":"name","className":"error","style":null}]}, {"Id":2,"name":"test2","addr":"address - 2","phone":"P2"},{"Id":3,"name":"test3","addr":"address - 3","phone":"P3"}, {"Id":4,"name":"test4","addr":"address - 4","phone":"P4"},{"Id":5,"name":"test5","addr":"address - 5","phone":"P5"}, {"Id":6,"name":"test6","addr":"address - 6","phone":"P6"},{"Id":7,"name":"test7","addr":"address - 7","phone":"P7"}, {"Id":8,"name":"test8","addr":"address - 8","phone":"P8"},{"Id":9,"name":"test9","addr":"address - 9","phone":"P9"}, {"Id":10,"name":"test10","addr":"address - 10","phone":"P10"}], "columns":[{"field":"Id","title":"code","width":"100px","hidden":false}, {"field":"name","title":"name","width":"100px","hidden":false}, {"field":"addr","title":"address","width":"100px","hidden":false}, {"field":"phone","title":"phone","width":"100px","hidden":false}]}
下面是 后端的程式码,用 PHP 写成,老实说 .Net 跟 PHP 比起来,PHP 在做 JSON 资料的处理真的是比较简单且直觉。
首先读者要先建立 几个 class 来处理上述资料,使用对应 class 处理好资料后,丢给 PHP 就会自动帮你生成上述资料的格式了。
一是 rows 资料主体,这里用 cutomer 这个 class 来处理客户资料,下面的 sample code 只是简单示范如何处理资料,实务上需要再加上资料库的读取处理。如上述,下面 Sample 也有示范如何在 rows 中包含 rowStyle 以及 cellStyle 这两个 class 的使用,在有需要的时候可以用来描述资料显示的样式,但非必要选项。
二是 columns 这个部分的 code 其实算是一个通用的 server code,实务上可以把这部分包成一个共用类别来处理。
oGrid 在跟 server 要资料,会传三个参数来告诉 server side 要给 oGrid 怎样的资料,参数分别说明如下:
type:有 init, data 两种,一开始 oGrid init 时 type 为 init,后面 user 切换分页时,type=data。
page:代表目前 oGrid 所在分页。
rows:代表每个分页要显示的资料笔数。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <?php 2 class column 3 { 4 public $field; 5 public $title; 6 public $width; 7 public $hidden; 8 9 function column($id, $caption) 10 { 11 $this->field = $id; 12 $this->title = $caption; 13 $this->width = "100px"; 14 $this->hidden = false; 15 } 16 } 17 class customer 18 { 19 public $Id; 20 public $name; 21 public $addr; 22 public $phone; 23 } 24 class rowStyle 25 { 26 public $className; 27 public $style; 28 } 29 class cellStyle 30 { 31 public $field; 32 public $className; 33 public $style; 34 } 35 $type = $_GET["type"]; 36 $page = isset($_POST['page']) ? intval($_POST['page']) : 0; 37 $rows = isset($_POST['rows']) ? intval($_POST['rows']) : 10; 38 39 $start = $page * $rows + 1; 40 $last = $start + $rows; 41 $items = array(); 42 for($i=$start;$i< $last;$i++){ // deal rows data 43 $obj = new customer(); 44 $obj->Id = $i; 45 $obj->name = "test".$i; 46 $obj->addr = "address - ".$i; 47 $obj->phone = "P".$i; 48 if($i == 1) 49 { 50 //$obj->rowStyle = new rowStyle(); 51 ////$obj->rowStyle->style = "background-color:#ffee00;"; 52 //$obj->rowStyle->className = "error"; 53 54 // for cell 55 //$obj->cellStyle = new cellStyle(); 56 //$obj->cellStyle->field = "phone"; 57 //$obj->cellStyle->className = "error"; 58 59 $obj->cellStyle = array(); 60 $cs = new cellStyle(); 61 $cs->field = "phone"; 62 $cs->className = "error"; 63 array_push($obj->cellStyle, $cs); 64 65 $cs = new cellStyle(); 66 $cs->field = "name"; 67 $cs->className = "error"; 68 array_push($obj->cellStyle, $cs); 69 } 70 array_push($items, $obj); 71 } 72 $result["total"] = 30; 73 $result["rows"] = $items; 74 75 76 if($type == "init") // deal columns when type is init 77 { 78 $columns = array(); 79 $col = new column("Id", "code"); 80 array_push($columns, $col); 81 $col = new column("name", "name"); 82 array_push($columns, $col); 83 $col = new column("addr", "address"); 84 array_push($columns, $col); 85 $col = new column("phone", "phone"); 86 array_push($columns, $col); 87 $result["columns"] = $columns; 88 } 89 90 echo json_encode($result); 91 92 ?>
上面 code 要注意的是只有 type=init 时才需要处理 columns,如果是切换分页时,type = data。
最后,介绍的是 前端的 oGrid 对应的操作,这部分相对于 server code 简单很多,只要如下面 sample 设定好 loadURL 来告诉 oGrid 到 server 哪抓取JSON 资料,再呼叫 load (同步),oGrid 就会到 server 端抓回资料,有必要读者 来可以在 load 后针对抓取后的资料在来做处理,如不需要,则可直接呼叫 renderData 来描绘UI。
下面 sample 有一个特别的地方,就是 obj.reloadPage = false;, oGrid 预设 reloadPage=true,代表每次有更换分页的动作都会到 server 端来要求传回对应的分页资料,如果设定为 false 则 oGrid 会检查该分页资料是否有抓取过,没有抓取过才会去server 端抓取,如此因为不用每次都到 server 端来要资料,所以效率提高很多。但相对也会有点风险,因为 server 端资料 如果被更改过,oGrid 却没有重新 reload 资料,则会造成前端资料跟server 不一致的错误,所以读者要看需求来决定是否要设 false。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 <HTML> 3 <HEAD> 4 <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> 5 <META http-equiv="Content-Type" content="text/html; charset=utf-8"> 6 <TITLE>set row/column background color from server</TITLE> 7 <script type="text/javascript" src="./oGrid.js"></script> 8 <link type="text/css" rel="stylesheet" href="oGrid.css" /> 9 <style type="text/css"> 10 .oGrid .error{background-color:#ffee00;color:red;} 11 </style> 12 <SCRIPT language="javascript"> 13 var obj; 14 window.onload = function () { 15 obj = new obj4u.oGrid(dataTable); 16 obj.event.AddEvent("onLog", showLog); 17 obj.event.AddEvent("onSelectedRow", oGrid_SelectedRow); 18 19 obj.loadUrl = 'http://obj4u.com/samples/getJSON3.php'; 20 //obj.reloadPage = false; // when this page only view data can use this function. 21 obj.load("init"); 22 obj.renderData(); 23 } 24 25 function oGrid_SelectedRow(rowElement, row) { 26 var selectedRows = obj.getSelectRows(); 27 alert(rowElement.rowIndex + "," + row.index + " , " + selectedRows.length + "," + row["Id"]); 28 } 29 30 function showLog(msg) { 31 alert(msg); 32 } 33 34 35 </SCRIPT> 36 </HEAD> 37 <BODY> 38 39 <TABLE id="dataTable"> 40 </TABLE> 41 42 </BODY> 43 </HTML>
上述 sample 取自 http://obj4u.com/samples/example08.html,一条小龙在加以解释,有需要可在连该网址来试试。