想了解MVC的完整從後端將值填回頁面上的方式,所以現在嘗試在View上按下button後,然後在Controller寫定一個值以後,再帶回View的textbox上,但我目前實作不出來,請問哪裡要做調整呢?
【View】
@model Practice.Models.TestModel
@{
ViewBag.Title = "Home";
}
<html>
<head>
<title></title>
</head>
<body>
<div class="row">
<div class="col-md-4">
<br />
<label>取得Name : </label>
</div>
</div>
<div class="row">
<div class="col-md-4">
Name:@Html.TextBoxFor(m => m.Name)
<input type="button" id="sName" value="" onclick="GetName()" />
</div>
</div>
</body>
</html>
【Controller】
@model Practice.Models.TestModel
namespace Practice.Controllers
{
public class TestController : Controller
{
public ActionResult TestIndex()
{
return View();
}
protected void GetName()
{
var sName="testName"
TestModel objModel = new TestModel();
objModel.Name = sName;
return;
}
}
}
【Model】
namespace Practice.Models
{
public class TestModel
{
public string Name { get; set; }
}
}
依照您目前的需求,搭配Ajax
來實作應該比較簡單一點。
然後,您可能要注意一下前、後端語法混用
的問題~XDDD
首先,要使用Ajax
就必須先將對應的API
先建出來
// Controller
public ActionResult GetName()
{
return Content("YoChen");
}
接著,準備好HTML
(我只列出必要的Tag)
<!-- View -->
<input type="text" id="display" value="" />
<input type="button" id="getNameButton" value="Get Name!!" />
最後,我們來Call API
(MVC預設有引用Jquery,這邊就直接用Jquery了~XDDD)
$(function () {
$('#getNameButton').click(function () {
$.ajax(
"/Test/GetName",
{
success: function (data, textStatus, jqXHR) {
$('#display').val(data);
},
error: function (jqXHR, textStatus, errorThrown) {
console.log(errorThrown);
}
}
)
})
}
不免俗地還是要提醒您,
MVC
只是一種架構模式
,並非所有使用者行為都一定會接觸到M、V、C哦!! XDDD
觀察流程,可以參考以下程式碼
// Model
public class TestViewModel
{
public string Name { get; set; }
}
// Controller
public ActionResult Index()
{
TestViewModel model = new TestViewModel() { Name = "YoChen" };
return View(model);
}
<!-- View -->
@model Practice.Models.TestViewModel
<h1>@Model.Name</h1>
好的,我知道,只是想透過這個簡單的練習瞭解 MVC 架構~
目前有個問題,就是我想透過按鈕事件將值帶出來,那這樣的話在Controller感覺要放在其他ActionResult中,但我目前調整成如下,並不會做動,請問可以怎麼調整呢,謝謝您!
<!-- View 以下兩個寫法不知道怎麼放才對 -->
Name:<input type="text" id="sName" value=@Model.Name readonly="readonly" />
Name:@Html.TextBoxFor(m => m.Name)
<input type="button" id="sName" onclick="@Url.Action("GetName", "TestController")" />
// Controller
public string GetName()
{
var _name="YoChen";
TestViewModel model = new TestViewModel() { _name };
return View(model);
}
// Model
public class TestViewModel
{
public string Name { get; set; }
}
"(引號)
不要遺漏。"(引號)
的部分沒有問題的話,Model.Name是否有賦值
,Action是否有將Model帶入View當中
。<!--value缺乏引號-->
Name:<input type="text" id="sName" value=@Model.Name readonly="readonly" />
<!--調整為-->
Name:<input type="text" id="sName" value="@(Model.Name)" readonly="readonly" />
onclick
Attribute內部應該放的是javascript function
,Url.Action
只能輸出對應Action的Url
<!--onclick未給予function-->
<input type="button" id="sName" onclick='@Url.Action("GetName", "TestController")' />
<!--調整為-->
<input type="button" id="sName" onclick="CallMyNameAPI()" />
<script>
function CallMyNameAPI() {
$.ajax(
'@Url.Action("GetName", "Test")',
{
success: function (data, textStatus, jqXHR) {
$('#Name').val(data);
},
error: function (jqXHR, textStatus, errorThrown) {
console.log(errorThrown);
}
}
)
}
</script>
我的思路跟各大神們不太一樣
單從MVC跟ajax來比,我還比較喜歡用ajax來的直觀點,至少不會有轉來轉去的搞到昏頭的麻煩
舉我最近在做的專案為例
後端 C#
dcERPDataContext myERP = new dcERPDataContext();
protected void Page_Load(object sender, EventArgs e)
{
string pono = Request.Form["pono"];
string act = Request.Form["act"];
if (act == "getPO" && !string.IsNullOrEmpty(pono))
{
getPO(pono.Trim().ToUpper());
}
}
private void getPO(string pono)
{
//用linq抓資料並直接轉json
var data = (from m in myERP.POMaster
join d in myERP.PODetail on m.id equals d.Mainid into detail
join c in myERP.Emp on m.empid equals c.id into contactor
where m.no == pono.ToUpper()
select new {
m,
detail=detail.OrderBy(o=>o.id)
,contactor
}).ToArray();
Response.Clear();
Response.Write(JsonConvert.SerializeObject(data).Replace("null","\"\""));
//上面那行防止出現null字樣,一律換成空字串....偷吃步
Response.End();
}
前端的javascript(我慣用jQuery),至於HTML就簡單的跟什麼一樣..沒什麼好舉例
$(function () {
let pono = "pono".urlParamValue();
if (pono !== "") {
getPO(pono);
}
}
var getPO = function (po) { //用ajax把收到的json布置到網頁而已
$.post({
url: "./",
dataType: "json",
data: {
act: "getPO",
pono: po,
}
})
.done(function (data) {
//這裡沒什麼,自己手動佈置畫面而已,把json一一塞進畫面格子裡
if (data.length > 0) {
let master = data[0].m;
let detail = data[0].detail;
let contactor = data[0].contactor;
$("#tbProject").val(master.ProjectNo);
$("#tbProjectName").val(master.ProjectName);
$("#tbPoNo").val(master.no);
$("#tbWorkGroundContactor").val(master.contactor);
if (contactor.length > 0) { $("#tbWorkGroundContactor").val(`${$("#tbWorkGroundContactor").val()} ${contactor[0].empname}`);
}
$("#tbPosMemo").val(master.memo);
if (detail.length > 0) {
//塞表身,我不愛用table,用css table
detail.forEach(function (item) {
let tr = $(`<div class="tr trbody" id="${item.id}"></div>`);
tr.data('itemdata', item); //tr的data塞進整個array
tr.append($(`<div class="tdh td">${item.itemname}</div>`));
tr.append($(`<div class="tdh td">${item.price}</div>`));
// 以下省略1001行,都在塞格而已.....
$("#posdetail .datagrid").append(tr);
});
resizeDataGrid("#posdetail .datagrid"); // 把表格對齊
}
}
})
.fail(function (d) {
//偷懶沒寫錯誤處理
});
};
var resizeDataGrid = function (gridname) {
// 上面提到表格對齊用的,偷吃步,我就不愛用Table..
let thArr = $(`${gridname} .tr:first-child .th`);
$(`${gridname} .tr:first-child .td`).each(function (i, v) {
if ($(thArr).innerWidth() < $(v).outerWidth() - 1) {
$(thArr[i]).innerWidth($(v).outerWidth() - 1);
}
});
};
//抓url後面的params用的prototype
String.prototype.urlParamValue = function () {
var desiredVal = null;
var paramName = this.valueOf();
window.location.search.substring(1).split('&').some(function (currentValue, _, _) {
var nameVal = currentValue.split('=');
if (decodeURIComponent(nameVal[0]) === paramName) {
desiredVal = decodeURIComponent(nameVal[1]);
return true;
}
return false;
});
return desiredVal;
};
頁面的部份截圖(已馬)
真的後端完全不管HTML怎麼做,前端也不管資料庫到底長在什麼地方,哪天我爽,從mssql搬到postgresql,前端也不會需要任何改動
上例扯到太多工作上的東西所以有改很多,可能有的變數名沒改到,會有點亂七八糟,拜託.....砍小力一點
會有這個試算表,是因為有時採購的內容成百上千行,從頭把單價打到尾,還沒打完網路出問題,等於做白工,所以才弄了這個試算的功能,還給用戶有存草稿的機會,避免直接上線打一半斷線的鳥問題發作,那真的會被罵到臭頭..
謝謝您~ 就像YoChen 回覆的一樣,這個方式經過兩位的演示,我有理解並實作出來,謝謝!