使用knockout将List绑定到Viewmodel

时间:2015-01-14 12:15:57

标签: javascript c# asp.net-mvc knockout.js

我是新手MVC,淘汰赛和JS就此而言。 我正在尝试使用Knockout显示提供者列表。 我有以下代码来获取提供者列表

        public ActionResult Index()
       {
            Provider providerList = new Provider();
            IList<Provider> providers = DAL.GetListofProviders.ToList();
            return View(providers);
       }

我有以下视图

   @model List<DEMO_JAN14.Models.Provider>
   @{
       Layout = "~/Views/Shared/_Layout.cshtml";
    }
 <head>
     <title>LIST OF PROVIDERS</title>
 </head>
 <body>
      <table class="table table-striped table-bordered table-hover">
    <tr>     
        <th>Provider Type</th>
        <th>First Name</th>
        <th>Last Name</th>
        <th>Certification</th>
        <th>Specialization</th>
        <th>SSN</th>
        <th>Facility Name</th>
        <th>Contact No</th>
        <th>Contact Email</th>
        <th></th>  
    </tr>

<tbody data-bind="foreach:viewmodel">
  <tr>
        <td class="col-lg-2" data-bind="text: ProviderType"></td>
        <td class="col-lg-1" data-bind="text: FirstName"></td>
        <td class="col-lg-1" data-bind="text: LastName"></td>
        <td class="col-lg-1" data-bind="text: Certification"></>
        <td class="col-lg-1" data-bind="text: Specialization"></td>
        <td class="col-lg-1" data-bind="text: SSN"></td>
        <td class="col-lg-4" data-bind="text: FacilityName"></td>
        <td class="col-lg-4" data-bind="text: ContactNumber"></td>
        <td class="col-lg-1" data-bind="text: ContactEmail"></td>
        <td><a class="btn btn-danger" id="del" onclick = "return confirm('Are you sure, you want to delete');" data-bind="attr: { href: '/Provider/Delete/' + ProviderID }"> Delete </a>
        </td>
    </tr> 
</tbody>           
  </table>
  </body>

我编写了一个脚本来将Model数据转换为Json数据。

  <script type="text/javascript">
    $.ajax({
       url: '/Provider/jsonview',
       dataType: "json",
    type: "GET",
    contentType: 'application/json; charset=utf-8',
    async: false,
    processData: false,
    cache: false,
    success: function (data) {
        viewmodel = ko.utils.parseJson(data);
        ko.applyBindings(viewmodel);
    },
    error: function (xhr) {
        alert('error');
    }
});
  </script>

我在控制器中写了一个jsonview动作。

     public ActionResult jsonview()
    {
        Provider providerList = new Provider();
        List<Provider> providers = DAL.GetListofProviders.ToList();
        var json = JsonConvert.SerializeObject(providers);
        return Json(json, JsonRequestBehavior.AllowGet);
    }

但是表格没有显示提供者列表。你们能引导我指向正确的方向吗?

我有一个JS文件&#34;附加脚本&#34;我正在_layout页面中引用,如图所示。                                            

       <link rel="stylesheet" href="../../Content/bootstrap-theme.min.css"/>
       <link rel="stylesheet" href="../../Content/bootstrap.min.css"/>

       <title>@ViewBag.Title</title>
       @Styles.Render("~/Content/css")
       @Scripts.Render("~/bundles/modernizr")

     <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
     <script type="text/javascript" src="../../Scripts/bootstrap.min.js"></script>
      <script type="text/javascript" src="../../Scripts/jquery-2.1.3.min.js"></script>
      <script type="text/javascript" src="../../Scripts/jquery.unobtrusive-ajax.min.js"></script>
      <script type="text/javascript" src="../../Scripts/jquery.validate.min.js"></script>
      <script type="text/javascript" src="../../Scripts/knockout-3.2.0.js"></script>


    </head>
    <body>
        @RenderBody()
     <script type="text/javascript" src="../../Scripts/AdditionalScripts.js"></script>
      </body>
      </html>

