2010-11-24 24 views
12

form form eylemleri iptal asp.net mvc 3 RC bir form gönderirken birden çok form eylemleri uygulamak için nasıl gidebileceğini merak ediyorum.Nasıl yapılır? Kaydet | Kaydet ve Kapat | ASP.NET MVC 3 RC

Bir kullanıcıyı düzenliyorsam, örneğin aşağıdaki düğmelerle bir işlem çubuğuna sahip olmak isterim;

"Kaydet" | "Kaydet ve Kapat" | "İptal"

Kaydet - Formu gönderir ve kaydeder, sizi düzenleme ekranına döndürür. Standart bir giriş/gönderme düğmesi olarak kolayca uygulanabilir. Burada özel bir şey yok. Bunun için

Kontrolör kodu

public ActionResult Edit(UserViewModel model) 
{ 
    ... 
    return RedirectToAction("Edit", model.Id"); 
} 

İptal gibi görünebilir - Sadece bir önceki ekrana geri döndürür. Bunun için bir çapa etiketi kullanmayı düşünüyordum.

<a href="@Request.UrlReferrer" class="button">Cancel</a> 

Ama nasıl uygulanacağı konusunda stumped, aynı form verilerini göndermek için gerektiğinde "Kaydet ve Kapat". Belki bir nullable yakın param olduğu hakkında merak ediyordum?

public ActionResult Edit(UserViewModel model, bool? close) 
{ 
    ... 
    return close.GetValueOrDefault(false) ? RedirectToAction("Index", model.Id" : RedirectToAction("Edit", model.Id"); 
} 

Ancak bu ek paramı bu örnekle birlikte nasıl birlikte gönderirim?

Mümkünse, yukarıdaki örnekte olduğu gibi gönderimi işlemek için tek bir form eylemine sahip olmak isterim.

Ayrıca, bu fikir etrafında başka bir kullanıcı etkileşimi modeliyle başka biri ortaya çıkmış mıdır?

Çözüm

aşağıda Ömer'in öneri kullanarak sona erdi ancak bunun yerine bir dizede geçen bu yüzden ben bütün kontrolörler dize kontrolleri yapmak gerekmez bir enum aldı. Ben <input> butonuna bir dostça "Kaydet ve Kapat" metnini istedi ama bir enum kullanmak istedikleri için

public ActionResult Edit(UserViewModel model, FormAction actionType) 
{ 
    // pre-check 
    if (actionType == FormAction.Cancel) 
    // just return user to previous view and don't save. 

    // Save code 

    if (actionType == FormAction.Save) 
    return ... 
    else if (actionType == FormAction.SaveAndClose) 
    .... 
} 

Ben ayrıştırılmasını yaptığı FORMACTION için özel ModelBinder uyguladı.

<input> etiketleri için tema zaten yerinde olduğundan <button> etiketini kullanmadım.

cevap

18

Birden aynı name öznitelik ancak farklı value özelliklere sahip bir formda gönderme düğmeleri olabilir. Hangi düğmeye tıklandığında, ilgili value sunucuya gönderilecektir.

Cancel için basit bir bağlantı kullanabilirsiniz, ancak yine de bir düğme olarak ekleyeceğim.

<input type="submit" name="actionType" value="Save" /> 
<input type="submit" name="actionType" value="Save and Close" /> 
<input type="submit" name="actionType" value="Cancel" /> 

Ve eyleminizde, değerleri sınayın.Eğer value Özellikte uzun bir metni olan beğenmezseniz

public ActionResult Edit(string actionType) 
{ 
    if(actionType == "Save") 
    { 
     // Save action 
    } 
    else if (actionType == "Save and Close") 
    { 
     // Save and quit action 
    } 
    else 
    { 
     // Cancel action 
    } 
} 

, standart HTML ayrı bir değer ve ayrı metni tanımlamak sağlayan <button> etiketi kullanabilirsiniz.

+0

http://stackoverflow.com/questions/2423041/using-two- Gönder düğmeleri-iç-tek-form/2426152 # 2426152 – takepara

+0

Teşekkürler Omar. Tam istediğim buydu. Şerefe! –

+0

Sorumu bu yaklaşıma dayalı olarak son çözümle güncelleştirdim. Oldukça benzer, sadece dizeleri yerine bir enum kullanmak için temizlenmiş. –

5

@Omar'ın önerisi mükemmeldir. Kullanıcının bir nesneyi silmesi istendiğinde bir onay istediğimde, bunu biraz daha genel bir şekilde yaptığım gibi. Not! HttpPost içinde, yönteme geçirilen öğeyi kullanmak yerine, nesneyi tekrar çekiyorum. Bir DB çağrısını, görünümü "Öğe" nin doldurulması için tüm özellikleri içerecek şekilde azaltabilirsiniz.

İşte Görünüm Modeli var

public class DeleteViewModel<T> { 
    public string ActionType { get; set; } 
    public T Item { get; set; } 
} 

Kontrolör

public ActionResult Delete(int id) { 
     DeleteViewModel<Category> model = new DeleteViewModel<Category>() { 
      Item = categoryRepository.Categories.FirstOrDefault(x => x.CategoryID == id) 
     }; 
     return View(model); 
    } 

    [HttpPost] 
    public ActionResult Delete(DeleteViewModel<Category> model) { 
     if (model.ActionType == "Cancel") 
      return RedirectToAction("Index"); 
     else if (model.ActionType == "Delete") { 
      var cat = categoryRepository.Categories.FirstOrDefault(x => x.CategoryID == model.Item.CategoryID); 
      categoryRepository.Delete(cat); 
      return RedirectToAction("Index"); 
     }   
     //Unknown Action 
     return RedirectToAction("Index"); 
    } 

Görünüm

<div class="actions"> 
     <div class="actions-left"><input type="submit" value="Cancel" name="ActionType"/></div> 
     <div class="actions-right"><input type="submit" value="Delete" name="ActionType" /></div> 
    </div> 
+0

Bu çözümü daha iyi beğeniyorum çünkü üzerinde hareket eden Modeli geçmenize izin veriyor. – Buzzer