繼上一篇,DataTable + 搜尋 的AJAX完成後,現在要進入第一個功能,新增。
這一系列的文章會稍微著重在於jQuery 對 Controller的溝通,然而實作功能,請先參閱「ASP.NET MVC 專案分層架構 Part.1 初學者的起手式」Kevin前輩的這篇系列文章再來。
又或者對於MVC,Model、Controll、View之間的關係有一定相當基本的了解,才建議看此篇文章。
雖然說此篇也是個新手文,但沒有寫過一個基本的MVC的朋友,還是先了解一下MVC之間的溝通,再來看此篇文章。
當然文內有任何錯誤或者有更好的方法,希望各位點出來一起討論,或者前輩能指導謝謝。
上一篇「ASP.NET MVC 4 實作PagedList.Mvc + AJAX 搜尋功能」,功能如果做出來沒有問題,我們就接下去做第一個新增的功能。
將新增功能的實作在Services寫好後,在Controller以POST方式寫Action,Controller如下。
[HttpPost]
public ActionResult Create(Customers customers)
{
if (customers != null && ModelState.IsValid)
{
this.custromService.Create(customers);
var returnData = new
{
// 成功與否
IsSuccess = true,
};
return Content(Newtonsoft.Json.JsonConvert.SerializeObject(returnData), "application/json");
}
else
{
var returnData = new
{
// 成功與否
IsSuccess = false,
};
return Content(Newtonsoft.Json.JsonConvert.SerializeObject(returnData), "application/json");
}
}
來講解一下Controller的部分,這部分有些參考到「[ASP NET MVC] 透過AJAX接收ModelState Errors顯示於對應欄位中」Chris前輩的文章。
等一下再寫前端傳給Action的時候會以POST的方式傳送,而相對的參數會以JSON格式。
所以在此很重要,要讓前端知道有沒有成功,就不能再使用return View之類的指令直接去轉換網址或重新整理網址,這些指令jQuery是不認得的。
回傳的資料理所當然的也會以Json傳給前端的jQuery接收。
此功能要撰寫的程式碼並不複雜,很容易就懂原理,後端大致上這樣就完成拉,然後接下來就是前端的View和jQuery的部分。
先講View的部分,首先因為如果將每一個功能都寫在Index裡面會很大很雜,要找起來就會比較麻煩。
上一篇講的架構是
View
_DataTable.cshtml <--- PartialView
Index.cshtml <--主要顯示畫面
在此我們再增加一個部分檢視,View架構就是如下。
View
_DataTable.cshtml <--- PartialView
_Create.cshtml <---新增功能的部分檢視
Index.cshtml <--主要顯示畫面
為什麼要這樣做,另一個原因在於,如果像我這個練習中沒有再多去建設一個ViewModel之下,一個頁面只能使用一個Model就會造成@model PageList<T>和原先的 @model model會有所衝突。
所以我們用了部分檢視,一樣可以呼叫到該頁面的HTML內容也可以針對其座操控。(他與上一章節所用的AJAX傳入的頁面方式不同,所以可以在Index上可以直接看到這部分的HTML Code,但所有的頁面是可會互相影響和操控的。)
講這麼多直接給你看_Create.cshtml的部分。如下
@model Ajax_CRUD_Model.Customers
<div class="modal fade" id="Create" tabindex="-1" role="dialog" aria-labelledby="modalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h3 class="modal-title" id="lineModalLabel">New Customer</h3>
</div>
<div class="modal-body">
<!-- content goes here -->
<form id="CreateForm">
<div class="form-group">
@Html.DisplayNameFor(model => model.CustomerID)
@Html.TextBoxFor(model => model.CustomerID, new {@class = "form-control" })
</div>
<div class="form-group">
@Html.DisplayNameFor(model => model.CompanyName)
@Html.TextBoxFor(model => model.CompanyName, new {@class = "form-control" })
</div>
<div class="form-group">
@Html.DisplayNameFor(model => model.ContactName)
@Html.TextBoxFor(model => model.ContactName, new {@class = "form-control" })
</div>
<div class="form-group">
@Html.DisplayNameFor(model => model.ContactTitle)
@Html.TextBoxFor(model => model.ContactTitle, new {@class = "form-control" })
</div>
<div class="form-group">
@Html.DisplayNameFor(model => model.Country)
@Html.TextBoxFor(model => model.Country, new {@class = "form-control" })
</div>
<div class="form-group">
@Html.DisplayNameFor(model => model.City)
@Html.TextBoxFor(model => model.City, new {@class = "form-control" })
</div>
<div class="form-group">
@Html.DisplayNameFor(model => model.PostalCode)
@Html.TextBoxFor(model => model.PostalCode, new {@class = "form-control" })
</div>
<div class="form-group">
@Html.DisplayNameFor(model => model.Phone)
@Html.TextBoxFor(model => model.Phone, new {@class = "form-control" })
</div>
<div class="form-group">
@Html.DisplayNameFor(model => model.Fax)
@Html.TextBoxFor(model => model.Fax, new {@class = "form-control" })
</div>
<div class="form-group">
@Html.DisplayNameFor(model => model.Address)
@Html.TextBoxFor(model => model.Address, new {@class = "form-control" })
</div>
<div class="form-group">
@Html.DisplayNameFor(model => model.Region)
@Html.TextBoxFor(model => model.Region, new {@class = "form-control" })
</div>
</form>
</div>
<div class="modal-footer">
<div class="btn-group btn-group-justified" role="group" aria-label="group button">
<div class="btn-group" role="group">
<button type="button" class="btn btn-default" data-dismiss="modal" role="button">Close</button>
</div>
<div class="btn-group" role="group">
<button type="submit" onclick="Create()" id="saveImage" class="btn btn-default btn-hover-green" data-action="save" role="button">Save</button>
</div>
</div>
</div>
</div>
</div>
</div>
對了,在此先提到顯示頁面的Index.cshtml檔案中要加入此頁面去不然就等於白做工了。如下
<!--加入部分頁面-->
@Html.Partial("~/Views/Customer/_Create.cshtml")
加入上述這段進入Index.cshtml
好了,最後就是jQuery的部分,因為頁面內容不大,所以我喜歡把什麼功能的jQuery加入在相對應的頁面底下。如下
<!--Ajax Create-->
<script>
function Create() {
var myForm = $("#CreateForm");
var dataForm = myForm.serialize();
var validator = myForm.validate();
$.ajax({
type: 'POST',
url: '@Url.Action("Create", "Customer")',
data: dataForm,
cache: false,
async: false,
dataType: 'json',
success: function (data) {
$('#Create').modal('hide');
alert('新增資料成功');
var page = window.location.hash
? window.location.hash.slice(1)
: 1;
fetchPage(page);
}
});
}
</script>
首先取得jQuery表單內容,再以Ajax方式將表單內容傳送到Action處理,結束。
沒錯這裡的jQuery就那麼的簡單,但有幾點要注意的地方,處理完成後Action會回傳資料回來給jQuery,此時要將我們的表單隱藏起來,再來看你要不要跳出什麼成功新增的訊息。
然後最重要的就是,要將DataTable重新整理一遍,也就是要下達一次上一篇所建構的函數fetchPage();
這樣新增的功能就大功告成拉。
然而下一篇我在思考要先講Chris前輩的驗證「[ASP NET MVC] 透過AJAX接收ModelState Errors顯示於對應欄位中」還是把其他功能先講完再回頭來講驗證,就讓我慢慢地思考一下吧。
MVC小菜鳥下台一鞠躬。