ผ่าน ViewData เพิ่มเติมไปยังมุมมองบางส่วนที่แข็งแกร่ง


174

ฉันมีมุมมองบางส่วนที่ใช้พิมพ์ ProductImage เป็นอย่างมากและเมื่อมีการแสดงผลฉันต้องการให้ ViewData เพิ่มเติมบางอย่างซึ่งฉันสร้างขึ้นแบบไดนามิกในหน้าที่มีอยู่ ฉันจะส่งผ่านทั้งวัตถุที่พิมพ์อย่างยิ่งและ ViewData ที่กำหนดเองของฉันไปยังมุมมองบางส่วนด้วยการโทร RenderPartial ได้อย่างไร

var index = 0;
foreach (var image in Model.Images.OrderBy(p => p.Order))
{
  Html.RenderPartial("ProductImageForm", image); // < Pass 'index' to partial
  index++;
}

คำตอบ:


251

RenderPartial ใช้พารามิเตอร์อื่นที่เป็นเพียง ViewDataDictionary คุณใกล้จะถึงแล้วเรียกมันว่า:

Html.RenderPartial(
      "ProductImageForm", 
       image, 
       new ViewDataDictionary { { "index", index } }
); 

โปรดทราบว่าสิ่งนี้จะแทนที่ ViewData เริ่มต้นที่ Views ทั้งหมดอื่น ๆ ของคุณมีตามค่าเริ่มต้น หากคุณกำลังเพิ่มอะไรลงใน ViewData มันจะไม่อยู่ในพจนานุกรมใหม่นี้ที่คุณกำลังส่งต่อไปยังมุมมองบางส่วนของคุณ


2
ฉันกำลังพยายามทำสิ่งนี้และกำลังส่งคืน "ไม่สามารถแปลงเป็นโมฆะเป็นวัตถุ" ได้
โปรแกรม

4
@programad ลองลบ @ จาก @ Html.RenderPartial () นี่เป็นการแก้ไขปัญหาที่ฉัน แต่ฉันเรียก RenderPartial () ในบรรทัดภายในบล็อครหัส @ {}
danjarvis

5
ฉันแนะนำให้ตรวจสอบคำตอบของ ctorx ด้านล่าง เขาเพิ่มข้อมูลเพิ่มเติมไปยัง ViewData ที่มีอยู่
raRaRa

162

หากต้องการขยายสิ่งที่ womp โพสต์คุณสามารถส่งมุมมองข้อมูลใหม่ขณะที่ยังคงรักษาข้อมูลมุมมองที่มีอยู่หากคุณใช้ Constructor Overload ของสิ่งที่ViewDataDictionaryชอบ:

Html.RenderPartial(
      "ProductImageForm", 
       image, 
       new ViewDataDictionary(this.ViewData) { { "index", index } }
); 

3
สิ่งนี้จะมีประโยชน์มากหากคุณจำเป็นต้องเก็บไว้TemplateInfo.HtmlFieldPrefixในการควบคุมลูกซึ่งจะถูกรีเซ็ตเป็นอย่างอื่น
Simon_Weaver

12
นี่เป็นทางออกที่ดีกว่า การสูญเสีย ViewData หมายความว่าคุณสูญเสีย ModelState และการตรวจสอบทั้งหมด +1
Kevin Farrugia

ดูเหมือนว่าจะใช้งานได้เฉพาะในกรณีที่คุณไม่ผ่าน TemplateInfo.HtmlFieldPrefix ใน ViewDataDictionary ของคุณ ฉันสามารถส่งผ่านตัวแปรตามที่แสดงในคำตอบเท่านั้นหรือส่งผ่าน TemplateInfo.HtmlFieldPrefix แต่ไม่ใช่ทั้งสองอย่าง
Ferox

45
@Html.Partial("_Header", new ViewDataDictionary { { "HeaderName", "User Management" }, { "TitleName", "List Of Users" } })
or
@{Html.RenderPartial("_Header", new ViewDataDictionary { { "HeaderName", "User Management" }, { "TitleName", "List Of Users" } });}

หน้าบางส่วน (_Header):

<div class="row titleBlock">
    <h1>@ViewData["HeaderName"].ToString()</h1>
    <h5>@ViewData["TitleName"].ToString()</h5>
</div>

2
ดูเหมือนว่าคำตอบที่สมบูรณ์ที่สุด (แม้ว่า. ToString () นั้นไม่จำเป็น)
โคลิน

9

ฉันคิดว่ามันจะไม่ทำงานเหรอ?

ViewData["currentIndex"] = index;

6
แม้ว่านี่จะไม่ใช่วิธีที่แข็งแกร่งในการทำ แต่ก็ช่วยให้ฉันทราบวิธีเรียกคืนค่ามุมมองข้อมูลจากคำตอบของ Womp
Mathias Lykkegaard Lorenzen

6

สร้างคลาสอื่นซึ่งมีคลาสที่คุณพิมพ์มาก

เพิ่มสิ่งใหม่ของคุณในชั้นเรียนและส่งคืนในมุมมอง

จากนั้นในมุมมองให้แน่ใจว่าคุณสืบทอดคลาสใหม่ของคุณและเปลี่ยนบิตของรหัสที่จะเกิดข้อผิดพลาด คือการอ้างอิงไปยังเขตข้อมูลของคุณ

หวังว่านี่จะช่วยได้ ถ้าไม่เช่นนั้นแจ้งให้เราทราบและฉันจะโพสต์รหัสเฉพาะ


4

วิธีที่ง่ายที่สุดในการส่งข้อมูลเพิ่มเติมคือการเพิ่มข้อมูลลงใน ViewData ที่มีอยู่สำหรับมุมมองเป็นบันทึก @Joel Martinez อย่างไรก็ตามหากคุณไม่ต้องการที่จะสร้างมลภาวะให้กับ ViewData ของคุณ RenderPartial มีวิธีการที่ใช้อาร์กิวเมนต์สามตัวเช่นเดียวกับรุ่นสองอาร์กิวเมนต์ที่คุณแสดง อาร์กิวเมนต์ที่สามคือ ViewDataDictionary คุณสามารถสร้าง ViewDataDictionary แยกต่างหากสำหรับส่วนของคุณที่มีเพียงข้อมูลพิเศษที่คุณต้องการส่งผ่าน


1

สิ่งนี้ควรใช้งานได้

this.ViewData.Add("index", index);

Html.RenderPartial(
      "ProductImageForm", 
       image, 
       this.ViewData
); 

ขอบคุณ! สิ่งนี้มีประโยชน์จริง ๆ เมื่อคุณขยายพจนานุกรม ViewData สำหรับเด็กเล็ก ฯลฯ
developius

1

ฉันรู้ว่านี่เป็นโพสต์เก่า แต่ฉันเจอเมื่อต้องเผชิญกับปัญหาที่คล้ายกันโดยใช้ core 3.0 หวังว่าจะช่วยใครบางคน

@{
Layout = null;
ViewData["SampleString"] = "some string need in the partial";
}

<partial name="_Partial" for="PartialViewModel" view-data="ViewData" />

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.