【问题标题】:POSTing KnockoutJS model to MVC controller, List<T> in List<T> is empty将 KnockoutJS 模型发布到 MVC 控制器,List<T> 中的 List<T> 为空
【发布时间】: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,但我也无法正常工作。

【问题讨论】:

    标签: asp.net-mvc knockout.js


    【解决方案1】:

    我设法让这个工作,所以希望它会在未来对其他人有所帮助。

    我删除了@Using (Html.BeginForm)

    我将提交按钮更改为普通按钮并将数据绑定添加到功能

            <input type="button" value="Submit" class="btn btn-satcom-primary btn-wider" id="btnSubmit" data-bind="click:SaveToDatabase" />
    

    SaveToDatabase 函数:

    self.SaveToDatabase = function () {
            var dataToSend = ko.mapping.toJSON(self);
            $.ajax({
                type: "POST",
                url: '@Url.Action("CreateQuote", "Test")',
                contentType: 'application/json',
                data: dataToSend,
                success: function (data) {
                },
                error: function (err) {
                    console.log(err.responseText);
                }
            });
        }
    

    这会正确地将所有数据发送到控制器。

    【讨论】:

      猜你喜欢
      • 2013-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-20
      相关资源
      最近更新 更多