MVC3 изменить представление из Jquery

#jquery #asp.net-mvc #asp.net-mvc-3 #jquery-ui #razor

#jquery #asp.net-mvc #asp.net-mvc-3 #jquery-пользовательский интерфейс #razor

Вопрос:

Я новичок в MVC3 и Jquery. Возможно, я не придерживаюсь правильного подхода к этому, пожалуйста, дайте мне знать, если есть лучшее решение.

Я хочу использовать jQuery для изменения представлений в моем приложении MVC. У меня есть список продуктов на главной странице. Когда пользователь нажимает на продукт, я использую Jquery для отправки запроса на сервер с идентификатором продукта и перехода на представление сведений о продукте. Прежде чем менять представления, я создаю эффект разнесения Jquery. Я использую функцию обратного вызова эффекта Jquery для отправки запроса. Когда я отлаживаю свой код. Вызывается контроллер сведений о продукте, который возвращает представление сведений. Но веб-браузер не изменяет представление сведений о продукте. он остается на домашней странице.

Вот мой контроллер продукта:

 public class ProductController : Controller
{

    public ActionResult Details(string productId)
    {
        return View();
    }
}
  

Эффект разнесения Jquery с обратным вызовом:

 $(".productOriginal").click(function () {
            $(this).hide("explode", {}, 1000, productSelectedCallback);
});
  

Обратный вызов Jquery:

 function productSelectedCallback() {
   var prodId = $(this).attr("id");
   var data = { productId: prodId.toString() };
   $(this).load('/Product/Details');
}
  

В дополнение к .load, я использую .post и .ajax и получил тот же результат со всеми. Итак, я, должно быть, в корне упускаю что-то здесь.

Я использую регистровые маршруты по умолчанию. Папка products настроена так же, как и домашняя папка, и имеет файл details.cshtml.

Спасибо за вашу помощь!

Ответ №1:

Попробуйте

 function productSelectedCallback() {
   var prodId = $(this).attr("id");
   var targetUrl = '/Product/Details/'   prodId.toString();
   $(this).load(targetUrl);
}
  

Редактировать:

Измените метод действия на вашем контроллере с

 public ActionResult Details(string productId)
{
    return View();
}
  

Для

 public ActionResult Details(int id)
{
    return View();
}
  

или ваш код jQuery для:

 function productSelectedCallback() {
   var prodId = $(this).attr("id");
   var targetUrl = '/Product/Details/?productId='   prodId.toString();
   $(this).load(targetUrl);
}
  

Вероятно, у вас нет настройки маршрута, чтобы использовать «ProductID» в вашем действии. Вы все еще можете использовать его (если не хотите настраивать маршрут), но он должен быть в строке запроса.

Правка 2:

В свете вашего последнего комментария, я не уверен, что вы действительно хотите использовать AJAX для своего решения, поскольку вы пытаетесь перенаправить с одной страницы на другую. Я бы предложил изменить ваш возвращаемый тип на результат RedirectToAction. Это сообщит браузеру, что вам нужно перенаправить, но это нужно будет сделать в действии, отличном от действия с вашими сведениями о продукте (иначе вы получите бесконечный цикл перенаправления).

Попробуйте что-то вроде этого:

 // In the home controller where Id = the product id
public ActionResult RedirectToProductDetails (int id)
{
    // Use whatever names you want for Id and ProductId, respectively
    return RedirectToAction ("Details", "Products", new { id = id });
}

// And then in your Product Controller:
public ActionResult Details (int id)
{
    var MyProduct = // Get your product from the database or whatever
    return View (MyProduct);
}
  

(Пожалуйста, обратите внимание, что это фактически приведет к двум отключениям для клиента, фактически устраняя любое преимущество использования подхода «AJAX».)

Комментарии:

1. С этим я получил тот же результат. Когда я отлаживаю код, я вижу, что он попадает в контроллер продукта и детализирует действие. Это возвращает вид. Я могу щелкнуть правой кнопкой мыши и выбрать Перейти к просмотру и перейти к нужному виду. Я также могу ввести …../product /details в URL веб-браузера и загрузить правильную страницу.

2. Я попытался полностью убрать идентификатор продукта с картинки. общедоступный ActionResult Details() { return View(); } функция productSelectedCallback() { var prodId = $(this).attr(«id»); var targetUrl = ‘/Product/Details/’; $(this).load(targetUrl); }

3. @Ryand — и что произошло? Можете ли вы запустить его в режиме отладки с перерывом в методе action и посмотреть, вызывается ли он вообще? Вы получаете внутреннюю ошибку или что-то в этом роде? Кроме того, возвращаете ли вы View() или PartialView()?

