מדריך ASP.NET MVC – תצוגת עריכה
בפרקים הקודמים למדנו כיצד לייצר תצוגת פרטים ותצוגת יצירה. בפרק זה נלמד לייצר תצוגת עריכה. אנו ניווכח לדעת כי תהליך זה איננו שונה מהאופן שבו הגדרנו את התצוגות הקודמות.
להורדת הקוד של הפרק הקודם לחץ כאן
תחילה נוסיף לינק Edit לכל פריט בקבוצה המוצגת. לחיצה על לינק זה תפנה את המשתמש לתצוגת העריכה המתאימה.
פתח את הקובץ Views/Group/Index.cshtml. עדכן את הקוד באופן הבא:
...
foreach (BookItem item in this.Model.Items)
{
<div class="item">
<span class="actions">
@Html.ActionLink(
"Edit",
"Edit",
"Book",
new { id = item.ID },
null)
</span>
@item.Description
</div>
}
...
שים לב לשימוש שנעשה בפונקצית העזר ActionLink על מנת לייצר לינק לפעולת העריכה. הפונקציה מקבלת כפרמטרים את הטקסט שיופיע בתצוגה, את שם ה-Action וה-Controller שהלינק יפנה אליו וכן פרמטרים נוספים שישלחו ל-Action (דרך ה-URL).
בדוגמא שלנו הלינק מפנה ל-Controller בשם-Book ול-Action בשם-Edit בתוכו. בחן את המימוש של הפונקציה BookController.Edit. הפונקציה מחליטה על סמך ה-id שנמסר לה מיהו ה-Controller האמיתי שצריך לטפל בבקשה וזאת עפ"י סוג האובייקט.
הרץ את התוכנית:
מבט על ה-HTML בצד ה-Browser מלמד על הפלט של הפונקציה ActionLink:
<div class="item">
<span class="actions">
<a href="/Group/Edit/0">Edit</a>
</span>
Ori, Calvo
</div>
ניתן לראות כיצד הפרמטר "id = item.ID" בקוד שכתבנו מקבל ביטוי בתוך ה-href של התגית "a". לחיצה על הלינק בזמן ריצה תגרום לשגיאה שכן עדיין לא הגדרנו את ה-Action המתאים בצד השרת:
פתח את הקובץ Controller\GroupController.cs והוסף Action חדש בשם Edit:
[HttpGet]
public ActionResult Edit(int id)
{
AddressBookDB db = AddressBookDB.Create();
Group group = (Group)db.GetItemByID(id);
return View(group);
}
הפונקציה שולפת את האובייקט המתאים מתוך המודל ומחזירה את התצוגה עבורו.
צור View חדש מסוג "Edit" עבור ה-Action החדש
Visual Web Developer ייצור קובץ CSHTML חדש תחת המחיצה Views\Group\Edit.cshtml. הקוד המתקבל נראה כך:
@model AddressBook.Models.Group
@{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Group</legend>
<div class="editor-label">
@Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>
@Html.HiddenFor(model => model.ID)
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
בדומה לתצוגת יצירה שים לב לשימוש ב-
- BeginForm
- LabelFor
- EditorFor
פרטים על כל רכיב HTML המצוין מעלה ניתן למצוא בפרק "תצוגת יצירה".
הרץ את התוכנית ולחץ על הלינק "Edit". תצוגת העריכה נראית כך:
התצוגה נראית דומה לתצוגת היצירה שבנינו בפרקים קודמים. ההבדל המרכזי הוא בכך שתצוגה זו מפרטת את הערכים הנוכחיים של אובייקט המודל.
מחק את שם הקבוצה והשאר אותה ריקה. לחץ על הכפתור "Save". שים לב כיצד תהליך ה-Validation מופעל באותו אופן לתהליך ה-Validation עבור תצוגת היצירה:
הכנס שם מסוים לתוך תיבת הטקסט ונסה ללחוץ על כפתור ה-Save. מתקבלת שגיאה:
עלינו לממש את ה-Edit Action הפעם עבור פעולת POST בדומה למה שעשינו בתצוגת היצירה.
פתח את הקובץ Controllers\GroupController.cs והוסף את הקוד הבא:
[HttpPost]
public ActionResult Edit(int id, bool? dummy)
{
AddressBookDB db = AddressBookDB.Create();
Group group = (Group)db.GetItemByID(id);
if (!TryUpdateModel(group))
{
return View(group);
}
return RedirectToAction("Index", new { id = group.Parent.ID });
}
הרץ את התוכנית ובחן כיצד ניתן לשנות את השם של הקבוצה Friends:
כדאי לציין כמה נקודות חשובות בהקשר של הקוד מעלה:
כפי שניתן לראות בתמונה מעלה הפעולה “Edit” זמינה עבור קבוצות ואנשי קשר. במידה ותלחץ על “Edit” עבור איש הקשר “Ori, Calvo” תיתקל בשגיאה של “The view 'Edit' or its master was not found or no view engine". אנו נטפל במימוש החסר בהמשך. בשלב זה יש ללחוץ על “Edit” רק עבור קבוצות.
בדומה לטיפול ביצירה של קבוצה חדשה גם במקרה הנוכחי אנו משתמשים בשתי פונקציות. האחת למקרה של בקשה מסוג HTTP GET והשנייה למקרה של בקשה מסוג HTTP POST המטפלת בנתונים שנשלחים מה-Browser.
הניסיון לעדכן אובייקט קיים (להבדיל מיצירה) ניתקל בבעיה חדשה שלא התמודדנו איתה עד עכשיו. נניח כי היינו בוחרים להגדיר את הפונקציה Edit באופן ה"רגיל":
[HttpPost]
public ActionResult Edit(Group group) {…}
במקרה זה התשתית של ASP.NET MVC מייצרת אובייקט חדש מסוג Group. עדכון של אובייקט זה הינו חסר משמעות מאחר והאוביקט איננו כלל חלק מהמודל השלם שאנו מחזיקים בזיכרון. מאחר ואנחנו מעוניינים לעדכן אובייקט ספציפי הקיים במודל עלינו תחילה לשלוף אותו מהמודל ואז לעדכן ידנית את כל השדות הרלונטים. צורת עבודה זו מונעת מאיתנו "ליהנות" מתהליך ה-Model Binding האוטומטי של ASP.NET MVC.
כדי לא לממש את תהליך ה-Model Binding מחדש בחרנו לממש את הפונקציה Edit כך שהיא מקבלת רק פרמטר אחד מתוך הנתונים שנשלחים מה-Browser והוא הפרמטר: id. בעזרת פרמטר זה ניתן לשלוף את האובייקט מתוך המודל ובעזרת פונקצית העזר TryUpdateModel לעדכן את כל השדות של האובייקט. שים לב שעצם העובדה שאנחנו מקבלים רק פרמטר id לפונקצית ה-Edit לא משנה את העובדה שה-Browser שולח שדות נוספים והתשתית של ASP.NET MVC מודעת לשדות אלו ומשתמשת בהם כדי לעדכן את אובייקט המודל.
מבט יותר מדוקדק בקוד מגלה כי הפונקציה Edit מקבלת פרמטר נוסף בשם dummy. פרמטר זה, כפי ששמו מלמד איננו בשימוש בקוד שלנו ומטרתו היא “להרגיע” את הקומפיילר ולייצר Overloading תקין של שתי פונקציות ה-Edit. הפרמטר ה-dummy מוגדר כ-Nullable על מנת שתשתית ה-Model Binding תתייחס אליו כאל פרמטר אופציונאלי (שכן ה-Browser לא שולח אף פעם נתון זה).
בפרק זה למדנו כיצד ליצור תצוגת עריכה וכיצד לטפל בנתונים שנשלחים מה-Browser על מנת לעדכן את אובייקט המודל המתאים.
בפרק הבא אנו נעשה אתנחתא קלה מנושא הטיפול בנתונים ונשכלל את התצוגה של התוכנית על מנת לייצר ממשק משתמש מרשים יותר.
תגובות בפייסבוק