#c# #asp.net-mvc #partial-views #asp.net-mvc-4
#c# #asp.net-mvc #частичные представления #asp.net-mvc-4
Вопрос:
Это ситуация:
У меня есть ASP.NET Приложение на MVC 4. Когда я запускаю приложение, я перехожу на страницу, и индексное действие на контроллере принимает Guid в качестве параметра id. С этим идентификатором я получаю список элементов из базы данных и помещаю его в ViewModel. Эта ViewModel передается представлению, в котором перечислены все элементы в виде ActionLink (при необходимости может быть изменен). Когда я нажимаю на один из элементов, я хочу получить список других элементов, основанный на идентификаторе выбранной ссылки, и показать этот новый список прямо рядом с первым списком.
Но это мой вопрос (и где я застрял на 2 дня): каков наилучший способ сделать это? Перейдите на новую страницу или используйте частичный просмотр. Потому что я немного пробовал и то, и другое, и, очевидно, я, должно быть, что-то сделал неправильно, потому что, похоже, ничего не сработало. Мне не нужны никакие AJAX-материалы или подобные помощники, только правильный способ сделать это … 🙂
Заранее спасибо!
Обновление: код, который у меня уже есть
Вид
@foreach (var order in Model.Orders)
{
<p>@Html.ActionLink(order.Name,
"OrderItems",
"OrdersController",
new { id = order.Id },
null)
</p>
}
@if (Model.Detail != null)
{
@Html.Partial("_OrderItemsByOrder", Model)
}
Контроллер
public ActionResult Index(Guid id)
{
var orders = Services.GetOrders(id);
var viewModel = new OrdersViewModel { Orders = orders };
return View(viewModel);
}
public ActionResult OrderItems(Guid id, OrdersViewModel model)
{
var orderItems = Services.GetOrderLines(id);
var viewModel = new OrdersViewModel
{
Orders = model.Orders,
Detail = new OrderDetailViewModel { OrderItems = orderItems }
};
return PartialView(viewModel);
}
Комментарии:
1. Я немного смущен тем, что именно вы пытаетесь вернуть пользователю. Вы пытаетесь вернуть список заказов, а затем иметь возможность щелкнуть по ним / выбрать их и просмотреть детали этого заказа?
Ответ №1:
Вероятно, вы (для удобства пользователя) захотите использовать AJAX и вывести список «других элементов» из ответа AJAX (вероятно, JSON или частичная HTML-страница, если вы действительно хотите избежать javascript)
Если вы действительно не хотите использовать AJAX, вы могли бы извлечь все элементы и все «другие элементы» и изначально сохранить их в «скрытых» полях и сделать два поля выбора.
http://www.plus2net.com/javascript_tutorial/dropdown-list.php
Пример:http://www.plus2net.com/javascript_tutorial/dropdown-list-demo.php
Честно говоря, я бы выбрал опцию AJAX, если только люди не будут часто использовать каждый из выпадающих списков или если количество опций очень ограничено.
Ajax:http://www.plus2net.com/php_tutorial/ajax_drop_down_list.php
И просто хочу отметить, что это не обязательно должны быть выпадающие списки, которые используются для выбора / заполнения, вам просто нужно изменить код, чтобы заполнить div или любой другой элемент, который вы хотите 🙂
Комментарии:
1. Извините, но ваш ответ мне ничего не проясняет.. Удобство использования сейчас не проблема, мне нужна базовая структура о том, как это сделать..
2. Может быть, вы могли бы опубликовать то, что у вас есть прямо сейчас? Вы просмотрели примеры и исходный код, чтобы увидеть, что они делают?
3. @Abbas для этого нужно использовать javascript. У вас есть 2 варианта: либо удалить все «другие параметры» при начальной загрузке страницы, либо динамически удалять их по мере необходимости с помощью AJAX. Вы не хотите загружать новую страницу каждый раз, когда кто-то выбирает первый вариант, поскольку это было бы сложнее и в то же время менее удобно для пользователя.
4. Я отредактировал свой пост с помощью некоторого имеющегося у меня кода. Хорошо, теперь, если я использую AJAX, как мне это сделать, поскольку я не эксперт в этом. И должен ли я отображать результат в том же виде или … ?
5. В случае AJAX: одно представление с тем, что у вас есть, и одно представление, которое отображает только список с «другими элементами».
Ответ №2:
Есть несколько способов, которыми вы могли бы создать главную / подробную страницу, подобную этой, на самом деле нет лучшего способа сделать это. AJAX может быть самым элегантным и удобным для пользователя, но это ни в коем случае не «правильный» ответ.
Глядя на опубликованный вами код, самое простое, что вы могли бы сделать, это иметь один метод действия и одно представление.
public class OrdersViewModel
{
public IEnumerable<Order> Orders { get; set; }
public OrderItems SelectedOrderItems { get; set; }
}
public ActionResult Orders(Guid id, Guid? orderId)
{
var model = new OrdersViewModel();
model.Orders = Services.GetOrders(id);
if (orderId != null)
{
model.SelectedOrderItems = Services.GetOrderLines(orderId);
}
return View(model);
}
Недостатком этого довольно простого подхода является то, что у вас, возможно, будет 2 Guid, загрязняющих ваш URL, и этот пример не подтверждает, что OrderID действительно принадлежит (пользователю?) Идентификатор — независимо от того, что представляет первый Guid. Однако вы могли бы справиться с этим с помощью нескольких строк кода.
Более элегантный способ справиться с этим, если вы не возражаете против изменения вашего URL-адреса, — придерживаться второго метода действия. Я хотел бы надеяться, что вы сможете определить «владельца» детали заказа из самой детали или каким-либо образом, который не потребовал бы от вас передавать это в метод action. Это помогает гарантировать, что в вашем представлении отображаются только сведения из правильного шаблона.
public ActionResult OrderDetails(Guid id /*the id of the order*/)
{
var orderLines = Services.GetOrderLines(id);
var model = new OrdersViewModel();
//ideally you could get to the "owner id" of the order from the order lines itself
//depending on how your domain model is set up
model.Orders = Services.GetOrders(orderLines.Order.OwnerId);
model.SelectedOrderItems = orderLines;
return View("Orders", model); //render the same view as the Orders page if like
}
Ваш вид, указанный в вашем вопросе, в значительной степени может остаться прежним. Визуализируйте ссылки на действия, которые представляют все заказы. Затем отобразите детали заказа, если таковой имеется в модели:
@if (Model.SelectedOrderItems!= null)
{
/* markup here or a render partial call */
}
Если вы отображаете детали заказа на других страницах, вам захочется поместить детали вашего заказа в частичный вид, чтобы не дублировать какую-либо из ваших разметок. Если это отображается только здесь, то на самом деле нет причин, по которым вы не могли бы правильно отобразить свою разметку в этом представлении.
Ответ №3:
Я бы предложил что-то вроде этого:
- У вас есть контроллер с действием. Действие принимает два параметра, один с вашим идентификатором guid и один необязательный с каким-либо другим идентификатором
- У вас есть свой «mainview», в котором перечислены ваши элементы
- В вашем контроллере добавьте еще одно действие, на этот раз только с одним параметром, идентификатором
- Добавьте другой вид, но на этот раз частичный, в котором перечислены другие ваши элементы
Действие 1 помещает список с элементами в viewmodel и необязательный идентификатор для отображения некоторых других элементов.
Действие 3 помещает список с некоторыми другими элементами в viewmodel
Действие 1 отображает вид 2, а действие 3 отображает вид 4. Вид 2 отображает, если так указано в viewmodel, действие 3.
В принципе, когда ни один конкретный элемент не выбран, цепочка выполнения будет выглядеть следующим образом: 1 => 2 => Готово
Но когда элемент выбран, цепочка будет выглядеть следующим образом: 1 => 2 => 3 => 4
(Конечно, это всего лишь один из способов сделать что-то ..)