asp.net-mvc - Knockout 和 ASP.NET MVC 编辑表单在映射后显示重复行
问题描述
大家早上好,我搜索了这个问题,但我找不到它。我正在尝试在带有淘汰赛的 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>
我已经疯了两个星期了。你能帮我吗?
解决方案
推荐阅读
- typescript - 如何在带有 TypeScript 的 React-Native 中使用 styled-component 键入无状态功能组件?
- docker - 根据环境变量从 dockerignore 中删除特定文件
- react-native - 将 react native app.js 文件连接到使用 react-native-router-flux 的 redux
- security - 蓝牙 LE 特性加密/认证通知不可能?
- python - 如何使用包含 Tensorflow 会话的函数映射数据集?
- ios - 什么时候“手指”事件作为手势发送到 UIGestureRecognizer vs touchesBegan/touchesMoved/touchesEnded 到 UIView
- mongodb - MongoDB聚合查找更改数组的排序
- sql - 尝试将数据类型 bigint 转换为 date 时出错
- apache-nifi - 我将如何使用 QueryDatabaseTable 获取选定的年份记录?
- algorithm - 是否有一种算法可以用仅基于少量起始值的数据填充二维矩阵?