在DropDownFor值更改时更改EditorFor的值

时间:2015-12-28 23:17:23

标签: c# jquery asp.net-mvc linq asp.net-mvc-4

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

谢谢。

3 个答案:

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