4. @jdangelo Да, произошло то же самое. Я действительно установил точку останова. Я возвращаю вид (); Есть еще идеи? Спасибо!

5. Я бы порекомендовал PartialView (в противном случае вы будете возвращать полную веб-страницу, а не только ту небольшую часть, которая вас интересует). Попробуйте показать элемент после обработки загрузки. $ (this).show(); Кроме того, я бы подключил FireBug или какой-либо другой HTTP-инспектор, чтобы вы могли наблюдать, как ваши вызовы завершаются и возвращаются на стороне клиента.

Ответ №2:

Обратный вызов jQuery

 function productSelectedCallback() {
   var prodId = $(this).attr("id");
    var BaseUrl = 'http://'   top.location.host ;

    $.ajax({
                type: 'POST',
                url: BaseUrl   '/Product/Details',
                data: ({ productId: prodId.toString() }),
                success: function (resp) {

                }
            });
}
  

Эффект разнесения CallJquery с обратным вызовом:

 $(".productOriginal").click(function () {
            $(this).hide("explode", {}, 1000, productSelectedCallback);
});
  

Вот мой контроллер продукта:

 public class ProductController : Controller
    {
        [HttpPost] 
        public ActionResult Details(string productId)
        {
            return View();
        }
    }
  

Комментарии:

1. Я пробовал это. Когда я устанавливаю точку останова для действия. он попадает в actiona и возвращает представление. Точно так же, как это сделал Груз. Вот код, который я использовал для выполнения ajax-вызова. Единственное отличие, которое я вижу, — это тот URL, я не ставлю перед ним базу. Но я думаю, что мой вызов ajax работает, учитывая, что это нажатие на контроллер и действие.

2. вот код $.ajax({ url: «/Product/Details», тип: ‘POST’, данные: JSON.stringify(data), тип данных: ‘json’, ContentType: ‘application / json, charset=utf-8’, async: false, beforeSend: функция () { }, успех: функция (данные) { }, ошибка: функция () { } });

3. @Ryand. Джонсон Это может показаться глупым вопросом, но помещаете ли вы результирующее представление в HTML DOM (делаете ли вы что-нибудь с представлением?) Браузер не будет автоматически ничего делать после вызова AJAX, вы получаете ответ, а затем выполняете с ним какие-либо действия.

Ответ №3:

На самом деле вы можете добиться этого, используя jquery ajax () вместо load(). И на вашем контроллере добавьте [HttpPost] для получения данных post. Тем не менее, вы можете делать все, что хотите, со своего контроллера, хотите ли вы вернуть представление или перенаправить на действие и т.д.

Комментарии:

1. Оно попадает на контроллер. Я установил там точку останова и прошел через нее. Он возвращает представление. Но браузер не отправляет ответ с новой страницей. он возвращается к исходному. Я также пробовал маршрут ajax с атрибутом httppost. Происходит то же самое. Я прошел через это.

2. Символически это не имеет особого смысла. POST не следует использовать в качестве GET. Это устраняет некоторые преимущества HTTP, которые создают встроенную масштабируемость.

Ответ №4:

попробуйте это: ОТРЕДАКТИРУЙТЕ ДЛЯ ТЕСТА

 $(".productOriginal").click(function (event) {
     event.stopPropagation();

     var 
        _this = this,
        prodId = $(this).attr("id"); // is string

     alert("Id product: "   prodId);

     $(this).hide("explode", 1000,
        function() {
           var data = { productId: prodId };
           $(_this).load('/Product/Details', data, function(responseText){
                alert("responseText :"   responseText);
           });
        }
     );

     return false;
});
  

Комментарии:

1. explode — это эффект пользовательского интерфейса jquery. Я получил точно такой же результат, когда скопировал ваш код. Единственное отличие состояло в том, что изображение продукта исчезло, а не взорвалось.

2. вы можете протестировать код, чтобы увидеть код продукта и результат, и проверить, работает ли это, затем вам нужно посмотреть, куда отправлять результат.

Ответ №5:

Я понял! Спасибо @jdangelo. Я пытался решить проблему, используя неправильные инструменты. Не было причин отправлять что-либо на сервер. У меня уже был идентификатор продукта. Я мог бы просто перенаправить с клиента.

Вместо:

 function productSelectedCallback() {
   var prodId = $(this).attr("id");
   var targetUrl = '/Product/Details/?productId='   prodId.toString();
   $(this).load(targetUrl);
}
  

Я использовал это:

 function productSelectedCallback() {
   var prodId = $(this).attr("id");
   var targetUrl = '/Product/Details/?productId='   prodId.toString();
   top.location.href = targeUrl;
}