У меня есть модальное окно Razor, которое получает данные от BE.
Вот модель
public class LocationServiceEditDto: EntityDto<int?>
{
public int ServiceId { get; set; }
public int? LocationId { get; set; }
public decimal? Cost { get; set; }
public int? MaterialUomId { get; set; }
public string MaterialUomName { get; set; }
public string LocationName => Location?.Name;
[JsonIgnore]
public LocationNameDto Location { get; set; }
public ICollection<LocationServicePriceDto> LocationServicePrices { get; set; }
}
в BE я пополняю коллекцию LocationServicePrices
А затем в View я показываю это вот так
<div class = "modal-body box-wrap">
<form role = "form" novalidate class = "form-validation" name = "ServicePriceInformationsForm">
<input type = "hidden" asp-for = "Id"/>
<input type = "hidden" asp-for = "ServiceId"/>
<div class = "form-group">
<label class = "required-label">@L("Location")</label>
<select class = "form-control" required asp-for = "LocationId">
<option value = "">@L("SelectALocation")</option>
@if (Model.LocationId.HasValue)
{
<option selected value = "@Model.LocationId">@Model.LocationName</option>
}
</select>
</div>
<div class = "form-group">
<label class = "required-label">@L("MaterialUom")</label>
<select class = "form-control" asp-for = "MaterialUomId" id = "ServicePrice_MaterialUomId">
<option value = "">Select an option</option>
@if (Model.MaterialUomId > 0)
{
<option value = "@Model.MaterialUomId">@Model.MaterialUomName</option>
}
</select>
</div>
<div class = "form-group">
<label>@L("Cost")</label>
<input class = "form-control" type = "text" asp-for = "Cost" data-rule-number = "true" data-rule-min = "0" data-rule-max = "@AppConsts.MaxDecimalDatabaseLength">
</div>
@foreach (var tier in @Model.LocationServicePrices)
{
<div class = "form-group">
<label>@tier.PricingTierName</label>
<input class = "form-control" type = "text" asp-for = "@tier.PricePerUnit" data-rule-number = "true" data-rule-min = "0" data-rule-max = "@AppConsts.MaxDecimalDatabaseLength">
</div>
}
</form>
</div>
Я хочу обновить каждый ввод в foreach и обновить @Model.LocationServicePrices
.
На данный момент, когда я ввожу значения и отправляю данные в BE, коллекция равна нулю.
Я сохраняю такие данные в файле .js
this.save = function () {
if (!_$form.valid()) {
_$form.showValidateMessage();
return;
}
var servicePrice = _$form.serializeFormToObject();
_modalManager.setBusy(true);
_serviceService.editLocationService(servicePrice).done(function () {
abp.notify.info('Saved successfully.');
_modalManager.close();
abp.event.trigger('app.createOrEditServicePriceModalSaved');
}).always(function () {
_modalManager.setBusy(false);
});
};
Код для метода serializeFormToObject
$.fn.serializeFormToObject = function () {
var $form = $(this);
var fields = $form.find('[disabled]');
fields.prop('disabled', false);
var json = $form.serializeJSON();
fields.prop('disabled', true);
return json;
};
Как я могу это исправить?
Не уверен, как работает весь ваш js-код, но система привязки модели связывает свойство по имени. Если ваш сервер получает данные формы, поскольку LocationServicePrices
является моделью списка, вам необходимо передавать их по имени, например: name = "LocationServicePrices[@i].PricePerUnit"
.
@{
int i = 0;
}
@foreach (var tier in @Model.LocationServicePrices)
{
<div class = "form-group">
<label>@tier.PricingTierName</label>
<input class = "form-control" type = "text" asp-for = "@tier.PricePerUnit"
name = "LocationServicePrices[@i].PricePerUnit" data-rule-number = "true" data-rule-min = "0" data-rule-max = "@AppConsts.MaxDecimalDatabaseLength">
</div>
i++;
}
Если ваш бэкэнд получает строку json, правильный json должен быть:
{
"Id": "",
"ServiceId": "2031",
"LocationId": "2",
"MaterialUomId": "6",
"Cost": "123",
"LocationServicePrices": [
{ "PricePerUnit": "1"},
{ "PricePerUnit": "2"},
{"PricePerUnit": "3"},
{"PricePerUnit": "4"},
{"PricePerUnit": "5" }
]
}
ОБНОВЛЯТЬ:
О том, как сгенерировать строку json. Вы можете использовать js-код ниже:
@model LocationServiceEditDto
<div class = "modal-body box-wrap">
<form role = "form" novalidate class = "form-validation" name = "ServicePriceInformationsForm">
<input type = "hidden" asp-for = "Id" />
<input type = "hidden" asp-for = "ServiceId" />
<div class = "form-group">
<select class = "form-control" required asp-for = "LocationId">
<option value = "">sssss</option>
<option value = "1">aa</option>
<option value = "2">bb</option>
<option value = "3">cc</option>
</select>
</div>
<div class = "form-group">
<select class = "form-control" asp-for = "MaterialUomId" id = "ServicePrice_MaterialUomId">
<option value = "">Select an option</option>
@if (Model.MaterialUomId > 0)
{
<option value = "@Model.MaterialUomId">@Model.MaterialUomName</option>
}
</select>
</div>
<div class = "form-group">
<input class = "form-control" type = "text" asp-for = "Cost" data-rule-number = "true" data-rule-min = "0" data-rule-max = "7">
</div>
@{
int i = 0;
}
@foreach (var tier in @Model.LocationServicePrices)
{
<div class = "form-group">
<label>@tier.PricingTierName</label>
<input class = "form-control" type = "text" asp-for = "@tier.PricePerUnit"
name = "LocationServicePrices[@i].PricePerUnit" data-rule-number = "true" data-rule-min = "0" data-rule-max = "7">
</div>
i++;
}
</form>
</div>
@section Scripts
{
<script>
var formData = {};
$('form[name = "ServicePriceInformationsForm"]').serializeArray().forEach(function (item) {
formData[item.name] = item.value;
});
// Convert LocationServicePrices data to JSON array
formData["LocationServicePrices"] = [];
$('.form-group input[id$ = "PricePerUnit"]').each(function () {
formData["LocationServicePrices"].push({ "PricePerUnit": $(this).val() });
});
console.info(formData)
console.info(JSON.stringify(formData))
</script>
}
Я обновил свой пост, добавив код метода serializeFormToObject
. Я попробовал ваш код и получил это { "0.PricePerUnit": "1", "1.PricePerUnit": "2", "2.PricePerUnit": "3", "3.PricingTierId": "9", "3.PricePerUnit": "4"}
в LocationServicePrices
Привет @EugeneSukh, serializeJSON
также не является функцией build-injs/jqeury. Вам лучше поделиться достаточным количеством кода. Вы пытались жестко закодировать переменную servicePrice
с помощью моей общей правильной строки jsong? Можете ли вы сначала попробовать и проверить, может ли он пройти на серверную часть и получить соответствующее значение?
Я попытался добавить вашу строку JSON, и да, она работает правильно. Как я могу воспроизвести это в коде?
Привет @EugeneSukh, как я уже говорил, ваша строка json преобразуется с помощью функции:serializeFormToObject
, затем вы делитесь этой функцией. Но в вашей функции она все еще содержит пользовательскую функцию или, возможно, функцию сторонней библиотеки:serializeJSON
, вам нужно поделиться достаточным количеством кода.
Как я могу правильно сериализовать без этой функции?
Привет @Eugene Sukh, проверьте мой обновленный ответ.
Привет @Eu, я вижу твою новую ветку, если твоя строка json if:
{ "Id": "", "ServiceId": "2031", "LocationId": "2", "MaterialUomId": "6", "Cost": "123", "LocationServicePrices": { "0.PricePerUnit": "1", "1.PricePerUnit": "2", "2.PricePerUnit": "3", "3.PricePerUnit": "4", "4.PricePerUnit": "5" } }
, это неправильно, тебе нужно поделиться своим методомserializeFormToObject
.