Question from Tapuz .Net forum: Control Extenders in Microsoft AJAX Control toolkit with PagingBulletedList
שאלה:
אני צריך להציג מידע ברשימה ממויינת אפלבתית.
בשביל זה בחרתי לעבוד עם PagingBulltedList של AJAX Control Toolkit.
איך אפשר לגרום לרשימה להציג את הסימן "#" שעל פיו יסנן את כל המספרים?
איך אפשר לקבל הודעה שהמשתמש בוחר אינדקס מסויים ולדעת איזה אינדקס נבחר?
להדגמה חיה ניתן ללחוץ כאן - http://ajax.asp.net/ajaxtoolkit/PagingBulletedList/PagingBulletedList.aspx.
תשובה:
השאלה הזו נוגעת לבדיוק כיצד ראוי לעבוד עם AJAX Control Toolkit כאשר צריך להרחיב אותו ולשנות את ההתנהגות הקיימת.
בואו נתחיל בלהכיר את ה-PagingBulletedList.
מדובר ב-AJAX Control Extender, כלומר זה פקד שמתלבש על פקד קיים.
במקרה שלנו ה-PagingBulletedList מתלבש על <asp:BulletedList> שזה פקד של ASP.Net 2.0 שמתרנדר לרשימה של <ul> ו-<li> ב-HTML. למשל, הפקד הבא:
<asp:BulletedList ID="BulletedList1" runat="server" DisplayMode="Text">
<asp:ListItem>writeln</asp:ListItem>
<asp:ListItem>1566</asp:ListItem>
<asp:ListItem>4556</asp:ListItem>
<asp:ListItem>9556776</asp:ListItem>
<asp:ListItem>12234</asp:ListItem>
<asp:ListItem>1566</asp:ListItem>
<asp:ListItem>abort</asp:ListItem>
<asp:ListItem>add</asp:ListItem>
<asp:ListItem>addBehavior</asp:ListItem>
<asp:ListItem>AddChannel</asp:ListItem>
<asp:ListItem>AddDesktopComponent</asp:ListItem>
<asp:ListItem>addElement</asp:ListItem>
<asp:ListItem>AddFavorite</asp:ListItem>
<asp:ListItem>addImport</asp:ListItem>
<asp:ListItem>addPageRule</asp:ListItem>
<asp:ListItem>addReadRequest</asp:ListItem>
<asp:ListItem>addRule</asp:ListItem>
<asp:ListItem>AddSearchProvider</asp:ListItem>
<asp:ListItem>alert</asp:ListItem>
<asp:ListItem>appendChild</asp:ListItem>
<asp:ListItem>appendData</asp:ListItem>
<asp:ListItem>applyElement</asp:ListItem>
<asp:ListItem>assign</asp:ListItem>
<asp:ListItem>attachEvent</asp:ListItem>
<asp:ListItem>AutoCompleteSaveForm</asp:ListItem>
...
</asp:BulletedList>
יתרנדר לתצוגה הזו בצד לקוח בדפדפן:
עכשיו נרצה איכשהו למיין את הרשימה הקיימת הזו שלנו, שרק לפי האות הראשונה (או X אותיות ראשונות) נציג אותן ביחד.
כלומר, נוכל לראות ביחד רק את כל המילים שמתחילות ב-a, או כל המילים שמתחילות ב-b וכך הלאה.
בשביל מטרה זו יש את PagingBulltedList של AJAX Control Toolkit ש"מתלבש" על BulltedList רגיל ומאפשר דפדפוף בו לפי אינדקס.
למשל הפקד הבא:
יגרום ל-BulltedList להיות מוצגת בצד לקוח כך: (לאחר שנלחץ על E)
לחיצה על האות O למשל תגרום לסינון חדש:
להדגמה חיה ניתן ללחוץ כאן - http://ajax.asp.net/ajaxtoolkit/PagingBulletedList/PagingBulletedList.aspx.
השאלה שואלת שתי שאלות. הראשונה, כיצד ניתן לקבל התראה מהפקד הזה כאשר המשתמש שינה את הסינון של הרשימה.
חשוב להבין שה-AJAX Control toolkit זה לא סתם עוד אוסף של ג'אווה סקריפטים.
מדובר במחלקות ופקדים צד-לקוח שכתובים בג'וואה סקריפט, אבל הם עדיין פקדים ומחלקות.
הפקדים האלו חושפים אירועים (Events), חושפים מאפיינים (Properties), חושפים קונסטרקטור (Constructor), חושפים מתודות (Methods) וכך הלאה.
רק במקרה זה כתוב בג'אווה סקריפט וכפוף למודל הכתיבה של Microsoft AJAX.
בואו נביט לתוך הקוד מקור של PagingBulltedList ונראה את זה.
נוריד מ-codeplex (אתר הפרוייקטים של מיקרוסופט) את הקוד העדכני - http://www.codeplex.com/AtlasControlToolkit/Release/ProjectReleases.aspx?ReleaseId=4923.
ובתוך התיקייה \AjaxControlToolkit\PagingBulletedList נוכל למצוא את קוד המקור מאחורי PagingBulletedList.
מאפיינים אמרנו שיש? בואו נראה אחד.
תזכרו, כל זה Javascript.
אפשר לראות שיש שדה פנימי heightValue_, ויש שני מתודות שחושפות Getter ו-Setter למאפיין.
get_Height מחזיר את הגובה הנוכחי של האלמנט, ו-set_Height מעדכן את השדה הפנימי ודואג לשנות את הגובה בפועל של האלמנט.
אמרנו שיש קונסטרקטור?
אמרנו שיש אירועים?
יש כאן מתודה אחת שמאפשרת לרשום פונקציות ג'אווה סקריפט לשינוי של אינדקס בפקד, מתודה אחת שמאפשרת להוריד הרשמה מאותה מתודה ומתודה אחת שמאפשרת לעלות את האירוע.
בדיוק כמו בכתיבה בקוד דוט נט!
עכשיו נראה איך מתממשקים למשל לאירוע של שינוי אינדקס.
בדף לדוגמה שמגיע עם Control Toolkit אפשר לראות את הקוד ג'אווה סקריפט:
זה הסינטקס להשיג את המופע צד לקוח של ה-PagingBulltedList שלנו לפי ID.
עכשיו נרצה לקבוע ולהדפיס למסך את הגובה של ה-Extender:
על המסך נראה:
כלומר, קבענו את גובה הפקד ל-250 ואז הדפסנו את הגובה על המסך.
כל זה באמצעות מאפיינים של ג'אווה סקריפט.
עכשיו נירשם לאירוע שמדבר על שינוי אינדקס בלקוח.
אמרנו איזה פונקציה צד לקוח נרצה שתרוץ שהגולש בדף בוחר אינדקס ונדפיס את הפרטים של האלמנט שנלחץ.
קיבלנו שלחצנו על האות B באינדקס במקום 4 (היות ואנחנו סופרים מערך מ-0 אז B באמת נמצא במקום 4).
השאלה השנייה שקיבלנו היא איך ניתן לשנות את הסידור של ה-PagingBulltedList כך שיציג את הסימן "#" לכל קבוצת המספרים.
נפתח את קובץ הג'אווה סקריפט של PagingBulletedList ואחרי קריאה זריזה שלו נוכל למצוא שבאמצעות הוספה של השורה הבאה בשורה 258 בתוך המתודה _generateIndexAndTabForView נוכל לבצע את זה.
סה"כ במתודה הזה מתבצעת החלוקה לקבוצות של האלמנטים שלנו, אז הוספנו תנאי קצר שבודק אם האלמנט הוא מספר ואם כן דואג שהוא יהיה תחת "#".
עכשיו השאלה היא איך נוסיף את השינוי הזה לפרוייקט שלנו.
אפשרות אחת היא לשנות את קובץ ה-JS של PagingBulletedListBehavior.js, לקמפל מחדש את Microsoft AJAX Control Toolkit ולהשתמש ב-DLL החדש שלנו.
אפשרות נוספת שהייתי רוצה להדגים היא שינוי בזמן ריצה של המתודה.
שימו לב מה עשינו כאן - לקחנו פונקציה פנימית של המחלקה בג'אווה סקריפט, ובזמן ריצה שנינו אותה כך שתעשה מה שנרצה.
bl._generateIndexAndTabForView זה שם של פונקציה, ולתוכה ביצענו השמה של פונקציה.
שנינו בזמן ריצה אצל את הלקוח את הפונקציה!
נראה את התוצאה של הקוד הזה:
ובאמת בצד-לקוח קיבלנו קבוצה שמבוססת על הסימן # שמייצג את כל המספרים!
מתי נשנה בזמן ריצה ומתי נדאג לקמפל מחדש את ה-AJAX Control toolkit?
נתחיל בלדבר נגד שינוי בזמן ריצה של ה-AJAx Control Toolkit:
1. שינוי בזמן ריצה יוצר מצב שלא יודעים איזה קוד מריץ מה. כלומר, לא יודעים בכלל מול איזה מתודה רצים באותו רגע.
2. שינוי בזמן ריצה יוצר ערבוב של אחריות בין הפקד צד-לקוח לבין המחלקה שמשתמשת בה שבפועל קובעת מה המחלקה מריצה.
3. מדובר על דרך גרועה לבצע שינויים מאסיביים ב-toolkit.
4. היות ושנינו מתודה פרטית (אנו יודעים זאת כי המתודה ששנינו מתחילה עם קו תחתון _) יכול להיות שבגירסה הבאה היא בכלל לא תהיה קיימת והשינוי שלנו לא יעבוד אם נרצה לשדרג לגירסה הבאה של AJAX Control toolkit.
עכשיו נדבר בעד שינוי בזמן ריצה של ה-AJAX control toolkit:
1. זה ממש מגניב. שנינו בזמן ריצה מתודה של מחלקה.
2. אם נשנה ישירות את הקובץ JS של ה-toolkit, נקמפל מחדש ונעבוד מול גירסה שלנו של ה-AJAX Control Toolkit כל שדרוג גירסה ל-AJAX Control Toolkit (שבערך פעם בחודש מתווספים לו פקדים) יגרור סט מאוד רציני של בדיקות ושינויים אצלנו. יש טכניקות שמאפשרות להתגבר על זה (לבצע Merge של הקבצים בגירסה הפרטית שלנו לתוך הגירסה הציבורית, אבל מדובר בתהליך ידני שיכול לקחת מספר שעות כל פעם).
קישור: http://www.tapuz.co.il/tapuzforum/main/Viewmsg.asp?forum=831&msgid=102202495