JS文件中的代码如图所示

    $(document).ready(function () {

//alert("document ready");

var Provider =
          {
              ProviderID: ko.observable(""),
              ProviderType: ko.observable(""),
              FirstName: ko.observable(""),
              LastName: ko.observable(""),
              Certification: ko.observable(""),
              Specialization: ko.observable(""),
              SSN: ko.observable(""),
              ContactNumber: ko.observable(""),
              ContactEmail: ko.observable(""),
              FacilityName: ko.observable(""),
          }
              ko.applyBindings(Provider);

//A function to check if all the fields have been filled before posting the form.
function ValidatethisForm() {
    if (Provider.ProviderType() === "")
        return false;
    else if (Provider.FirstName() === "")
        return false;
    else if (Provider.LastName() === "")
        return false;
    else if (Provider.Certification() === "")
        return false
    else if (Provider.Specialization() === "")
        return false;
    else if (Provider.ContactNumber() === "")
        return false;
    else if (Provider.ContactEmail() === "")
        return false;
    else if (Provider.FacilityName() === "")
        return false;
    else
        return true;
   }

   //Post the form on clicking the Submit Button.
    $("#Submit").on("click", function () {
    if (ValidatethisForm()) {
        $.ajax({
            type: "POST",
            url: "/Provider/Create",
            data: Provider
        });
    }
    });

$("#ProviderType").blur(function () {
    if ($('#ProviderType :selected').text() == "Select a Provider Type")
        alert("Please choose a Provider");
     });

   //Scripts for the First Name
      $("#FirstName").blur(function () {
    if ($(this).val().trim().length == 0) {
        $(this).addClass('borderclass');
        $("#Err_FirstName").show();
    }
    else {
        $("#Err_FirstName").hide();
        $(this).removeClass('borderclass');
    }
          });

     $("#FirstName").focusin(function () {
    if ($("#Err_FirstName").is(":visible"))
        $(this).addClass('borderclass');
});

$("#FirstName").keydown(function (event) {
    //$("#Err_FirstName").hide();
    //var inputVal = $(this).val();
    //var reg = /^[A-Za-z]+$/
        });

//Scripts for the Last Name
$("#LastName").blur(function () {
    if ($(this).val().trim().length == 0) {
        $(this).addClass('borderclass');
        $("#Err_LastName").show();
    }
    else {
        $("#Err_LastName").hide();
        $(this).removeClass('borderclass');
    }
         });

      $("#LastName").keypress(function () {
    //$("#Err_LastName").hide();
          });

     //Scripts for the Certification
      $("#Certification option:selected").blur(function () {
    if ($('#Certification :selected').text() == "Select a Certification")
        alert("Please choose a Certification");
         });

     //Scripts for the Specialization
        $("#Specialization option:selected").blur(function () {
        if ($('#Specialization :selected').text() == "Select a Specialization")
        alert("Please choose a Specialization");
         });

     //Scripts for SSN
     $("#SSN").blur(function () {
       if ($(this).val().trim().length == 0) {
        $("#Err_SSN").show();
        $(this).addClass('borderclass');
    }
      else {
        $("#Err_SSN").hide();
        var SSN = $(this).val();
        $(this).val(SSN.substring(0, 3) + "-" + SSN.substring(3, 5) + "-" + SSN.substring(5));
        $(this).removeClass('borderclass');
    }
       });

   $("#SSN").keypress(function () {
    //$("#Err_SSN").hide();
     });

   //Scripts for the Facility Name
     $("#FacilityName").blur(function () {
       if ($(this).val().trim().length == 0) {
        $("#Err_FacName").show();
        $(this).addClass('borderclass');
    }
      else {
        $("#Err_FacName").hide();
        $(this).removeClass('borderclass');
    }
       });

   $("#FacilityName").keypress(function () {
      //$("#Err_FacName").hide();
      });

      //Scripts for the Contact Number
      $("#ContactNumber").blur(function () {
     if ($(this).val().trim().length == 0) {
        $("#Err_ContactNum").show();
        $(this).addClass('borderclass');
    }
    else {
        $("#Err_ContactNum").hide();
        var ContactNum = $(this).val();
        $(this).val("(" + ContactNum.substring(0, 3) + ")" + ContactNum.substring(3, 6) + "-" +      ContactNum.substring(6));
        $(this).removeClass('borderclass');
    }
      });

     $("#ContactNumber").keypress(function () {
    //$("#Err_ContactNum").hide();
     });

//Scripts for the Email Address
     $("#EmailAddress").blur(function () {
    if ($(this).val().trim().length == 0) {
        $("#Err_EmailAddress").show();
        $(this).addClass('borderclass');
    }
    else {
        $("#Err_EmailAddress").hide();
        var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
        var email = $('#EmailAddress').val();
        $(this).removeClass('borderclass');
        if (!re.test(email)) {
            $("#Err_EmailAddress").show();
            $(this).addClass('borderclass');
        }
    }
    });

    $("#EmailAddress").keypress(function () {
    //$("#Err_EmailAddress").hide();
    });

      //$(function () {
     //    $('#SuccessMessage').delay(2000).fadeOut(500);
    //});
     })

     function onlyAlphabets(evt) {
   var charCode;
   if (window.event)
    charCode = window.event.keyCode;  //for IE
   else
    charCode = evt.which;  //for firefox
  if (charCode == 32) //for &lt;space&gt; symbol
    return false;
if (charCode > 31 && charCode < 65) //for characters before 'A' in ASCII Table
    return false;
if (charCode > 90 && charCode < 97) //for characters between 'Z' and 'a' in ASCII Table
    return false;
if (charCode > 122) //for characters beyond 'z' in ASCII Table
    return false;
return true;
      }

      function onlyNumbers(evt) {
var charCode;
if (window.event)
    charCode = window.event.keyCode;   //if IE
else
    charCode = evt.which; //if firefox
if (charCode > 31 && (charCode < 48 || charCode > 57))
    return false;
return true;
    }

      function validateEmail() {
var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
var email = $('#EmailAddress').val();
return re.test(email)
        }

