0.前言 前些時間順著Yeelink學習了RESTFUL,使用PHP和Slim架構嘗試實現簡單的REST API,樹莓派可通過GET方法獲得JSON資料包,通過這種方式實現了樹莓派和伺服器(我的PC)的互動。但是由於沒有WEB前端,所以只能使用cURL工具或直接修改資料庫的方式改變LED狀態,體驗非常差。 前端架構體驗: 【前端學習1——Bootstrap jquery ajax】 REST API入門體驗可參考: 【PHP再學習4—— slim架構學習和使用】 【PHP再學習5——RESTFul架構 遠端控制LED】 受到【開源IOT——一個最小的物聯網系統設計方案及源碼】一文的影響。我決定除了伺服器和嵌入式側之外,我應該再多做一些。
1.REST API 使用PHP Slim架構構造REST API。其中有兩個API和本例有關,一個為獲得所有LED資訊,LED資訊包括ID,描述和狀態;另一個為更新LED狀態,LED狀態只有兩種ON或者OFF,代表開啟和關閉。【獲得全部LED資訊】HTTP 方法 GETHTTP URL /api/ledsHTTP 返回 如所示 【說明】1.total代表記錄總數,使用total主要便於分頁處理 2.rows代表具體記錄,rows之後為json數組 3.若在URL中沒有指定page和rows,預設page為1,rows為10.簡單說預設僅返回10個。
圖1 GET方法獲得LED資訊
【更新某個LED狀態】HTTP 方法 PUTHTTP URL /api/leds/<leds_id>/statusHTTP 要求內容 {“status”:"on"}或{“status”:"off"}HTTP 響應 {“success”:“true”}或{"success":"false"}
圖2 PUT請求分析2.更新表格【1】建立一個表格,但不填充內容
<div class="row"> <div class="span12"> <table class="table table-hover" id="ledsTable"> <thead> <tr> <th>編號 ID</th> <th>描述 DESC</th> <th>狀態 STATUS</th> <th>動作 ACTION</th> </tr> </thead> </table> </div> </div>
【2】更新表格——ajax方法 【JS代碼】
function updateAll() { // 動態表格內容 $.getJSON('http://localhost/api/leds',function(data){ // data.total 表示記錄總數 // data.row 表示記錄內容 console.log(data.total); $.each( data.rows , function( index , item){ // 取出 id description status var id = item.id; console.log(id); var description = item.description; console.log(description); var status = item.status; console.log(status); console.log(status); var btnStyle = 'btn-success'; var btnText; // 修改按鈕樣式,ON為綠色 OFF為白色 if( status == 'on'){ btnStyle = 'btn-success'; btnText = 'O N'; } else { btnStyle = 'btn-default'; btnText = 'OFF'; } // 插入一行,很遺憾 javascript沒有 format var newRow = '<tr dev_id="' + id + '">' + '<td>' + id + '</td>' + '<td>' + description + '</td>' + '<td>' + status + '</td>' + '<td>' + '<button type="button" class="btn btn-xs ' + btnStyle + '">' + btnText + '</button>' + '</td>' + '</tr>'; $('#ledsTable').append(newRow); }); }); }
【幾點說明】 1.$.getJSON('http://localhost/api/leds',function(data) 使用ajax的getJSON方法,URL為http://localhost/api/leds;若獲得HTTP響應,響應內容在data中。 2.$.each( data.rows , function( index , item) 使用each方法遍曆所有data.rows內容——所有LED資訊,LED資訊位於item中,而index為序號(和LED ID還不太相同) 3.var newRow = '<tr dev_id="' + id + '">' + 給所有的tr標籤加上了 dev_id屬性,便於LED改變狀態時獲得編號。 4.$('#ledsTable').append(newRow); 增加到表格中。
3.按鈕控制 【基本流程】 按下表格末尾的button,在按鈕事件處理中(確切地說為回調處理)找到tr標籤中的裝置ID,再從該行的第2個td標籤中找到text,該text為當前的LED狀態,最後裝配一個PUT請求翻轉LED狀態。
【JS代碼】
$("table").delegate("button", "click", function(){ console.info($(this)); // 嘗試獲得 <button>text</button> console.log($(this).text()); var $tr_obj = $(this).parent().parent(); // tr元素中包含 dev_id屬性 var dev_id = $tr_obj.attr('dev_id'); console.log( dev_id ); // 訪問該tr元素的所有子td元素 var $td_obj = $($tr_obj).children("td"); // 所有td元素的第二個 var $status_obj = $($td_obj).eq(2); var status_str = $status_obj.text(); console.log(status_str); // 改變按鈕樣式 if( status_str == "on"){ $(this).removeClass('btn-success');$(this).addClass('btn-default'); $(this).text("OFF"); $status_obj.text("off"); send_ledctrl( dev_id , "off"); }else{ $(this).removeClass('btn-default');$(this).addClass('btn-success'); $(this).text("O N"); $status_obj.text("on"); send_ledctrl( dev_id , "on" ); } }); function send_ledctrl(dev_id, cur_status){ $.ajax({ url: '/api/leds/' + dev_id + '/status', // /api/leds/1 async: true, dataType: 'json', type: 'PUT', data: JSON.stringify({status:cur_status}), success: function(data, textStatus){ // 列印返回內容 {"success":true} console.log(data.success); }, error: function(jqXHR, textStatus, errorThrown){ console.log("error"); }, }); }
【幾點說明】 1. $("table").delegate("button", "click", function(){ 使用table的委託方法,子類為button,事件為click。delegate可以為動態建立的標籤增加事件,有別於on方法。 2.var $tr_obj = $(this).parent().parent(); 獲得tr標籤,採用子類找父類的方法。在這裡$tr_obj為一個jquery對象,所有前面加$以標記。 3.$(this).removeClass('btn-success');$(this).addClass('btn-default'); 根據LED的狀態,清除BUTTON的舊樣式,獲得新樣式。
4.最終效果
圖3 最終效果