August 06, 2006

Voodoo Child

שבו-נא ואספר לכם סיפור על כוסות רוח למתים וזריקות משכחי-כאבים לפגרים שיש שיכנו אותם CellRenderers.
במסגרת העבודה, הוטל עלי לפתח קומפוננטה אשר הייתה אמורה להשתמש ברינדור תאים ב-List מפני שזו הייתה הדרך הנכונה והפשוטה להשיג את התוצאה הרצויה. ישנם הרבה אזורים מפורזים בפלאש, ומכאן גם בפלקס, אך לדעתי אזור הדמדומים הגדול ביותר הוא ה- CellRenderer.
רק למען ההבהרה למי שעדיין לא חווה, ה-CellRenderer הוא למעשה קומפוננטה אשר אמורה לתפוס את המקום עבור תא רגיל ברשימה. לא רק זאת אלא בנוסף אמורה לרנדר את המידע של אותו התא בצורה שהדרישות קובעות, למשל: כל תא ברשימה יכיל chekbox וכדומה.
אין ספק שזהו כלי חזק מאד שנותן המון גמישות לקומפוננטה, ומכאן גם לאפליקציה בה היא מוצגת, אבל... בין זה ולבין לומר שהדבר הזה עובד יופי יופי... יש מרחק מרתון.
בואו נתחיל מהמתודה הכי חשובה של ה-CellRenderer, הלא היא setValue הידועה לשמצה. המתודה הזו נקראת בכל אינטרקציה עם התא. נפחת נפיחה ליד התא – בום! יש אינבוקציה. הזזת את הכוס קפה ליד המקלדת – יש אינבוקציה. עכשיו, במקום שגאוני אדובי יחלקו את האינטרקציה עם התא לחלקים מוגדרים כמו rollover, press וכיו"ב הם פשוט כתבו מתודה אחת – ואתה כבר תדאג שהכל יקרה בצורה נכונה, עם כל מיני Booleans שהופכים את הקוד שלך לחתיכת חריון-יונים של תלמיד חוג מחשבים, הקבצה ג'.
מעבר לכך – מתבצעים גם רינדורים לתאים שלא קיימים. כלומר, אם יש לך רק 4 תאים, אבל הרשימה נפרשת על יותר, פלקס ירנדר גם את השאר. אה... נכון... בבקשה לא לשכוח להתנות את הרינדור הגראפי ב"האם יש מידע לרנדר בכלל". כל כך יקר ולא יעיל.
אז הנה אני כבר יוצר לי את ה-CellRenderer שלי ונכנס, ראש-קדימה, אל הזוועתון שנקרא UIComponent Life cycle ובאותה נשימה – sizing. שהרי setValue ו-layoutChildren משחקים מחניים בניהם ומה שנוצר זה קקופוניה של callstack. כמו פרכוס של התא עד שהוא נרגע ואם אני פוקסיונר, אז גם המידע בו מוצג בצורה הנכונה.
פה בא לעזר-כנגדי פונקציות האינבלדיציה (זה נשמע כמו קפקאזית, נכון?... ). כל מתודות האינבלדציה האפשריות כמו invalidateLayout, invalidateSize, Invalidate הכל... הכל... פשוט עבודה בעיניים. ברמת העקרון – זה קורה. המתדות האלו באות לעדכן את הקומפוננטה אחרי פריים אחד, אבל לצערי בגלל המסירות של LayoutChildren והחברה שלו setValue – קול הענות החלושה נעלם בינות לדציבלים של הארכיטקטורה החיגרת הזו.
אחרי שהתא שלי נרגע, אחרי שדחפתי לו כמות מורפיום בינארי שיכולה לפיל שרתים, הגיעה השעה לבדוק את ה-sizing של כל הקומפוננטה. מה זה אומר? להתחיל לשחק איתה קצת, למתוח לכווץ... קצת להרוס.
מתיחה אחת וכל הקומפוננטה קיבלה צורה שיכולה לעלות על מגדל פעמון הקתדרלה בנוטרדאם ולצלצל. כאילו שום דבר לא מחזיק את התאים במקום, כל אחד מקבל מיקום ראנדומלי והכל נראה כמו מסיבת פול-מון בגואה.
"אז אתה יודע מה", אני אומר לעצמי בין קפה למאפה, "אולי אני בכלל אשתמש ב-dataGrid? הוא גם יכול להתאים תחת המצב הקשה".
עכשיו בואו... בואו בואו הטו אוזן – ל-List יש קטע שבא לעשות טוב, אבל מה, עושה רע. שנאמר כבר: הדרך לגיהנום רצופה בכוונות טובות. ומכיוון שגם אנחנו עוסקים ב-dataGrid אז אנחנו עוסקים עדיין ב... ניחשתם נכונה – List. הקטע המרתיח הוא שמפתחי הקומפוננטות של פלאש/פלקס החליטו שמרנדרים רק מה שרואים, שזה נשמע אחלא וזה נשמע גדול, לא? בטח – אבל איך עושים את זה? או! זו השאלה. והתשובה אף יותר מפתיעה... אם גללתי מטה, הרשומה העליונה עפה משם ונדחפת למקום האחרון למטה, וההפך, אם אני גולל מעלה הרשומה העליונה עפה ונדחפת למקום האחרון למעלה. ואתם יודעים מה כל ה"קווה-קווה-דה-לה-אומה" הזה עושה בסוף? במילה אחת? "בלאגן שילד היפראקטיבי בחדר מלא לגו לא עושה". אוקיי, ניסיתי מילה אחת – לא יצא.
והנה, אני גולל מעלה ומטה ורואה איך הרשומות שלי מתערבבות כמו קלפים בידיו של עזרא טיסונה... פשוט וודו קורם עור וגידים אל מול עיני הממשתהות, וכמו תגלית אני מבין שעכשיו אני הוא ה- Voodoo Child.
באמת שאני מנסה לקצר את הסיפור הזה, אבל ראבק – זה לא היה קצר. ובכל הפורומים והמקורות שחיפשתי תמיד נתקלתי באותה תשובה – "ככה זה".
המקרה החריף והחריף עד שאמרתי שאין דרך אחרת וחייבים לתת פה איזה workaround מבאיש. משהו עם גודל תא וגריד hardcoded, ובגלל שאז הheader של הגריד נגלל אף הוא, אז הנה header שלי שעומד איתן. בקיצור גועל נפש.
למה אני מספר לכם את זה? שתי סיבות: האחת היא שאני חייב לפרוק וחבל על המסכים בעבודה ובבית. והשנייה היא שאני מאמין שבמוקדם ומאוחר אתם תתקלו בזה (מי שמפתח, לא המוזרים שאוהבים לקרא את השטויות שלי סתם) ואז אתם תזכרו, ולפחות אני ארגיש כי לא עמלי לשווא.
שיהיה שבוע של כיף כיף, רגוע ושלו.

No comments: