У меня есть страница, на которой можно создавать и обновлять продукт.
Моя страница создания работает, но я хочу, чтобы эта страница тоже обновлялась, поэтому есть некоторые данные предварительной загрузки, такие как функции и изображения, которые я хочу показать администратору, и это нормально, я предварительно загрузил функции и не испытываю проблем, но я предварительно загрузил изображения с помощью js (поскольку я не мог предварительно загрузить iformfille в модель представления, что вы все сделаете см.)
Я не могу обновить свой продукт, потому что не могу отправить эти предварительно загруженные изображения на контроллер
буду очень признателен за ПОМОЩЬ, ниже приведен мой код
Мое действие для получения данных обновления от службы
public IActionResult ProductDetail(NewProductViewModel product){
var brands = _brand.BrandLookupService().Excute().Select(b => new ProductsBrandViewModel { Id = b.Id, Name = b.Name });
var model = new NewProductViewModel();
var categories = _product.GetCategoriesService().Excute().Data.Select(CategoryMapper.ConvertDto);
if (product.Id==0)
{
ViewBag.Brands = new SelectList(brands, "Id", "Name");
ViewBag.Categories = new SelectList(CategoryMapper.FlattenCategoriesWithLevel(categories), "Id", "Name");
}
else
{
var productDetail= _product.GetProductDetail().Excute(new CategoryDetailParamDTO { Id=product.Id});
if (!productDetail.IsSuccess)
{
return NotFound();
}
model.Id = productDetail.Data.Id;
model.Name=productDetail.Data.Name;
model.Price=productDetail.Data.Price;
model.Description=productDetail.Data.Description;
model.HowToUse=productDetail.Data.HowToUse;
model.IsActive = productDetail.Data.IsDisplayed;
model.Stock = productDetail.Data.Quantity;
model.Features = productDetail.Data.Features.Select(r => new FeatureViewModel { Id=r.Id,Name=r.DisplayName,Value=r.Value}).ToList();
ViewBag.Main = productDetail.Data.MainPicture;
ViewBag.Pictures= productDetail.Data.Pictures.OrderBy(p=>p==productDetail.Data.MainPicture);
ViewBag.Brands = new SelectList(brands, "Id", "Name",productDetail.Data.BrandId);
ViewBag.Categories = new SelectList(CategoryMapper.FlattenCategoriesWithLevel(categories), "Id", "Name",productDetail.Data.CategoryId);
}
return View(model);}
Мои cshtml-коды
@using PetPaw.EndPoint.Areas.Admin.Models.ViewModels.Product
@model NewProductViewModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
*@{
Layout = "~/Areas/Admin/Views/Shared/_AdminLayout.cshtml";
if (Model.Id==0)
{ ViewData["Title"] = "CreateProduct";
}
else
{
ViewData["Title"] = "UpdateProduct";
}
}
افزودن محصول جدید
product info
اطلاعات پایه
product name
category
categories
brand
brands
animal
dog
cat
all
Des
How to use
stock and price
Price
stock
features
@if (Model.Id != 0)
{
for (int i = 0; i < Model.Features.Count(); i++)
{
remove
}
}
add feature
pics
uplaod pic
first will be main bydefault or u can change it
cancel
save
@section Scripts
{
let featureCounter = @(Model.Features?.Count() ?? 0);
const pictures = @Html.Raw(Json.Serialize(ViewBag.Pictures ?? new List()));
}
моя форма продукта на js
let uploadedImages = []; // { id, url, file?, isMain }
document.addEventListener('DOMContentLoaded', function () {
try {
preloadImagesFromServer();
} catch (error) {
console.error('Add product page error:', error);
}
});
// ---------- Features ----------
function addFeature() {
const container = document.getElementById('featuresContainer');
if (!container) return;
const featureId = featureCounter++;
const featureDiv = document.createElement('div');
featureDiv.className = 'row g-2 mb-2';
featureDiv.id = `feature-${featureId}`;
featureDiv.innerHTML = `
remove
`;
container.appendChild(featureDiv);
}
function removeFeature(id) {
const feature = document.getElementById(`feature-${id}`);
if (feature) feature.remove();
}
// ---------- Preload Images ----------
function preloadImagesFromServer() {
const preview = document.getElementById('imagesPreview');
if (!preview) return;
const mainPic = "@ViewBag.Main";
uploadedImages = [];
preview.innerHTML = '';
pictures.forEach((url, index) => {
const isMain = url === mainPic || (!uploadedImages.some(img => img.isMain) && index === 0);
uploadedImages.push({ id: index, url: url, isMain: isMain });
const imageItem = document.createElement('div');
imageItem.className = 'image-preview-item';
imageItem.id = `image-${index}`;
imageItem.innerHTML = `
×
${isMain ? '✓ main' : 'choose as main'}
`;
preview.appendChild(imageItem);
});
if (!uploadedImages.some(img => img.isMain) && uploadedImages.length > 0) {
setMainImage(uploadedImages[0].id);
}
}
// ---------- Upload New Images ----------
function handleImageUpload(event) {
const files = Array.from(event.target.files);
const preview = document.getElementById('imagesPreview');
if (!preview) return;
files.forEach(file => {
const reader = new FileReader();
reader.onload = function (e) {
const imageId = uploadedImages.length;
const isMain = !uploadedImages.some(img => img.isMain); // اولین main
uploadedImages.push({ id: imageId, url: e.target.result, file: file, isMain: isMain });
const imageItem = document.createElement('div');
imageItem.className = 'image-preview-item';
imageItem.id = `image-${imageId}`;
imageItem.innerHTML = `
×
${isMain ? '✓ main' : 'choose as main'}
`;
preview.appendChild(imageItem);
if (isMain) setMainImage(imageId);
};
reader.readAsDataURL(file);
});
}
// ---------- Main Image ----------
function setMainImage(imageId) {
uploadedImages.forEach(img => img.isMain = false);
const mainImg = uploadedImages.find(img => img.id === imageId);
if (mainImg) mainImg.isMain = true;
uploadedImages.forEach(img => {
const btn = document.querySelector(`#image-${img.id} .btn`);
if (btn) {
btn.style.background = img.isMain ? '#8bc34a' : 'rgba(255,255,255,0.9)';
btn.style.color = img.isMain ? 'white' : '#666';
btn.textContent = img.isMain ? '✓ main' : 'choose as main';
}
});
const mainIndexInput = document.getElementById('MainPictureIndex');
if (mainIndexInput) mainIndexInput.value = imageId;
}
// ---------- Remove Image ----------
function removeImage(imageId) {
const imageItem = document.getElementById(`image-${imageId}`);
if (imageItem) imageItem.remove();
uploadedImages = uploadedImages.filter(img => img.id !== imageId);
if (uploadedImages.length > 0 && !uploadedImages.some(img => img.isMain)) {
setMainImage(uploadedImages[0].id);
}
}
моя модель представления
public class NewProductViewModel
{
public long Id { get; set; }
public string Name { get; set; }
public string? Description { get; set; }
public string? HowToUse { get; set; }
public decimal Price { get; set; }
public int Stock { get; set; }
public long CategoryId { get; set; }
public long BrandId { get; set; }
public long AnimalId { get; set; }
public bool IsActive { get; set; }
public int MainPictureIndex { get; set; }
public List ExistingProductPictures { get; set; } = new List();
public List Pictures { get; set; }=new List();
public List Features { get; set; }=new List();
}
Подробнее здесь: https://stackoverflow.com/questions/798 ... m-and-cant
Мобильная версия