我正在尝试建立一个在线银行网站(用于学习ASP.NET MVC)。我有一个班级帐户
class Account
{
int account_id;
String account_number;
decimal balance;
}
我有交易的模型。
public class MakeTransactionModel
{
[Required]
public String AccountFrom { get; set; }
[Required]
public String AccountTo { get; set; }
public Decimal OrignalBalance { get; set; }
[Required]
public Decimal Amount { get; set; }
[Required]
public String TransactionFor { get; set; }
}
然后在控制器中,我将帐户放入ViewBag。
ViewBag.account_from = new SelectList(db.Accounts, "account_id", "account_number");
在View中,我创建了一个显示所有帐户的下拉菜单
@Html.DropDownListFor(u => u.AccountFrom, (SelectList)ViewBag.account_from, htmlAttributes: new { @class = "form-control", @id = "AccountFrom", onchange=@"
@Model.OrignalBalance = 1000; // I tried this but did not work
" })
现在,我想在EditorFor
中显示所选帐户的余额@Html.EditorFor(model => model.OrignalBalance, new { htmlAttributes = new { @id="OrignalBalance", @class = "form-control", disabled = "disabled", @readonly = "readonly" } })
我在 ViewBag 中拥有所有帐户,并且我显示下拉帐户号码(这些帐户中也有余额)。我试图在 DropDownFor 值更改时更改 EditorFor 的值但仍无法执行此操作。我尝试使用jquery做到这一点,但我不知道我可以在 jquery
中使用 LINQ我的jquery代码是
<script type="text/javascript">
$(document).ready(function () {
$(function () {
$('#AccountFrom').change(function () {
var selectedValue = $('#AccountFrom').text();
$('#OrignalBalance').val(@{new BankEntities().Accounts.SingleOrDefault(acc => acc.account_number == $('#AccountFrom').text())}); // I am trying to do this
});
});
}
)
</script>
如果我找到一个很好的解决方案,那将是很好的,所以我可以在更改事件上更新EditorFor。
谢谢。
答案 0 :(得分:4)
您应该拨打ajax电话并传递帐号并从服务器获取金额。
$(function()
{
$('#AccountFrom').change(function() {
var accountId= $('#AccountFrom').val();
var url="@Url.Action("Balance","Account")";
$.post(url+"?accountNumber="+accountId,function(response){
if(response.Status==="success")
{
$("#OrignalBalance").val(response.Balance);
}
else
{
alert("Invalid Account");
}
});
});
});
假设你有一个动作方法来返回余额
[HttpPost]
public ActionResult Balance(string accountNumber)
{
//Of course you want to authorize the call
var db=new BankEntities();
var a= db.Accounts.FirstOrDefault(x=> x.account_number ==accountNumber);
if(a!=null)
{
return Json( new { Status="success", Balance=a.Balance });
}
else
{
return Json( new { Status="error"});
}
}
如果您不想制作动作方法和ajax方式,您可以做的是,创建您的帐号和余额的字典,并将其作为视图模型的一部分并在剃刀视图中传递,设置对于js对象和在change事件中,您可以查询js字典以获取值。
另外,我建议不要使用ViewBag在操作方法和视图之间传输数据以呈现下拉列表。您应该添加一个强类型属性来处理它。
因此,让我们为您的视图模型添加一些新属性。
public class MakeTransactionModel
{
// Your other existing properties here
public Dictionary<string,decimal> AccountBalances { set; get; }
// These 2 properties are for rendering the dropdown.
public int FromAccountId { set; get; }
public List<SelectListItem> FromAccounts { set; get; }
}
在您的GET操作中,请使用帐号和相应的余额值填写此属性。
public ActionResult Transfer()
{
var vm = new MakeTransactionModel();
vm.AccountBalances = new Dictionary<string, decimal>();
// Hard coded for demo. You may read it from your db tables.
vm.AccountBalances.Add("CHECKING0001", 3450.50M);
vm.AccountBalances.Add("SAVINGS0001", 4450.50M);
//load the data for accounts.pls change to get from db
vm.FromAccounts = new List<SelectListItem>
{
new SelectListItem { Value="CHECKING0001", Text="Checking" },
new SelectListItem { Value="SAVINGS0001", Text="Saving" }
};
// to do : Load other properties also
return View(vm);
}
在剃须刀视图中,序列化此属性并设置为js对象。
@model MakeTransactionModel
@using(Html.BeginForm())
{
@Html.DropDownListFor(s=>s.FromAccountId,Model.FromAccounts,"Select")
@Html.EditorFor(model => model.OrignalBalance,
new { @id="OrignalBalance", @class = "form-control",
disabled = "disabled", @readonly = "readonly" } )
<input type="submit" />
}
@section Scripts
{
<script>
var balanceDict = @Html.Raw(Newtonsoft.Json.JsonConvert
.SerializeObject(Model.AccountBalances));
$(function () {
$('#FromAccountId').change(function() {
var accountId= $('#AccountFrom').val();
var v = balanceDict[accountId];
$("#OrignalBalance").val(v);
});
});
</script>
}
答案 1 :(得分:2)
它可能看起来不像,但这是相当广泛的。基本纲要,您必须:
将所有帐户和余额序列化为JSON并将其存储在客户端:
这里的代码比适当的代码多,但是你可以使用JSON.net来获取new BankEntities().Accounts.ToList()
的JSON(顺便提一句,你应该从你的控制器代码获取,而不是在你的视图中),然后将window
变量设置为JavaScript中的变量,并在值发生变化时调用该变量。
未经测试,但类似:
var balances = @Html.Raw(JsonConvert.SerializeObject(new BankEntities()
.Accounts
// Filter by logged in user
.ToDictionary(c => c.account_number, c.balance));
$(document).ready(function () {
$(function () {
$('#AccountFrom').change(function () {
var selectedValue = $('#AccountFrom').text();
$('#OrignalBalance').val(balances[selectedValue]);
});
});
}
介绍通过AJAX执行的API调用,以便在值发生变化时获得余额。
Shyju beat me to this one,但只要您愿意引入API元素,它可能是更好的方法。它是第一次学习MVC的先进技术,但它并不太复杂。
这就是我在生产应用程序中所做的事情(虽然我是用Web API做的),但是对于刚刚播放,第一个选项更快一些,并且可能更容易理解和调试完全如果你刚刚开始。
这里的困惑来自执行代码的地方。与服务器端相比,script
无法引用BankEntities
,因为它正在运行客户端。
答案 2 :(得分:1)
JQuery对LINQ一无所知,因为它基于客户端。因此,我建议在帐户更改时发出ajax请求。
例如,在视图中,进行ajax调用<script type="text/javascript">
$(document).ready(function() {
$('#AccountFrom').change(function() {
var selectedAccountNumber = $('#AccountFrom option:selected').text();
$.ajax({
url: "/Accounts/GetAccountBalance",
type: "POST",
dataType: "json",
data: { accountNumber: selectedAccountNumber },
success: function (
$('#OrignalBalance').val(data.Balance);
}
});
});
});
</script>
并在控制器中有以下内容(假设您有一个名为Accounts的控制器)
public ActionResult GetAccountBalance(string accountNumber)
{
var account = db.Accounts.SingleOrDefault(a => a.account_number == accountNumber);
// add validation logic for account not exits
return Json(new { AccountNumber = accountNumber, Balance = account.balance });
}