剛步入ASP.NET MVC架構的空間,前一份工作只是修修改改PHP和部分的.NET。所以整個還很菜阿,目的記錄自己學習的過程,以及希望有任何一位前輩覺得哪寫錯或方法很爛,麻煩順便可以大發慈悲的指點一下。
那麼準備開始從大多數專案都會碰到的CRUD來寫起吧,雖然很多API可以去串接很快速達到所要的功能,但練功還是自己慢慢地刻出一個畫面再說。
首先,此篇是參考 KEVIN 前輩的文章,再加入自己的應用和想法產生出來的,正所謂凡事先從模仿開始,但千萬別一開始就去學灌籃吧。相對這篇也不適合第一次接觸MVC沒有開發經驗的人閱讀。
本文引用kevin前輩文章,謝謝分享那麼優的文章。
ASP.NET MVC 資料分頁操作 - 使用 PagedList.Mvc @ GitHub
當參考Kevin前輩的 「ASP.NET MVC 資料分頁操作 - 使用 PagedList.Mvc @ GitHub」系列文章發現Ajax那篇文章有實際做到,但分頁進階處理此篇文章就每一次都會重新整理頁面。
於是本篇文章就,利用這兩篇文章做一個簡單的結合,達到搜尋的結果也可以呈現AJAX。
首先實際做完Kevin前輩的文章Part 3 Ajax部分會得到類似下圖的Table,當然沒有上面搜尋的功能。
首先把顯示頁面的搜尋欄位建好,程式碼如下
<div class="container">
<div class="row">
<div class="col-md-10 col-md-offset-1">
<div class="well">
<div class="col-xs-6 form-group">
<label class="col-xs-3 control-label">CustomerID:</label>
<div class="col-xs-8">
@Html.TextBox("CustomerID", "", new { htmlAttributes = new { @class = "form-control", @id = "CustomerID" } })
</div>
</div>
<div class="col-md-6 form-group">
<label class="col-xs-3 control-label">CompanyName:</label>
<div class="col-xs-8">
@Html.TextBox("CompanyName", "", new { htmlAttributes = new { @class = "form-control", @id = "CompanyName" } })
</div>
</div>
<span class="clearfix"></span>
<div class="row">
<div class="col-md-offset-5">
<input id="Serach" type="button" class="btn btn-primary" value="Search">
<span></span>
<input id="re" type="button" class="btn btn-default" value="Cancel">
</div>
</div>
</div>
</div>
</div>
</div>
接下來是搜尋的Controller部分,但實作搜尋篩選資料並不是放在Controller內。搜尋的方式我會用POST的方式來傳遞參數
[HttpPost]
public ActionResult PagedPartial(string CustomerID = null, string CompanyName = null, int page = 1)
{
var query = this.custromService.Search(CustomerID, CompanyName);
int currentPage = page < 1 ? 1 : page;
var result = query.ToPagedList(currentPage, pageSize);
ViewData.Model = result;
return PartialView("_DataTable");
}
實作的搜尋方法我放在Service裡來實作這個功能,跟我一樣還很菜的不懂這一段怎麼來的朋友依然可以參考Kevin前輩的文章「ASP.NET MVC 專案分層架構 Part.1 初學者的起手式」這系列的文章。
public IEnumerable<Customers> Search(string CustomerID, string CompanyName)
{
var query = this.repostitory.GetAll().AsQueryable();
if (!string.IsNullOrWhiteSpace(CustomerID))
{
query = query.Where(x => x.CustomerID.Contains(CustomerID));
}
if (!string.IsNullOrWhiteSpace(CompanyName))
{
query = query.Where(x => x.CompanyName.Contains(CompanyName));
}
query = query.OrderByDescending(x => x.CustomerID);
return query;
}
當後端的方式都完整的建立好的時候,再來就剩下前端的部分,在前端採用jQuery來傳送參數給Controller。在View的部分會有兩個檔案,一個作為部分加入的頁面,一個是我們連到網站會看到的頁面。
View
__DataTable.cshtml <--- PartialView
Index.cshtml <--主要顯示畫面
先來看_DataTable.cshtml的內容。此為TABLE所顯示的資料畫面,這個沒什麼好講的,看完Kevin前輩的文章都可以很容易的理解。
@using PagedList
@using PagedList.Mvc
@model IPagedList<Ajax_CRUD_Model.Customers>
<div class="container-full">
<div class="row">
<div class="col-md-10 col-md-offset-1">
<div class="panel panel-default panel-table">
<div class="panel-heading">
<div class="row">
<div class="col col-xs-6">
<h3 class="panel-title">Customer</h3>
</div>
<div class="col col-xs-6 text-right">
<button data-toggle="modal" data-target="#squarespaceModal" class="btn btn-sm btn-primary btn-create">Create New</button>
</div>
</div>
</div>
<div class="panel-body">
<table class="table table-striped table-bordered table-list">
<thead>
<tr>
<th><em class="fa fa-cog"></em></th>
<th>@Html.DisplayNameFor(model => model.FirstOrDefault().CustomerID)</th>
<th>@Html.DisplayNameFor(model => model.FirstOrDefault().CompanyName)</th>
<th>@Html.DisplayNameFor(model => model.FirstOrDefault().ContactName)</th>
<th>@Html.DisplayNameFor(model => model.FirstOrDefault().ContactTitle)</th>
<th>@Html.DisplayNameFor(model => model.FirstOrDefault().Country)</th>
<th>@Html.DisplayNameFor(model => model.FirstOrDefault().City)</th>
<th>@Html.DisplayNameFor(model => model.FirstOrDefault().PostalCode)</th>
<th>@Html.DisplayNameFor(model => model.FirstOrDefault().Phone)</th>
<th>@Html.DisplayNameFor(model => model.FirstOrDefault().Fax)</th>
<th>@Html.DisplayNameFor(model => model.FirstOrDefault().Address)</th>
<th>@Html.DisplayNameFor(model => model.FirstOrDefault().Region)</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td align="center">
<button id="TETT" onclick="getValue('@item.CustomerID','@item.CompanyName')" data-toggle="modal" data-target="#Ediotr" class="btn btn-sm btn-default fa fa-pencil"></button>
<button data-toggle="modal" onclick="GetDeletValue('@item.CustomerID','@item.CompanyName')" data-target="#Delete" class="btn btn-sm btn-danger fa fa-trash"></button>
</td>
<td>@Html.DisplayFor(modelItem => item.CustomerID)</td>
<td>@Html.DisplayFor(modelItem => item.CompanyName)</td>
<td>@Html.DisplayFor(modelItem => item.ContactName)</td>
<td>@Html.DisplayFor(modelItem => item.ContactTitle)</td>
<td>@Html.DisplayFor(modelItem => item.Country)</td>
<td>@Html.DisplayFor(modelItem => item.City)</td>
<td>@Html.DisplayFor(modelItem => item.PostalCode)</td>
<td>@Html.DisplayFor(modelItem => item.Phone)</td>
<td>@Html.DisplayFor(modelItem => item.Fax)</td>
<td>@Html.DisplayFor(modelItem => item.Address)</td>
<td>@Html.DisplayFor(modelItem => item.Region)</td>
</tr>
}
</tbody>
</table>
</div>
<div class="panel-footer">
@Html.PagedListPager(Model, page => Url.Action("Index", new { page }))
</div>
</div>
</div>
</div>
</div>
重點在Index上面,有事前先做好的搜尋,在搜尋的下面再加上一個DIV作為部分參照的資料載入的地方。(此部分Kevin前輩內文都有詳細的說明)
<!--DataTable Ajax 插入位置-->
<div id="CustomerData"></div>
Kevin的原文內容在搜尋分頁那篇,是採用
@using (Html.BeginForm)
這個方式來對Controller來傳遞參數,這樣網頁Return一定會因此refresh。
所以在此改用Kevin系列文章的「ASP.NET MVC 資料分頁 - 使用 PagedList.Mvc:AJAX」此篇方法來做修改,達到Ajax的部分。
<!--Ajax 查詢以及顯示清單-->
<script>
$(function () {
var page = window.location.hash
? window.location.hash.slice(1)
: 1;
fetchPage(page);
$('#Serach').click(function () {
fetchPage(page);
});
$('#re').click(function () {
$('#CustomerID').val("");
$('#CompanyName').val("");
fetchPage(page);
});
});
var List = function () {
$('#BankData .pagination li a').each(function (i, item) {
var hyperLinkUrl = $(item).attr('href');
if (typeof hyperLinkUrl !== 'undefined' && hyperLinkUrl !== false) {
var pageNumber = $(item).attr('href').replace('/Customer?page=', '');
$(item).attr('href', '#').click(function (event) {
event.preventDefault();
$(event.target).attr('href');
fetchPage(pageNumber);
});
}
});
};
var fetchPage = function (page) {
var pagedPartialUrl = '@Url.Action("PagedPartial", "Customer")';
var CustomerID = $('#CustomerID').val();
var CompanyName = $('#CompanyName').val();
if (CustomerID != null || CustomerID != "" || CompanyName != null || CompanyName != "") {
pagedPartialUrl = '@Url.Action("PagedPartial", "Customer")';
$.post(pagedPartialUrl, { page: page, CustomerID: CustomerID, CompanyName: CompanyName }, function (data) {
window.location.hash = page;
$('#BankData').html(data);
List();
});
} else {
$.post(pagedPartialUrl, { page: page }, function (data) {
window.location.hash = page;
$('#BankData').html(data);
List();
});
}
};
</script>
fetchPage() => 傳遞參數以及抓取Ajax Data,所以對Controller也是這裡溝通。
List () => 抓取分頁,因為這裡所以才可進行AJAX的分頁,以及搜尋的分頁,這是完全依照Kevin前輩的文章,由於小弟很菜,jQuery功力更慘只好先依照前輩的文章來使用,詳細自行參考吧,不太了解這部分的意思。但這是功能的重點。代表我還不夠認真只好再努力多念點書了....
本篇的修改的點在於fetchPage的修改,改成一部分有傳遞搜尋參數,另一個只有傳遞page,再加入兩個Button來作為搜尋功能的依據,再將Kevin前輩的List()部份抽離出來獨立成為一個函數,避免掉要重複寫一段一樣的塞在fetchPage內。
簡單的修改一些部分就能達到Ajax 的資料頁面拉。
下一篇會來介紹One Page 達到 CRUD的應用,記得兩個多月前第一個MVC專案的開始,一個功能一個PAGE多煩阿,兩個月後,開始懂得應用jQuery去對Controller呼叫Action來做使用,解決掉我很多的新手問題,後續會再將這些相關的練習發給大家參考,希望我是有慢慢再進步的,菜鳥文,下台一鞠躬。