Asp.net mvc 敲除和ASP.NET MVC编辑表单在映射后显示重复的行

Asp.net mvc 敲除和ASP.NET MVC编辑表单在映射后显示重复的行,asp.net-mvc,razor,knockout.js,knockout-mapping-plugin,Asp.net Mvc,Razor,Knockout.js,Knockout Mapping Plugin,大家早上好 我找了这个问题,但找不到。 我正在尝试使用knockout、嵌套集合和计算变量在asp.net mvc应用程序中编辑报价 创作进展顺利。但编辑表单显示重复的行。就像服务器显示其数据,而KNOCKOUT也显示其自己的数据一样 当我查看控制台时,我的击倒模式被称为正确的次数 我和一个编辑一起工作 我的淘汰赛: var QuotationDetail = function (data) { var self = this; var pro

大家早上好 我找了这个问题,但找不到。 我正在尝试使用knockout、嵌套集合和计算变量在asp.net mvc应用程序中编辑报价

创作进展顺利。但编辑表单显示重复的行。就像服务器显示其数据,而KNOCKOUT也显示其自己的数据一样

当我查看控制台时,我的击倒模式被称为正确的次数 我和一个编辑一起工作

我的淘汰赛:

var QuotationDetail = function (data) {

        var self = this;

                var productsData = @Html.Raw(Json.Encode(ViewBag.Products));
        self.productCategories = ko.observableArray(productsData);


        if (data != null) {
            self.QuotationId = ko.observable();
            self.Id = ko.observable();


            self.Quantity = ko.observable(data.Quantity);
            self.Discount = ko.observable(data.Discount);
            self.UniteQuotation = ko.observable(data.UniteQuotation);
            self.Description = ko.observable(data.Description);
            self.ProductCategory = ko.observable();
            self.Product = ko.observable();
            self.PriceUnit = ko.observable(data.PriceUnit);

            self.ProductName = ko.observable(data.ProductName);
            self.PriceHT = ko.pureComputed(function () {
                return self.PriceUnit() ? self.PriceUnit() * parseInt("0" + self.Quantity(), 10) - ((self.PriceUnit() * parseInt("0" + self.Quantity(), 10) * parseFloat("0" + self.Discount()) / 100)) : 0;
            });
     

        } else {
            self.QuotationId = ko.observable();
            self.Id = ko.observable();

            console.log('pas de données');
            self.Quantity = ko.observable(1);
            self.Discount = ko.observable(0);
            self.UniteQuotation = ko.observable();
            self.Description = ko.observable();
            self.ProductCategory = ko.observable();
            self.Product = ko.observable();
            self.PriceUnit = ko.observable();

            self.ProductName = ko.observable();
            self.PriceHT = ko.pureComputed(function () {
                return self.PriceUnit() ? self.PriceUnit() * parseInt("0" + self.Quantity(), 10) - ((self.PriceUnit() * parseInt("0" + self.Quantity(), 10) * parseFloat("0" + self.discount()) / 100)) : 0;
            });
            self.Product.subscribe(function () {
                if (self.Product()) {
                    self.PriceUnit(self.Product().ProductPrice);
                    self.ProductName(self.Product().Title);
                    self.Description(self.Product().Description);
                }
                else {
                    self.priceunit(0);
                }

            });
        }
       
            // fin

    };

    var mapping = {

        create: function (options) {
            return new QuotationDetail(options.data);
        }
    }
    var Quotation = function () {

        var self = this;
      
         var data = @Html.Raw(Json.Encode(Model.QuotationDetails));
        console.log('Lancement du mapping des détails : ' + JSON.stringify(data));

        self.lines = ko.mapping.fromJS(data, mapping);

        //self.lines = ko.observableArray(ko.utils.arrayMap(appdatas, function (line) {
        //    return new QuotationDetail(line);
        //}));
           //self.lines = ko.utils.arrayMap(appdatas, function (data) { return new QuotationDetail(data); });
      


        self.discountgeneral = ko.observable(0);

        var dataTvas = @Html.Raw(Json.Encode(ViewBag.TVAs));
        console.log(JSON.stringify(dataTvas));
        self.tvas = ko.observableArray(dataTvas);

        self.tva = ko.observable();
        self.grandTotalService = ko.pureComputed(function () {
            var totalService = 0;
            $.each(self.lines(), function () { totalService += this.PriceHT() })
            return totalService;
        });
        // Put one line in by default
        self.grandTotalHT = ko.pureComputed(function () {
            var totalHT = 0;
            $.each(self.lines(), function () { totalHT += this.PriceHT() - (this.PriceHT() * parseFloat("0" + self.discountgeneral()) / 100) })
            return totalHT;
        });

        self.grandTotalDisc = ko.pureComputed(function () {
            var totalDisc = 0;
            $.each(self.lines(), function () { totalDisc += (this.PriceHT() * parseFloat("0" + self.discountgeneral()) / 100) })
            return totalDisc;
        });
        self.grandTotalTVA = ko.pureComputed(function () {
            var totalTVA = 0;
            $.each(self.lines(), function () { totalTVA += this.PriceHT() * parseFloat("0" + self.tva().Pourcentage) / 100 })
            return totalTVA;
        });
        self.grandTotal = ko.pureComputed(function () {
            var total = 0;
            $.each(self.lines(), function () { total += this.PriceHT() - (this.PriceHT() * parseFloat("0" + self.discountgeneral()) / 100) + (this.PriceHT() * parseFloat("0" + self.tva().Pourcentage) / 100) })
            return total;
        });


        // Operations
        self.addDetail = function () {
            self.lines.push(new QuotationDetail())
        };
        self.removeDetail = function (line) { self.lines.remove(line) };

    };



    $(document).ready(function () {
        ko.applyBindings(new Quotation());
    });
我的编辑模板视图

<div class="detail">
    <div class="row" data-bind="ifnot: ProductName">
        <div class="form-group col-md-6">
            <label>Catégorie</label>
            <select class="form-control" data-bind="options: productCategories, optionsText: 'Title',optionsCaption: 'Catégorie...', value: ProductCategory"> </select>
        </div>
        <div class="form-group col-md-6" data-bind="with:ProductCategory">
            <label>Produit</label>
            <select class="form-control" data-bind="options : Products,optionsText: 'Title',optionsCaption: 'Produit...',value:$parent.Product"> </select>

        </div>
        <div data-bind="with:Product">
           
            <input type="hidden" data-bind="value: Id, attr: {name: 'QuotationDetails[' + $index() + '].ProductId'}" />

        </div>
    </div>
    <div class="form-row">
        <div class="form-group col-md-2">
            <label>Type</label>
            @Html.EnumDropDownListFor(model => model.UniteQuotation, new { data_bind = "value : UniteQuotation", @class = "form-control", placeholder = "Type" })
        </div>

        <div class="form-group col-md-4">
            <label>Produit</label>
            @Html.TextBoxFor(model => model.ProductName, new { data_bind = "text:ProductName", @class = "form-control", @readonly = "readonly"  })
    
        </div>
        <div class="form-group col-md-1">

            <h5> Quantité <span class="text-danger">*</span></h5>
            <div class="controls">
                @Html.TextBoxFor(model => model.Quantity, new
                {
                    data_bind = "textInput :Quantity,valueUpdate:'afterkeydown'",
                    @class = "form-control",
                    required = "required",
                    data_validation_required_message = "Veuillez renseigner une quantité"
                })

            </div>
        </div>

        <div class="form-group col-md-2">

            <h5> Prix unitaire <span class="text-danger">*</span></h5>
            <div class="controls">

                @Html.TextBoxFor(model => model.PriceUnit, new { data_bind = "textInput:PriceUnit,valueUpdate: 'afterkeydown'", @class = "form-control", required = "required", data_validation_required_message = "Veuillez renseigner un prix unitaire" })

            </div>
        </div>


        <div class="form-group col-md-1">
            <label>Remise (%)</label>
            @Html.TextBoxFor(model => model.Discount,
                                                        new { data_bind = "textInput: Discount", @class = "form-control" })
        </div>
        <div class="form-group col-md-1">
            <label>Total HT</label>
            € @Html.TextBoxFor(model => model.PriceHT, new { data_bind = "value:formatCurrencyDouble(PriceHT())", @class = "form-control", @readonly = "readonly" })

        </div>

        <div class="form-group col-md-1">
            <label></label>
            <a href='#' data-bind='click: $parent.removeDetail'><i class="far fa-times-circle" style="font-size:40px"></i></a>

        </div>
    </div>
    <div class="form-group col-md-12">
        @Html.TextAreaFor(model => model.Description, new { data_bind = "value:Description , summernote: { height: 250 },valueUpdate: 'afterkeydown'", rows = "10", @class = "form-control summernote", placeholder = "Description" })
        @Html.ValidationMessageFor(model => model.Description, "", new { @class = "text-danger" })

    </div>


</div>

凯蒂戈里酒店
产品
类型
@EnumDropDownListFor(model=>model.UniteQuotation,新的{data_bind=“value:UniteQuotation”,@class=“form control”,placeholder=“Type”})
产品
@Html.TextBoxFor(model=>model.ProductName,新的{data\u bind=“text:ProductName”,@class=“form control”,@readonly=“readonly”})
定量*
@Html.TextBoxFor(model=>model.Quantity,新建)
{
data_bind=“text输入:数量,值更新:'afterkeydown',
@class=“表单控制”,
required=“required”,
需要数据验证消息=“Veuillez renseigner une quantité”
})
统一大奖赛*
@Html.TextBoxFor(model=>model.PriceUnit,新{data\u bind=“textInput:PriceUnit,valueUpdate:'afterkeydown',@class=“form control”,required=“required”,data\u validation\u required\u message=“Veuillez renseigner un prix unitaire”})
减量(%)
@Html.TextBoxFor(model=>model.Discount,
新{data_bind=“textInput:Discount”,@class=“form control”})
总HT
€@Html.TextBoxFor(model=>model.PriceHT,new{data_bind=“value:formatCurrencyDouble(PriceHT())”,@class=“form control”,@readonly=“readonly”})
@Html.TextAreaFor(model=>model.Description,new{data_bind=“value:Description,summernote:{height:250},valueUpdate:'afterkeydown',rows=“10”,@class=“form control summernote”,placeholder=“Description”})
@Html.ValidationMessageFor(model=>model.Description,“,new{@class=“text danger”})
我已经疯了两个星期了。你能帮我吗