2012-09-11 19 views
9

के साथ किसी ऑब्जेक्ट के लिए एक संपादन फ़ॉर्म कैसे बना सकता हूं, मेरे पास रेजर का उपयोग करके मेरे एमवीसी एप्लिकेशन के लिए एक संपादन पृष्ठ है।मैं किसी ऑब्जेक्ट के लिए एएसपी.नेट एमवीसी 4 में रेजर

मैं की तरह एक मॉडल है:

public class MyModelObject 
{ 
    public int Id { get; set; } 

    public string Name { get; set; } 

    public string Description { get; set; } 

    public List<MyOtherModelObject> OtherModelObjects { get; set; } 
} 

और MyOtherModelObject लगता है:

public class MyOtherModelObject 
{ 
    public string Name { get; set; } 

    public string Description { get; set; } 
} 

मैं MyModelObject के लिए संपादित करें पेज बनाने रहा हूँ। उपयोगकर्ता को MyModMOelelObject उदाहरणों को बनाने/जोड़ने के लिए MyModelObject के संपादन पृष्ठ पर फ़ॉर्म में स्थान जोड़ने के लिए एक तरीका चाहिए क्योंकि उपयोगकर्ता अन्य मॉडेल ऑब्जेक्ट्स की सूची चाहता है।

मुझे लगता है कि उपयोगकर्ता एक बटन दबा सकता है, जो किसी अन्य क्रिया के लिए AJAX करेगा जो फ़ॉर्म तत्वों का आंशिक दृश्य देता है (क्योंकि कोई फ़ॉर्म टैग नहीं है क्योंकि यह मेरे संपादन पृष्ठ पर फ़ॉर्म का हिस्सा है)। जब उपयोगकर्ता ने सभी MyOtherModelObjects को जोड़ दिया है और वे डेटा भर चुके हैं, तो वे अपने संपादन को मौजूदा MyModelObject में सहेजने में सक्षम होना चाहिए, जो संपादन कार्रवाई में HttpPost करेगा और उम्मीद है कि सभी MyOtherModelObjects सही सूची में होंगे।

मुझे उपयोगकर्ता को जोड़ने के बाद आइटम को फिर से ऑर्डर करने में सक्षम होने की भी आवश्यकता है।

क्या कोई यह जानता है कि यह काम कैसे करें? इस समाधान के साथ नमूना परियोजना, या ऑनलाइन नमूना walkthrough लागू किया है?

+0

आप http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx पर एक नज़र, हालांकि यह है कि क्या उस्तरा वाक्य रचना है हो सकता है (और न ही MVC4 यह संभवतः दे सकता है एक विचार) –

+0

पहली नज़र में। ऐसा लगता है कि यह एक सूची के लिए काम करेगा, लेकिन यह एक सूची के लिए काम करेगा जो किसी अन्य वस्तु का हिस्सा है, और क्या यह मॉडल को बांधने में सक्षम होगा? – DaveH

उत्तर

19

यह blog post में चरण-दर-चरण मार्गदर्शिका शामिल है जो यह बताती है कि इसे कैसे प्राप्त किया जाए।


अद्यतन:

टिप्पणी अनुभाग मैं कदम कैसे अपने परिदृश्य के लिए ऊपर उल्लिखित लेख अनुकूल करने के लिए कदम को दर्शाता हुआ हूँ में अनुरोध के रूप में।

मॉडल:

public class MyOtherModelObject 
{ 
    public string Name { get; set; } 
    public string Description { get; set; } 
} 

public class MyModelObject 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public string Description { get; set; } 
    public List<MyOtherModelObject> OtherModelObjects { get; set; } 
} 

नियंत्रक:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     var model = new MyModelObject 
     { 
      Id = 1, 
      Name = "the model", 
      Description = "some desc", 
      OtherModelObjects = new[] 
      { 
       new MyOtherModelObject { Name = "foo", Description = "foo desc" }, 
       new MyOtherModelObject { Name = "bar", Description = "bar desc" }, 
      }.ToList() 
     }; 
     return View(model); 
    } 

    [HttpPost] 
    public ActionResult Index(MyModelObject model) 
    { 
     return Content("Thank you for submitting the form"); 
    } 

    public ActionResult BlankEditorRow() 
    { 
     return PartialView("EditorRow", new MyOtherModelObject()); 
    } 
} 

देखें (~/Views/Home/Index.cshtml):

@model MyModelObject 

@using(Html.BeginForm()) 
{ 
    @Html.HiddenFor(x => x.Id) 
    <div> 
     @Html.LabelFor(x => x.Name) 
     @Html.EditorFor(x => x.Name) 
    </div> 
    <div> 
     @Html.LabelFor(x => x.Description) 
     @Html.TextBoxFor(x => x.Description) 
    </div> 
    <hr/> 
    <div id="editorRows"> 
     @foreach (var item in Model.OtherModelObjects) 
     { 
      @Html.Partial("EditorRow", item); 
     } 
    </div> 
    @Html.ActionLink("Add another...", "BlankEditorRow", null, new { id = "addItem" }) 

    <input type="submit" value="Finished" /> 
} 

आंशिक (~/Views/Home/EditorRow.cshtml):

@model MyOtherModelObject 

<div class="editorRow"> 
    @using (Html.BeginCollectionItem("OtherModelObjects")) 
    { 
     <div> 
      @Html.LabelFor(x => x.Name) 
      @Html.EditorFor(x => x.Name) 
     </div> 
     <div> 
      @Html.LabelFor(x => x.Description) 
      @Html.EditorFor(x => x.Description) 
     </div> 
     <a href="#" class="deleteRow">delete</a> 
    } 
</div> 

स्क्रिप्ट:

