使用 knockout 将 List 绑定到 Viewmodel
Binding a List to a Viewmodel using knockout
我是 MVC 和 Knockout 以及 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>
我已经编写了一个脚本来将模型数据转换为 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>
我在controller里写了jsonview action
public ActionResult jsonview()
{
Provider providerList = new Provider();
List<Provider> providers = DAL.GetListofProviders.ToList();
var json = JsonConvert.SerializeObject(providers);
return Json(json, JsonRequestBehavior.AllowGet);
}
但是 table 没有显示 providers.Could 的列表,你们指引我正确的方向吗?
我在 _layout 页面中引用了一个 JS 文件 "Additional Scripts",如图所示。
<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 <space> 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)
}
您不需要手动序列化提供程序,尝试 return 原始数据,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');
}
});
为了使其正常工作,您需要将模型绑定到敲除。所有数据都已传递到视图,因此您无需执行 AJAX 请求
控制器代码:
public ActionResult Index()
{
Provider providerList = new Provider();
IList<Provider> providers = DAL.GetListofProviders.ToList();
return View(providers);
}
视图接收 IList 类型的模型
查看代码:
@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>
并且在脚本部分,确保将模型从控制器绑定到淘汰赛 viewModel:
编辑:就像 Max 建议的那样,您不需要 AJAX 调用,您可以这样做
<script type="text/javascript">
var data = @Html.Raw(Json.Encode(Model));
var viewModel = ko.mapping.fromJS(data);
ko.applyBindings(viewModel);
</script>
希望这对您有所帮助。
我是 MVC 和 Knockout 以及 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>
我已经编写了一个脚本来将模型数据转换为 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>
我在controller里写了jsonview action
public ActionResult jsonview()
{
Provider providerList = new Provider();
List<Provider> providers = DAL.GetListofProviders.ToList();
var json = JsonConvert.SerializeObject(providers);
return Json(json, JsonRequestBehavior.AllowGet);
}
但是 table 没有显示 providers.Could 的列表,你们指引我正确的方向吗?
我在 _layout 页面中引用了一个 JS 文件 "Additional Scripts",如图所示。
<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 <space> 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)
}
您不需要手动序列化提供程序,尝试 return 原始数据,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');
}
});
为了使其正常工作,您需要将模型绑定到敲除。所有数据都已传递到视图,因此您无需执行 AJAX 请求
控制器代码:
public ActionResult Index()
{
Provider providerList = new Provider();
IList<Provider> providers = DAL.GetListofProviders.ToList();
return View(providers);
}
视图接收 IList
查看代码:
@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>
并且在脚本部分,确保将模型从控制器绑定到淘汰赛 viewModel: 编辑:就像 Max 建议的那样,您不需要 AJAX 调用,您可以这样做
<script type="text/javascript">
var data = @Html.Raw(Json.Encode(Model));
var viewModel = ko.mapping.fromJS(data);
ko.applyBindings(viewModel);
</script>
希望这对您有所帮助。