2 个答案:

答案 0 :(得分:1)

您不需要手动序列化提供程序,尝试返回原始数据,JsonResult将负责序列化。

return Json(DAL.GetListofProviders.ToList(), JsonRequestBehavior.AllowGet);

还有其他错误,比如 - 您不需要重新创建和重新绑定您的viewModel - 您不需要解析结果

var viewmodel = {
    providers: ko.observableArray()
};
ko.applyBindings(viewmodel);

$.ajax({
 url: '/Provider/jsonview',
   dataType: "json",
   type: "GET",
   contentType: 'application/json; charset=utf-8',
   success: function (data) {
      viewmodel.providers(data);        
   },
   error: function (xhr) {
     alert('error');
   }
 });

Working JsFiddle

答案 1 :(得分:1)

为了使其工作,您需要将模型绑定到淘汰赛。所有数据都已传递到视图中,因此您不需要执行AJAX请求

控制器代码:

public ActionResult Index()
{
    Provider providerList = new Provider();
    IList<Provider> providers = DAL.GetListofProviders.ToList();
    return View(providers);
}

视图接收IList&lt; Provider&gt;

类型的模型

查看代码:

@model List<DEMO_JAN14.Models.Provider>
@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<head>
    <title>LIST OF PROVIDERS</title>
</head>
<body>
<table class="table table-striped table-bordered table-hover">
    <tr>     
        <th>Provider Type</th>
        <th>First Name</th>
        <th>Last Name</th>
        <th>Certification</th>
        <th>Specialization</th>
        <th>SSN</th>
        <th>Facility Name</th>
        <th>Contact No</th>
        <th>Contact Email</th>
        <th></th>  
    </tr>
<tbody data-bind="foreach: viewModel"> <-- Bind it to the viewModel
<tr>
    <td class="col-lg-2" data-bind="text: ProviderType"></td>
    <td class="col-lg-1" data-bind="text: FirstName"></td>
    <td class="col-lg-1" data-bind="text: LastName"></td>
    <td class="col-lg-1" data-bind="text: Certification"></>
    <td class="col-lg-1" data-bind="text: Specialization"></td>
    <td class="col-lg-1" data-bind="text: SSN"></td>
    <td class="col-lg-4" data-bind="text: FacilityName"></td>
    <td class="col-lg-4" data-bind="text: ContactNumber"></td>
    <td class="col-lg-1" data-bind="text: ContactEmail"></td>
    <td><a class="btn btn-danger" id="del" onclick = "return confirm('Are you sure, you want to delete');" data-bind="attr: { href: '/Provider/Delete/' + ProviderID }"> Delete </a>
    </td>
      </tr> 
    </tbody>           
</table>

在脚本部分中,确保将Model从控制器绑定到knockout viewModel: 编辑:像Max建议你不需要那个AJAX电话,你可以做这样的事情

<script type="text/javascript">
    var data = @Html.Raw(Json.Encode(Model));
    var viewModel = ko.mapping.fromJS(data);
    ko.applyBindings(viewModel);
</script>

希望这会有所帮助。