พอดีเห็นเพื่อนโพส OpenUI5 ก็สงสัยว่ามันคืออะไรแถมมี comment เรื่อง angularjs มาอีกนิดหน่อย ก็เลยเป็นโอกาสดีผมเองก็ไม่เคยใช้ทั้งคู่ เลยเอามาลองเล่นดูละกัน

OpenUI5 คือ lib UI ของ javascript ที่พัฒนาขึ้นมาโดย SAP หรือจริงๆที่เรียกว่า SAPUI5 โดยเอามาเปิดเป็น opensource ให้สาธารณะชนได้ลองใช้กัน

AngularJS เป็น javascript framework ที่ทำงานอยู่บน client side มีลักษณะเป็นแบบ MVC

-ผมก็ไม่ค่อยรู้เรื่อง Javascript เท่าไหร่ แค่พอทำได้ แต่ถ้าซับซ้อนมากก็บาย-

ในครั้งนี้ผมจะสร้าง REST webservice ด้วย JAX-RS บน Glassfish 4 ในลักษณะนี้

@Path(“product”)
public class MyAPI {

@Context
private UriInfo context;

/**
* Creates a new instance of MyAPI
*/
public MyAPI() {
}

/**
* Retrieves representation of an instance of rest.MyAPI
* @return an instance of java.lang.String
*/
@GET
@Produces(“application/json”)
public String getJson() {
List<Product> products = new ArrayList<Product>();
products.add(new Product(“X1”, 26.0, 100));
products.add(new Product(“X2”, 2116.0, 1300));
products.add(new Product(“X3”, 246.0, 400));
products.add(new Product(“X4”, 36.0, 1040));
Gson gson = new Gson();
return gson.toJson(products);
}

ก็คือถ้ามีใคร access /api/product ด้วย get method เราจะ return jason array ที่ประกอบไปด้วยรายการ product ของเรา

AngularJS

กว่าจะเขียนออกมาได้ต้องดำผุดดำว่ายพอสมควรเนื่องจากความรู้ JS ค่อยข้างต่ำเตี้ย อธิบายแบบคร่าวๆคือ การใช้ angularjs นั้นคล้ายกับการสร้าง View ใน Rails หรือ Play หรือ Framework อื่นๆนั่นแหละ เพียงแต่ที่เราจะ return object มาที่ view โดยตรง เราจะเปลี่ยนมาใช้เป็น JSON แทนนั่นเอง โดย angular จะทำหน้าที่ส่ง ajax request ไป ลักษณะการทำงานเหมือนเป็น UI ที่ต่อกับ API ด้านหลังอะไรประมาณนั้น

โดยเราจะต้องสร้าง module ในที่นี้คือ myProduct โดยไม่ได้มี dependency กับ module อิ่นๆ “[ ]”  จากนั้นเราก็สร้าง controller ใน module นี้โดยมีชื่อว่า myController ซึ่งมีตัวแปร $http ที่จะโดน inject ด้วย $http อีกที (ยังไม่เข้าใจ) ซึ่งตรงนี้เราสามารถใส่ได้หลายตัวแปร และหลาย dependencies หลังจากนั้นก็จะส่ง http get ไปยัง api ของเรา

สร้าง controller ด้วย directive ng-controller โดยตั้งชื่อว่า my และก็จะใช้ ng-repeat เพื่อทำการ loop ผ่าน array ของ product โดนใช้ expression {{ }} ในการอ่านค่าจากตัวแปร โดยใน expression เราสามารถใส่ ” | ” ที่ทำงานเหมือนใน unix ได้อีกด้วย

angular

html

<html ng-app=”myProduct”>
<head>
<meta charset=”UTF-8″>
<meta name=”viewport” content=”width=device-width, initial-scale=1.0″>
<script type=”text/javascript” src=”angular/angular.js”></script>
<script type=”text/javascript” src=”angular/app.js”></script>
<script type=”text/javascript” src=”angular/ng-table.min.js”></script>
<link data-require=”ng-table@*” data-semver=”0.3.0″ rel=”stylesheet” href=”http://bazalt-cms.com/assets/ng-table/0.3.0/ng-table.css&#8221; />
<link data-require=”bootstrap-css@*” data-semver=”3.0.0″ rel=”stylesheet” href=”//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css” />

</head>
<body>
<div ng-controller=”myController as my” class=”row”>
<div class=” col-xs-9″>
<h1>Products</h1>
<table class=”table”>
<tr><td>Name</td><td>Price</td><td>Stock</td></tr>
<tr ng-repeat=”product in my.products”>
<td data-title=”‘Name'”>{{product.name}}</td>
<td data-title=”‘Price'”>{{product.price | currency}}</td>
<td data-title=”‘Stock'”>{{product.stock}}</td>
</tr>
</table>
</div>
</div>
</body>
</html>

app.js

var app = angular.module(‘myProduct’, [ ]);
app.controller(‘myController’, [‘$http’, function($http) {
var my = this;
my.products = [];
$http.get(‘/openUI5/api/product’).success(function(data) {
my.products = data;
});

}]);

OpenUI5

openui

ปรับปรุงจากตัวอย่างนี้ http://jsbin.com/openui5-table-json/6/edit โดยเราจะมี Table, Model และ controller (UI)

ก่อนอื่นเราก็จะสร้าง table ที่มี column “Product Name”, “Price”, “Stock” โดยเชื่อมกับ controller โดยตัว controller น่าจะเป็นตัวบอก คุณลักษณะของ row ใน column นั้นๆ(เดา) พอได้ตารางแล้ว เราก็จะเอา data เข้าไปในตาราง

สร้างตัวแปร oModel จาก JSONModel แล้วใช้คำสั่ง loadData ในการ load url ของเราเข้าไปหลังจากนั้นก็ทำการ setModel ให้ table แล้วก็เลือก bindRows โดยในที่นี้คือ Root ของ Json Array (เราสามารถเลือก bind กับ portion ไหนใน array ใหญ่ๆก็ได้เช่น /Root/A/B) เสร็จแล้วก็เอาไปแสดงผลใน content

<html>
<head>
<meta charset=”UTF-8″>
<meta name=”viewport” content=”width=device-width, initial-scale=1.0″>
<script id=’sap-ui-bootstrap’ type=’text/javascript’
src=’https://openui5.hana.ondemand.com/resources/sap-ui-core.js&#8217;
data-sap-ui-theme=’sap_bluecrystal’
data-sap-ui-libs=’sap.ui.commons,sap.ui.table’></script>
<script>

// create the DataTable control
var oTable = new sap.ui.table.Table({editable: true});

// define the Table columns
var oControl = new sap.ui.commons.TextView({text: “{name}”}); // short binding notation
oTable.addColumn(new sap.ui.table.Column({label: new sap.ui.commons.Label({text: “Product Name”}),template: oControl,width: “100px”}));
oControl = new sap.ui.commons.TextField().bindProperty(“value”, “price”);
oTable.addColumn(new sap.ui.table.Column({label: new sap.ui.commons.Label({text: “Price”}),template: oControl, width: “80px”}));
oControl = new sap.ui.commons.TextField().bindProperty(“value”, “stock”);
oTable.addColumn(new sap.ui.table.Column({label: new sap.ui.commons.Label({text: “Stock”}),template: oControl, width: “80px”}));

// create a JSONModel, fill in the data and bind the Table to this model
var oModel = new sap.ui.model.json.JSONModel();

oModel.loadData(“/openUI5/api/product”);
oTable.setModel(oModel);
oTable.bindRows(“/”);

// finally place the Table into the UI
oTable.placeAt(“content”);

</script>
</head>
<body>
<div id=”content”></div>
</body>
</html>

learning curve openUI นั้นเอาเข้าจริงก็ไม่สูงเท่าไหร่ แต่ code มันค่อนข้างเยอะไปนิด ส่วน angularJS เอามาทำง่ายๆแบบนี้ไม่มีปัญหาในการเข้าใจ แต่ถ้าลองเอา ngTable มาใช้ร่วมกัน มันจะเริ่มซับซ้อนเข้าไปอีกขั้น ไม่เหมือนกับ javascript ด้วย jquery หรือ openUI ที่เคยทำกัน ต้องอาศัยความเข้าใจพอสมควร

สรุป angular นั้นน่าสนใจ น่าเอามาทำ internal application (เข้าใจว่า search engine ไม่อ่าน angular การทำ SEO คงยากขึ้นไปอีก) การเขียน app แบบง่ายๆไม่ซับซ้อนมาก สามารถทำได้รวดเร็วดี ไวกว่า jquery โดดๆ แล้วก็ code อ่านง่ายกว่าด้วย