摘要:ThinkPHP是一個小型網站很常用的低階框架,但是不專業的文件和編碼導致使用者很容易只知其表不知其裡。這裡僅就官方文件中未曾提及的在thinkphp中使用jquery實作ajax 非同步互動略作總結。
環境:ThinkPHP3.2.3,jQuery
##閱讀目錄:
正文:
在一般的網站中,都需要用到jquery或其他框架(例如 angular)來處理前後端資料互動。在thinkphp在後台也內建了一些函式用於資料互動(例如ajaxReturn())。本文的目的是打通jquery ajax到thinkphp的前後端資料互動過程。
前言:
一、thinkphp關於ajax的介紹
1.1 ajaxReturn:
\Think\Controller類別提供了ajaxReturn方法用於AJAX呼叫後#返回資料給#客戶端(視圖、範本、js等)。並且支援JSON、JSONP、XML和EVAL四種方式給客戶端接受資料(預設JSON)。 (連結:http://document.thinkphp.cn/manual_3_2.html#ajax_return)
##設定方式:convention .php中定義了預設編碼類型為DEFAULT_AJAX_RETURN => 'JSON',
分析:ajaxReturn()呼叫了json_encode()將數值轉換成json資料儲存格式,常用的數值是陣列。
注意:The value being encoded can be any type except a resource(資源檔).All string data must be UTF-8 encoded.(連結:http://php.net/manual/en/function.json-encode.php##)#範例:
$data['status'] = 1;
$data['content'] = 'content';#$this->ajaxReturn($data);
1.2
請求類型:##系統內建了一些常數用來判斷請求類型,例如:
IS_GET 判斷是否是
##GET方式提交IS_POST 判斷是否為
POST方式提交 IS_PUT 判斷是否為PUT方式提交 IS_DELETE 判斷是否為DELETE方式提交 IS_AJAX 判斷是否為AJAX#提交 REQUEST_METHOD 目前提交類型 目的:一方面可以針對請求類型做出不同的邏輯處理,另一方面可以過濾不安全的請求。 (連結:http://document.thinkphp.cn/manual_3_2.html#request_method##) 使用方法: ## $this->success(' }else{# ”「非法請求」 '); }#1.3 #} 跳躍與重新導向: 功能比較雞肋,在ajax http://document.thinkphp.cn/manual_3_2.html#page_jump_redirect)## 二、 的介紹: 2.1 官網關於 #的介紹:jQuery.ajax() 方法用於執行AJAX (非同步HTTP)請求。 (連結:http://www.jquery123.com/jQuery.ajax/)##語法: $.ajax({name:value, name:value, ... }),該參數規定 請求的一個或多個名稱/值對。 常見參數: 預設: 'GET') #類型: String ("POST" 或 , 預設為"GET"。注意:其它HTTP 請求方法,如PUT 和DELETE 也可以使用,但僅有部分瀏覽器支援。 url (預設: 目前頁面位址#) #類型: String 發送請求的位址。 async (預設: true)(1.8版本已棄用) 類型: Boolean #預設設定下,所有請求都是非同步請求(也就是說這是預設設置為 true )。如果需要傳送同步請求,請將此選項設為 false 。 data 類型: Object, String 傳送到伺服器的資料。將自動轉換為請求字串格式。 GET 請求中將附加在 URL 後面。查看 processData 選項說明,以禁止此自動轉換。物件必須為"{鍵:#值}"格式。如果這個參數是一個數組,jQuery會依照 traditional 參數的值, 將自動轉換為一個同名的多值查詢字符字串(看下面的說明)#。註:如 {foo:["bar1", "bar2"]} #轉換成 '&foo=bar1&foo=bar2'#。 dataType (預設: Intelligent Guess (xml, json, script, or html)) 類型: String 預期伺服器傳回的資料類型。如果不指定,jQuery 將自動根據HTTP 套件MIME ##資訊來智慧判斷,例如 XML MIME類型就被辨識為XML#。在1.4中,JSON#就會產生一個JavaScript對象,而script則會執行這個腳本。隨後伺服器端傳回的資料會根據這個值解析後,傳遞給回呼函數。舉例: 把回應的結果當作JSON 執行,並回傳一個JavaScript物件。在jQuery 1.4 中,JSON 格式的資料以嚴格的方式解析,如果格式有錯誤, jQuery都會被拒絕並且拋出一個解析錯誤的例外。 (請參閱json.org的更多信息,正確的JSON格式。) error 類型: Function( jqXHR jqXHR, String textStatus, String errorThrown ) 要求失敗時呼叫此函數。有以下三個參數:jqXHR (在jQuery 1.4.x前為XMLHttpRequest) 物件、描述發生錯誤類型的一個字串和捕獲的異常物件。如果發生了錯誤,錯誤訊息(第二個參數)除了得到null之外,還可能是"timeout", "error", "abort " ,和"parsererror"。 當一個HTTP錯誤發生時,errorThrown 接收HTTP狀態的文字部分,例如: "Not Found"(找不到) 或#"Internal Server Error."(伺服器內部錯誤)。 從jQuery 1.5開始, 在error設定可以接受函數組成的陣列。每個函數將被依序呼叫。 注意:此處理程序在跨網域腳本和JSONP形式的請求時不被呼叫。這是一個 Ajax Event。 success 類型: Function( Object data, String textStatus, jqXHR jqXHR ) #請求成功後的回調函數。這個函數傳遞3個參數:從伺服器傳回的數據,並根據dataType參數進行處理後的數據,一個描述狀態的字串 ;還有jqXHR(在jQuery 1.4.x前為# XMLHttpRequest) 物件。在jQuery 1.5, 成功設定可以接受一個函數陣列。每個函數將被依序呼叫。這是一個Ajax Event 其他jQuery-ajax-settings
#http://www.jquery123.com/#jQuery-ajax-settings# ##在js中把id作為資料傳送到伺服器, 儲存一些資料到伺服器上, 一旦請求完成就通知使用者。 如果請求失敗,則提醒使用者。 中使用success##和error參數判斷請求結果成功或失敗,並執行下一步操作。 2.2.2 json和ajax的关系? 在上面关于jquery.ajax的介绍中提到了,json可以作为一个ajax函数的dataType,这样数据就会通过json语法传输了。(链接:http://www.cnblogs.com/haitao-fan/p/3908973.html) 在jquery的ajax函数中,只能传入3种类型的数据: >1.json字符串:"uname=alice&mobileIpt=110&birthday=1983-05-12" >2.json对象:{uanme:'vic',mobileIpt:'110',birthday:'2013-11-11'} >3.json数组: 2.2.3 json的编解码和数据转换: 2.2.2中提到的json对象是更方便与js数组、js字符串或php数组、php字符串进行数据转化的json类型。下面以json对象为例讲解一下json对象与js和php的数据类型转化。 json对象转化成数组: 想要将表单数据提交到后台,需要先从表单获取数据/数据集: serialize和serializeArray的区别是serialize()获取到序列化的表单值字符串,serializeArray()以数组形式输出序列化表单值。举例: 相对来说,serializeArray()和最终想要得到的json数组更加相似。只不过需要将包含多个name-value形式json对象的json数组改写成'first_name':'Hello'形式的json对象。 这里使用第二种方法举例,可以起名为change_serialize_to_json(): 完整流程: 在js端将表单数据转化为json形式的其他函数: 将json字符串转换为json对象: str_replace() 函数用于替换掉字符串中的特定字符,比如替换掉数据转换后多余的空格、'/nbsp'等 注意:serialize和serializeArray()函数在处理checkbox时存在无法获取未勾选项的bug,需要自己编写函数改写原函数,举例: //value赋值为off是因为正常的serializeArray()获取到的勾选的checkbox值为on。 三、使用js操作DOM实现局部刷新: 实现局部刷新的途径: 1、假设页面有查询form和结果table。 2、点击查询form的提交,触 发js自定义的submit事件,在submit函数中对获取的表单数据检测后如果符合要求就传递给控制器,控制器从数据库获取结果数组后返回给ajax的success。对返回给ajax的结果数组,可以创建一个refresh()函数,或直接在success中用jQuery(或其他js)操纵结果table(DOM),比如删除tbody节点下的所有内容,并将结果数组格式化后添加到tbody下面。 举例: //1、php中的form表单 //2、js校验表单并发起ajaxvar menuId = $("ul.nav").first().attr("id");
var request = $.ajax({
url: "script.php",
type: "POST",
data: {id : menuId},
dataType: "html"
});
request.done(function(msg) {
$("#log").html( msg );
});
request.fail(function(jqXHR, textStatus) {
alert( "Request failed: " + textStatus );
});
[
{"name":"uname","value":"alice"},
{"name":"mobileIpt","value":"110"},
{"name":"birthday","value":"2012-11-11"}
]
<script type="text/javascript">
var jsonStr = '[{"id":"01","open":false,"pId":"0","name":"A部门"},{"id":"01","open":false,"pId":"0","name":"A部门"},{"id":"011","open":false,"pId":"01","name":"A部门"},{"id":"03","open":false,"pId":"0","name":"A部门"},{"id":"04","open":false,"pId":"0","name":"A部门"}, {"id":"05","open":false,"pId":"0","name":"A部门"}, {"id":"06","open":false,"pId":"0","name":"A部门"}]';
// var jsonObj = $.parseJSON(jsonStr);
var jsonObj = JSON.parse(jsonStr)
console.log(jsonObj)
var jsonStr1 = JSON.stringify(jsonObj)
console.log(jsonStr1+"jsonStr1")
var jsonArr = [];
for(var i =0 ;i < jsonObj.length;i++){
jsonArr[i] = jsonObj[i];
}
console.log(typeof(jsonArr))
</script>
var serialize_string=$('#form').serialize();
得到:a=1&b=2&c=3&d=4&e=5
var serialize_string_array=$('#form').serializeArray();
得到:
[
{name: 'firstname', value: 'Hello'},
{name: 'lastname', value: 'World'},
{name: 'alias'}, // 值为空
]
var data = {};
$("form").serializeArray().map(function(x){
if (data[x.name] !== undefined) {
if (!data[x.name].push) {
data[x.name] = [data[x.name]];
}
data[x.name].push(x.value || '');
} else {
data[x.name] = x.value || '';
}
});
输出:{"input1":"","textarea":"234","select":"1"}
var serialize=$('#form').serialize()结果(得到一个字符串,用serializeArray()更好,其中中文都会转换成utf8):
serial_number=SN2&result=%E9%9D%9E%E6%B3%95
var serialize_array=$('#form').serializeArray()结果(结果是json对象数组):
Array [ Object, Object ]
var data=change_serialize_to_json(serialize_array)的结果是(以第二种转换方法为例,结果是json对象):
Object {serial_number: "SN2", result: "非法" }
var json_data=JSON.stringify(data)(结果是json字符串):
{"serial_number":"SN2","result":"非法"}
eval("(" + status_process+ ")");
json字符串转化成json对象:
// jquery的方法
var jsonObj = $.parseJSON(jsonStr)
//js 的方法
var jsonObj = JSON.parse(jsonStr)
json对象转化成json字符串:
//js方法
var jsonStr1 = JSON.stringify(jsonObj)
JSON.parse()用于从一个字符串中解析出json对象。JSON.stringify()相反,用于从一个对象解析出字符串。
$.fn.mySerializeArray = function () {
var a = this.serializeArray();
var $radio = $('input[type=radio],input[type=checkbox]', this);
var temp = {};
$.each($radio, function () {
if (!temp.hasOwnProperty(this.name))
{
if ($("input[name='" + this.name + "']:checked").length == 0)
{
temp[this.name] = "";
a.push({name: this.name, value: "off"});
}
}
});
return a;
};
<p class="modal fade hide" id="add_engineer_modal" tabindex="-1" role="dialog">
......
<form id="add_engineer_modal_form" class="form-horizontal">
<fieldset>
......
<button type="button" class="btn btn-primary" id="add_engineer_modal_submit" onclick="add_engineer_modal_submit()" >提交更改</button>
......
</fieldset>
</form>
</p>
function add_engineer_modal_check_value() {
//以edit_modal_check_value()为模板
var serialize_array_object = $("#add_engineer_modal_form").mySerializeArray();
var data = change_serialize_to_json(serialize_array_object);
var check_results = [];
check_results['result'] = [];//保存错误信息
check_results['data'] = data;//保存input和select对象
//check_employee_number是自定义判断员工号函数。
if (check_employee_number(data['employee_number']) == false)
{
check_results['result'].push("请输入有效的员工号(可选)");
}
return check_results;
}
function add_engineer_modal_submit() {
var check_results = add_engineer_modal_check_value();
if (check_results['result'].length == 0)
{
var json_data = JSON.stringify(check_results['data']); //JSON.stringify() 方法将一个JavaScript值转换为一个JSON字符串(ajax要求json对象或json字符串才能传输)
$.ajax({
type: 'POST',
url: add_engineer_url, //在php中全局定义url,方便使用thinkphp的U方法
data: {"json_data": json_data}, //ajax要求json对象或json字符串才能传输,json_data只是json字符串而已
dataType: "json",
success: function (data) {
console.log("数据交互成功");
},
error: function (data) {
console.log("数据交互失败");
}
});
}
else
{
//弹出错误提示alert
}
return 0;
}
3、控制器返回数组给js
public function add_engineer() {
if (IS_AJAX)
{
$posted_json_data = I('post.json_data');
$posted_json_data_replace = str_replace('"', '"', $posted_json_data);
$posted_json_data_replace_array = (Array)json_decode($posted_json_data_replace);
//处理数据库事务写入,通过判断写入结果来区分ajaxReturn的结果
//可以将所有想要返回的数据放在一个数组中,比如新增的行id、插入数据库的操作是否成功
//如果操作数据库成功就返回如下结果。
$user_table->commit();
$data['result'] = true;
$data['pk_user_id'] = $data_add_user_result;
$this->ajaxReturn($data);
return 0;
}
}
改写js:
在js的ajax中,如果整个ajax正常交互,就会走success函数,否则会走error函数,一般情况下,error出现的原因都是传输的数据不符合要求。
在success中的data就是ajaxReturn中传输的数组,举例:
success: function (data) {
if (data['result'] == false)
{
alert(data['alert']);
}
else
{
$('#add_engineer_modal').modal('hide');
$('#user_list_table tr').eq(0).after('<tr></tr>');
//这里就可以使用data['pk_user_id']了。
$('#user_list_table tr').eq(1).append('<td>'+data['pk_user_id']+'</td>');
}
},
四、总结
整个过程是:
在php中编写页面中的表单、提交按钮等;
在js中對php中的按鈕事件加入校驗和觸發函數,在js函數內,如果js物件的格式和內容正確就向控制器url( #php中初始化)發起ajax請求;
控制器中的對應操作回應ajax 請求,並判斷資料後做資料庫讀寫操作,然後對資料庫操作結果做出判斷,ajaxReturn回傳js所需的陣列;
當ajax成功返回時,js中ajax 的success裡面使用js重寫(或初始化)需要顯示的資訊。
這樣就完成了ajax異步局部刷新。
以上是thinkphp中有關ajax異步局部刷新的介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!