$('#addItem').click(function() { 
    $.ajax({ 
     url: this.href, 
     cache: false, 
     success: function (html) { 
      $('#editorRows').append(html); 
     } 
    }); 
    return false; 
}); 

$('a.deleteRow').live('click', function() { 
    $(this).parents('div.editorRow:first').remove(); 
    return false; 
}); 

टिप्पणी: BeginCollectionItem कस्टम सहायक एक ही लेख मैं करने के लिए लिंक करने के बाद से लिया जाता है, लेकिन मैं इसे यहाँ जवाब की पूर्णता के लिए उपलब्ध कराने के कर रहा हूँ:

public static class HtmlPrefixScopeExtensions 
{ 
    private const string idsToReuseKey = "__htmlPrefixScopeExtensions_IdsToReuse_"; 

    public static IDisposable BeginCollectionItem(this HtmlHelper html, string collectionName) 
    { 
     var idsToReuse = GetIdsToReuse(html.ViewContext.HttpContext, collectionName); 
     string itemIndex = idsToReuse.Count > 0 ? idsToReuse.Dequeue() : Guid.NewGuid().ToString(); 

     // autocomplete="off" is needed to work around a very annoying Chrome behaviour whereby it reuses old values after the user clicks "Back", which causes the xyz.index and xyz[...] values to get out of sync. 
     html.ViewContext.Writer.WriteLine(string.Format("<input type=\"hidden\" name=\"{0}.index\" autocomplete=\"off\" value=\"{1}\" />", collectionName, html.Encode(itemIndex))); 

     return BeginHtmlFieldPrefixScope(html, string.Format("{0}[{1}]", collectionName, itemIndex)); 
    } 

    public static IDisposable BeginHtmlFieldPrefixScope(this HtmlHelper html, string htmlFieldPrefix) 
    { 
     return new HtmlFieldPrefixScope(html.ViewData.TemplateInfo, htmlFieldPrefix); 
    } 

    private static Queue<string> GetIdsToReuse(HttpContextBase httpContext, string collectionName) 
    { 
     // We need to use the same sequence of IDs following a server-side validation failure, 
     // otherwise the framework won't render the validation error messages next to each item. 
     string key = idsToReuseKey + collectionName; 
     var queue = (Queue<string>)httpContext.Items[key]; 
     if (queue == null) 
     { 
      httpContext.Items[key] = queue = new Queue<string>(); 
      var previouslyUsedIds = httpContext.Request[collectionName + ".index"]; 
      if (!string.IsNullOrEmpty(previouslyUsedIds)) 
       foreach (string previouslyUsedId in previouslyUsedIds.Split(',')) 
        queue.Enqueue(previouslyUsedId); 
     } 
     return queue; 
    } 

    private class HtmlFieldPrefixScope : IDisposable 
    { 
     private readonly TemplateInfo templateInfo; 
     private readonly string previousHtmlFieldPrefix; 

     public HtmlFieldPrefixScope(TemplateInfo templateInfo, string htmlFieldPrefix) 
     { 
      this.templateInfo = templateInfo; 

      previousHtmlFieldPrefix = templateInfo.HtmlFieldPrefix; 
      templateInfo.HtmlFieldPrefix = htmlFieldPrefix; 
     } 

     public void Dispose() 
     { 
      templateInfo.HtmlFieldPrefix = previousHtmlFieldPrefix; 
     } 
    } 
} 
+1

बिल्कुल नहीं। यह कैसे वस्तुओं की एक चर लंबाई सूची करने के लिए की चर्चा है, लेकिन यह कैसे वस्तुओं है कि किसी अन्य वस्तु का हिस्सा हैं की एक चर लंबाई सूची के लिए यह करने के लिए चर्चा नहीं करता। – DaveH

+0

@ डेव एच, लेकिन यह लागू करने के लिए मामूली आसान होगा। आपको बस इतना करना है जो सूची जिसे आप संपादित करना चाहते हैं, उसका एक 'IEnumerable ' संपत्ति है कोई नया दृश्य मॉडल पेश करते हैं, आप 'MyModelObject' के साथ अपने प्रश्न में है बिल्कुल के रूप में है। –

+1

आप आसानी से कहते हैं कि आसान है? और यह सब कैसे मूल वस्तु MyModelObject पर बंधेगा। हल करने के लिए छोड़े गए उत्तर का कुछ बड़ा हिस्सा है, जिसमें एमवीसी के डिफ़ॉल्ट मॉडलबिंड व्यवहार को फिर से लिखना शामिल हो सकता है। क्या ऐसा करने के साथ सुरक्षा चिंताएं हैं। मैं इस नमूने के माध्यम से काम कर रहा हूँ, और सुलझाने एकल ऑब्जेक्ट की सूची के लिए कई अन्य मंच पदों पर यह पाया है, लेकिन काफी नमूना मैं कुशलता से अभी तक हल दी नहीं देखा है। – DaveH

0

मैं इस ब्लॉग पोस्ट http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/ में सीखा सबक लेने में सक्षम था और इसे मेरे मामले में लागू करता हूं जहां मॉडलऑब्जेक्ट में कई गुण होते हैं, जिनमें से कई सूची हैं।

मैंने अपनी स्क्रिप्ट को मॉडल के भीतर कई सूचियों के साथ काम करने के लिए उपयुक्त के रूप में संशोधित किया है, और जितनी जल्दी हो सके मेरा समाधान ब्लॉग करूँगा।यह निश्चित रूप से मेरे वर्तमान स्प्रिंट के बाद तक इंतजार करना होगा। जब मैं करूँगा तो मैं लिंक पोस्ट करूंगा।

संबंधित मुद्दे