2010-02-15 6 views
2

J'ai une vue partielle liée à un objet Cart. Cart a une collection de CartLines. Ma vue est ci-dessous:Problème de formulaire imbriqué de liaison de modèle ASP.NET

 <tbody> 
     <% foreach (var line in Model.Lines) { %> 
     <tr> 
      <td align="center"><%=Html.CatalogImage(line.Product.DefaultImage, 80) %></td> 
      <td align="left"> 
       <%=Html.ActionLink(line.Product.Name, "Product", "Catalog", 
        new { productId = line.Product.Id }, new { title = "View " + line.Product.Name })%> 
      </td> 
      <td align="right"><%= line.Product.Price.ToString("c")%></td> 
      <td align="center"> 
       <%=Html.Hidden("lines[" + i + "].key", line.Product.Id) %> 
       <%=Html.TextBox("lines[" + i + "].value", line.Quantity, new { @class = "quantity" })%> 
      </td> 
      <td align="right"><%= (line.LineTotal).ToString("c")%></td> 
      <td> 
       <%using (Ajax.BeginForm("RemoveFromCart", "Cart", 
         new {ProductId = line.Product.Id, returnUrl = ViewData["returnUrl"]}, 
         new AjaxOptions { UpdateTargetId="cart", LoadingElementId="loading" })) 
        {%>       
         <input type="image" src="<%=AppHelper.ImageUrl("delete.gif")%>" value="Remove item" /> 
       <%} %> 
      </td> 
     </tr> 
     <% i++; } %> 
    </tbody> 

Il y a deux choses à noter. Le premier est que j'utilise un formulaire par ligne pour supprimer des éléments.

La seconde est que j'avais essayé de permettre aux utilisateurs de modifier la quantité d'articles en ligne, puis cliquez sur un bouton de mise à jour pour passer toutes les modifications apportées à l'action du contrôleur:

 // POST: /Cart/Update 
    [HttpPost] 
    public ActionResult Update(Cart cart, IDictionary<int,int> lines, string returnUrl) 
    { 
     foreach (var line in lines) { 
      Product p = _catalogService.GetProduct(line.Key); 
      cart.UpdateItem(p, line.Value); 
     } 

     if (Request.IsAjaxRequest()) 
      return PartialView("Cart", cart); 
     else 
      return RedirectToAction("Index", new { returnUrl }); 
    } 

Notez que j'utilise un dictionnaire puisque je suis seulement préoccupé par le produit et la quantité. Je n'aime pas vraiment le fait que je dois récupérer le produit avant d'appeler cart.UpdateItem mais je n'ai pas compris comment passer le produit du modèle à mon action au lieu de l'id. Le problème principal cependant, est plutôt bêtement j'ai enveloppé le chariot entier sous une forme afin que je puisse poster les valeurs et ensuite passé une bonne heure se demandant pourquoi les choses ne fonctionnaient pas correctement dans IE - doh! formes imbriquées

Alors je suis coincé sur la façon de contourner ce problème. Je veux la possibilité de supprimer des éléments individuellement, mais permettre à un utilisateur de modifier les quantités d'éléments et ensuite passer toutes les modifications à la fois au contrôleur. Je ne peux pas utiliser les liens pour mon action de suppression car j'aurais besoin d'utiliser javascript pour forcer un post et tout doit fonctionner sans Javascript activé.

[Mise à jour]

Est-ce une meilleure solution est de permettre des mises à jour sur mon classeur de modèle personnalisé? De cette façon, je pourrais faire des changements dans ma vue et renvoyer l'objet panier au contrôleur - bien que je ne sois pas sûr que cela soit possible avec les collections enfants (Cart.CartItems). J'ai regardé des sites comme Amazon et il semblerait qu'ils enveloppent l'ensemble du panier dans un formulaire et que les boutons de mise à jour globaux et les boutons d'élément individuels suppriment la même action lorsque javascript est désactivé. Toute aide serait appréciée.

Merci, Ben

Répondre

0

Il n'y a qu'une seule façon ici et thats la manière laide. Avoir 1 forme autour de tout. Ensuite, dans l'action, vous devez vérifier quel bouton a été enfoncé (vous obtenez le nom du bouton dans la requête).

Il devient encore plus moche avec des différences dans Firefox et IE. Si vous avez appuyé sur un bouton, c'est-à-dire firefox (Ne vous rappelez pas lequel), vous envoyez non seulement le nom du bouton enfoncé, mais également l'emplacement où le bouton a été enfoncé.

Vous avez plus d'options si votre solution peut compter sur les navigateurs compatibles JS. Mais c'est une autre histoire.

+0

J'ai jeté un coup d'oeil à quelques magasins de commerce électronique en utilisant MVC et comment ils traitent javascript désactivé. Il semblerait que la plupart enveloppent le chariot sous une forme pour les mises à jour de quantité et il semblerait qu'ils emploient des demandes d'obtention standard pour enlever des articles du chariot - considéré comme une mauvaise pratique non? –

+0

Oui effectuer une mise à jour via obtenir n'est pas un bon moyen. –

+0

Hmm, je ne suis pas sûr de savoir comment contourner cela alors. Je peux ajouter un bouton de mise à jour par ligne et avoir un chargement de plusieurs formulaires (en me donnant un formulaire de mise à jour et un formulaire de suppression) ou utiliser des liens pour supprimer des éléments, puis utiliser jscript pour détourner le lien et effectuer un poster. Ensuite, je pourrais avoir un seul formulaire pour le bouton de mise à jour.Cependant, si quelqu'un désactive javascript, j'ai alors le problème que mes liens supprimer vont maintenant effectuer un GET. C'est une chose qui serait si facile dans une application web normale :( –

Questions connexes