【发布时间】:2019-11-13 20:45:58
【问题描述】:
我对 KnockoutJS 的经验很少,所以请多多包涵。
我有一个基本示例,我想开始工作,以便将其扩展到我的项目。
对于本示例,您单击按钮并调用 AddSku 方法以返回带有 List 的 QuoteLine 数据。
但是,如图所示,BomDetails 是空的:
型号:
public class QuoteViewModel
{
public int Id { get; set; }
public string QuoteName { get; set; }
public IList<QuoteLine> QuoteLines { get; set; }
}
public class QuoteLine
{
public string Description { get; set; }
public string Sku { get; set; }
public IList<BomDetail> BomDetails = new List<BomDetail>();
}
public class BomDetail
{
public string Name { get; set; }
}
控制器方法:
[HttpGet]
public ActionResult CreateQuote()
{
QuoteViewModel quote = new QuoteViewModel();
quote.Id = 10;
quote.QuoteName = "Test Create Quote";
quote.QuoteLines = new List<QuoteLine>();
return View(quote);
}
[HttpPost]
public ActionResult CreateQuote(QuoteViewModel viewModel)
{
if (ModelState.IsValid)
{
}
return RedirectToAction("CreateQuote");
}
[HttpGet]
public JsonResult AddSku()
{
QuoteLine line = new QuoteLine();
line.BomDetails = new List<BomDetail>();
line.Sku = "TestSku";
line.Description = "TestDescription";
line.BomDetails.Add(new BomDetail
{
Name = "BOM Detail 1"
});
line.BomDetails.Add(new BomDetail
{
Name = "BOM Detail 2",
});
return Json(line, JsonRequestBehavior.AllowGet);
}
观点:
@model EngineeringAssistantMVC.ViewModels.QuoteViewModel
<script src="~/Scripts/knockout.mapping-latest.js"></script>
<div class="container-fluid">
<h2>Create Quote</h2>
@using (Html.BeginForm("CreateQuote", "Test", FormMethod.Post, new { @id = "createQuoteForm", @class = "form-horizontal", role = Model, enctype = "multipart/form-data" }))
{
@Html.AntiForgeryToken()
@Html.HiddenFor(m => m.Id)
@Html.HiddenFor(m => m.QuoteName)
<h3>Quote Lines</h3>
<table class="table master-detail-table" id="receiving-table">
<thead>
<tr>
<th>SKU</th>
<th>Description</th>
</tr>
</thead>
<tbody data-bind="foreach: QuoteLines">
<tr>
<td>
<input class='form-control' data-bind='value: $data.Sku, attr: { name: "QuoteLines[" + $index() + "].Sku" } ' type='text' readonly='readonly' />
</td>
<td>
<input class='form-control' data-bind='value: $data.Description, attr: { name: "QuoteLines[" + $index() + "].Description" } ' type='text' readonly='readonly' />
</td>
</tr>
<tr class="detail-row">
<td colspan="7">
<table class="table">
<thead>
<tr>
<th>Name</th>
</tr>
</thead>
<tbody data-bind="foreach: BomDetails">
<tr>
<td>
<input class='form-control' data-bind='value: $data.Name, attr: { name: "BomDetails[" + $index() + "].Name" } ' type='text' readonly='readonly' />
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<h3>Add Sku from Db</h3>
<div class="row">
<div class="col-sm-2">
<input type="button" value="Add Sku" id="btnAddSku" class="btn btn-satcom-primary btn-wider" />
</div>
</div>
<h3>Submit</h3>
<div class="row">
<div class="col-sm-1">
<input type="submit" value="Submit" class="btn btn-satcom-primary btn-wider" id="btnSubmit" />
</div>
</div>
}
</div>
<script type="text/javascript">
$(function () {
quoteViewModel = new QuoteViewModel();
ko.applyBindings(quoteViewModel);
$('#btnAddSku').off().on('click', function () {
AddFromDb();
});
});
function QuoteViewModel() {
var self = this;
self.Id = ko.observable('@Model.Id');
self.QuoteName = ko.observable('@Model.QuoteName');
self.QuoteLines = ko.observableArray([]);
self.AddQuoteLine = function (sku, description, bomDetails) {
self.QuoteLines.push(new QuoteLineViewModel(sku, description, bomDetails));
}
}
function QuoteLineViewModel(sku, description, bomDetails) {
var self = this;
self.Sku = sku;
self.Description = description;
self.BomDetails = ko.observableArray([]);
$.each(bomDetails, function (index, item) {
self.BomDetails.push(new BomDetailViewModel(item.Name));
});
}
function BomDetailViewModel(name) {
var self = this;
self.Name = name;
}
function AddFromDb() {
$.ajax({
type: "GET",
url: '@Url.Action("AddSku", "Test")',
success: function (line) {
window.quoteViewModel.AddQuoteLine(line.Sku, line.Description, line.BomDetails);
}
});
}
我已经尝试了很多方法来填充它,但无法弄清楚问题出在哪里,但我希望这只是我正在做或不做的一些愚蠢的事情。
我也尝试过使用 ko.mapping,但我也无法正常工作。
【问题讨论】: