knockout.js 正在将KnockoutJS模型发布到MVC控制器,< T>List中的List< T>为空

41ik7eoe  于 2022-11-10  发布在  其他
关注(0)|答案(1)|浏览(153)

我对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,但是我也不能让它工作。

lp0sw83n

lp0sw83n1#

我设法让这个工作,所以希望它能帮助别人在未来。
我删除了@Using(Html.BeginForm)
我将提交按钮更改为普通按钮,并向函数添加了数据绑定

<input type="button" value="Submit" class="btn btn-satcom-primary btn-wider" id="btnSubmit" data-bind="click: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);
            }
        });
    }

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

相关问题