在DropDownFor值更改时更改EditorFor的值

本文关键字:EditorFor 的值 DropDownFor | 更新日期: 2023-09-27 18:28:15

我正在尝试创建一个在线银行网站(用于学习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
                " })

现在,我正试图在的编辑器中显示所选账户余额

@Html.EditorFor(model => model.OrignalBalance, new { htmlAttributes = new { @id="OrignalBalance", @class = "form-control", disabled = "disabled", @readonly = "readonly" } })

我有ViewBag中的所有帐户,并且我在下拉列表中显示帐户编号(这些帐户中也有余额)。我正试图在DropDownFor值更改上更改EditorForquery中使用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。

谢谢。

在DropDownFor值更改时更改EditorFor的值

您应该进行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对象,在更改事件中,你可以查询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>
}

看起来可能不是这样,但这相当宽泛。基本概要,你要么必须:

  • 将所有帐户和余额序列化为JSON并存储在客户端:

    这是比这里合适的更多的代码,但您可以使用JSON.net为new BankEntities().Accounts.ToList()获取JSON(顺便说一句,这是您应该从控制器代码中获得的,而不是在您的视图中),然后在JavaScript中将window变量设置为该变量,并在值更改时调用该变量。

    未测试,但类似于:

    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在这一点上击败了我,但这可能是一种更好的方法,只要你能轻松地引入API元素。对于第一次学习MVC来说,它有点高级,但并不太复杂。

    这是我在生产应用程序中要做的(尽管我会使用Web API),但对于只是玩来说,第一个选项会更快一些,而且如果你刚开始的话,可能更容易理解和调试。

这里的混乱来自于代码的执行位置。与服务器端相比,script不能引用BankEntities,因为它运行的是客户端。

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 });
}