Я использую Entity Framework Core, переопределяя класс DbContext обычным способом, чтобы получить свои данные. ASP.NET Core MVC не имеет элемента управления древовидным представлением, поэтому я использую плагин jQuery jsTree, который вызывает все мои проблемы.
Это класс ProductFolder для категорий продуктов:
Код: Выделить всё
public class ProductFolder
{
[Key]
public int ProductFolderId { get; set; } = 0;
public int ParentFolderId { get; set; } = 0;
public int ProductFolderLevel { get; set; }
[Required]
public string ProductFolderName { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public ProductFolder()
{
ProductFolderId = 0;
ParentFolderId = 0;
ProductFolderLevel = 0;
ProductFolderName = string.Empty;
}
}
Код: Выделить всё
public class Product
{
[Key]
public int ProductId { get; set; } = 0;
public int ParentFolderId { get; set; } = 0;
public int ProductLevel { get; set; }
[Required]
[Display(Name = "Product Name")]
public string ProductName { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
[Display(Name = "Width [DX]")]
public decimal DX { get; set; } = 0.0M;
[Display(Name = "Height [DY]")]
public decimal DY { get; set; } = 0.0M;
[Display(Name = "Depth [DZ]")]
public decimal DZ { get; set; } = 0.0M;
public int CNCMachineId { get; set; } = 1;
[Display(Name = "CNC Machine")]
public string CNCMachineName { get; set; } = string.Empty;
[NotMapped]
ProductFaceCollection ProductFaceCollection;
[NotMapped]
ProductInteriorCollection ProductInteriorCollection;
[NotMapped]
public decimal materialThickness { get; set; } = 18.0M;
public Product()
{
ProductId = 0;
ParentFolderId = 0;
ProductLevel = 1;
ProductName = string.Empty;
ProductFaceCollection = new ProductFaceCollection();
ProductFaceCollection.ProductFaceCells.Add(new ProductFaceCell());
ProductInteriorCollection = new ProductInteriorCollection();
ProductInteriorCollection.ProductInteriorCells.Add(new ProductInteriorCell());
}
}
Код: Выделить всё
public class JsTreeModel
{
public string id { get; set; }
public string text { get; set; }
public int level { get; set; }
public List children { get; set; }
public JsTreeModel()
{
id = "#";
text = string.Empty;
level = 0;
children = new List();
}
public JsTreeModel(int id, string text, int level)
{
this.id = id.ToString();
this.text = text;
this.level = level;
children = new List();
}
}
Код: Выделить всё
using System.Data;
using Newtonsoft.Json;
using Microsoft.AspNetCore.Mvc;
using MyIMS_EFCore.Models;
namespace MyIMS_EFCore.Controllers
{
public class ProductsController : Controller
{
private readonly AppDbContext _context;
private readonly ILogger
_logger;
public ProductsController(AppDbContext context, ILogger logger)
{
_context = context;
_logger = logger;
}
// GET: Products
public IActionResult Index(int? id)
{
// Create jstree nodes from product categories.
JsTreeModel ProductTreeModel = new JsTreeModel();
GetProductFolders(ref ProductTreeModel);
// Save jstree nodes as Json in ViewBag.
ViewBag.Json = JsonConvert.SerializeObject(ProductTreeModel);
// Create product list by product category, represented by jstrees selected node id.
List productList = new List();
productList = _context.Products.Where(x => x.ParentFolderId == id).ToList();
// The model for this controllers View is IEnumerable (to be used to populate the products table), so return the product list.
return View(productList);
}
public void GetProductFolders(ref JsTreeModel treeModel)
{
List rootList = new List();
rootList = _context.ProductFolders.Where(x => x.ParentFolderId == 0).ToList();
PopulateTree(rootList[0].ProductFolderId, treeModel);
}
private void PopulateTree(int parentid, JsTreeModel treeModel)
{
List productFolders = new List();
productFolders = _context.ProductFolders.Where(x => x.ParentFolderId == parentid).ToList();
treeModel.children = new List();
for (int i = 0; i < productFolders.Count; i++)
{
JsTreeModel childNode = new JsTreeModel(productFolders[i].ProductFolderId, productFolders[i].ProductFolderName, productFolders[i].ProductFolderLevel);
treeModel.children.Add(childNode);
PopulateTree(productFolders[i].ProductFolderId, childNode);
}
}
private int StringToInt(string value)
{
if (String.IsNullOrEmpty(value))
{
return -1;
}
int result = 0;
bool b = int.TryParse(value, out result);
if (b == false)
{
return -1;
}
return result;
}
[HttpGet]
[Route("Products/Node/{id}")]
public IActionResult Node(string id)
{
int nodeid = StringToInt(id);
List productList = new List();
productList = _context.Products.Where(x => x.ParentFolderId == nodeid).ToList();
return View(productList);
}
}
}
Код: Выделить всё
@model IEnumerable
@{
ViewData["Title"] = "Products";
}
Products
@* Product categories *@
@* Products *@
ProductName
DX
DY
DZ
@foreach (var item in Model)
{
@item.ProductName
@item.DX
@item.DY
@item.DZ
}
@section Scripts {
[*]
$(document).ready(function () {
$('#jsProductTree').jstree({
'core': {
'themes': {
'icons': false
},
'data': @Html.Raw(ViewBag.Json)/* Product categories data created in Controller*/
},
'plugins': ["defaults","changed","json_data","ui"],
})
$('#jsProductTree').on('changed.jstree', async function(e, data) {
alert("(" + data.node.id + ") " + data.node.text);
let url = `@Url.Action("Node", "Products")/${encodeURIComponent(data.node.id)}`;
let response = await fetch(url);
if (response.ok) {
// parses the JSON response from the server
let newTreeData = response.json();
// redraw the jstree
}
else {
console.error('Failed to load jstree');
}
});
});
}
Я хочу обновить таблицу «Продукты» справа при изменении выбранного узла дерева.
Что работает? Все, включая:
- Заполнение jstree.
- Событие onchanged.jstree, которое вызывает функцию Node(string id). Вызов оповещения в сценарии показывает правильный идентификатор и текст узла jstree, а правильный идентификатор узла передается в переменную int id в функции Node(). Но я понятия не имею, что должна возвращать эта функция, почему или как jstree обрабатывает ее при возвращении.
Я думаю, это скорее тот случай, когда я не понимаю. Я думал, что могу «просто» получить идентификатор выбранного узла древовидного представления, каким-то образом передать его контроллеру, выполнить запрос с этим идентификатором, создать список продуктов, обновить страницу, и таблица отобразит правильные продукты.
Очевидно, это не так просто, и я не знаю, что делаю, настолько хорошо, чтобы даже знать, с чего начать. Я думаю, мне нужно заполнить jstree, вызвав метод GetProductFolders() изнутри jstree, чтобы отключить его от метода Index(), который затем позволит мне обновлять только таблицу при обновлении представления.
Моя основная проблема заключается в следующем: как обновить страницу при смене узла?
Я понимаю, что прошу многого. Я здесь явно тону, и, может быть, лет 10 назад я бы нашел время научиться плавать, но у меня просто нет этого времени, и, кроме того, я, как и Гомер Симпсон, боюсь, что если я втолкну что-нибудь еще в голову, то вытолкнет что-то более важное.
Кстати, я видел много примеров jstree, и здесь есть множество вопросов, связанных с jstree, но они все относительно использования только jstree; Я не нашел ни одного вопроса или примера использования jstree вместе с другим элементом управления, что кажется странным. Полагаю, вы можете использовать только одно древовидное представление в качестве инструмента редактирования каталога?