למה בכלל צריך ספריות כמו אנגולר

פוסט זה כולל טיפ קצר בנושא פיתוח Front End. אם אתם רוצים ללמוד יותר לעומק על פיתוח Front End מהבסיס ועד הנושאים המתקדמים תשמחו לשמוע שבניתי קורס וידאו מקיף בנושא זה הכולל מעל 50 שיעורי וידאו והמון תרגול מעשי.
למידע נוסף והצטרפות לקורס בקרו בדף קורס Front End באתר.
 

לא פעם אני שומע מחברים געגועים ל jQuery, בייחוד כשמדובר באנשים שמתחילים לפתח באנגולר או ספריות מודרניות אחרות. געגועים זה ענין טבעי כמובן וכך גם קיטורים על אנגולר, אבל נראה לי הוגן לפני שמתעצבנים על תשתית, לנסות להבין איזה בעיות היא פותרת ולשפוט אותה מנקודת המבט הזו (כמה טוב אנגולר מצליחה לפתור את הבעיות הרלוונטיות עבורה), ולא כמה היא דומה או שונה לקוד הישן והטוב, שאגב ממש לא היה כל כך טוב.

כשבאים להבין ספריות Model/View ואת ההגיון שלהן, השאלה הראשונה שצריך לשאול קשורה בכלל ל״מצב״ היישום, כלומר למידע שהיישום מחזיק בכל רגע נתון וקובע מה יוצג בממשק. נתחיל עם jQuery ויישום לדוגמא שבודק האם כתובת המייל שלכם דלפה באחת מפריצות ההאקרים האחרונות.

1. חכם jQuery אומר: המידע של היישום נשמר ב DOM

נסו להכניס את המייל שלכם בתיבה למטה וללחוץ על הכפתור Check Email. היישום משתמש בשירות שנקרא haveibeenpwned כדי לגלות אם כתובת המייל שלכם דלפה לאחרונה, ואם כן הוא גם יספר לכם באיזה לוח מודעות היא נמצאה. בכל פעם שמזהים כתובת מייל אנו נרשום אותה גם ברשימת הכתובת שבדקנו (מתחת לטופס). כך משתמשים שיש להם כמה כתובות מייל יכולים לראות את הסטטוס של כל הכתובות מול העיניים:

 

הקוד עושה את העבודה ולדעתי גם מאוד פשוט להבין אותו (עברו לטאב JavaScript כדי לקרוא), אבל הוא די קרוב לנקודת השבירה. חשבו למשל על הדרישה הבאה: אין לשמור כתובת מייל יותר מפעם אחת ברשימת ההיסטוריה. דרישה הגיונית לגמרי שהרי ממילא מה שמעניין את המשתמש הוא התוצאה העדכנית ביותר לכתובת מייל מסוימת. 
מימוש אפשרי אחד יצטרך לשלוף מה DOM את כל אלמנטי ההיסטוריה ולבדוק מי מהם מתאים לכתובת המייל שעכשיו קיבלתי עליה תוצאה. הבדיקה עשויה להיראות כך:

var found = false;

$('.history li').each(function() {
  if ( $(this).html() === email ) {
    // found it: no need to add
    found = true;
  }
});

if ( ! found ) {
  // add item
}

אבל זה רעיון רע מאוד: קודם כל כי הקוד רץ בכל מקרה על כל רשימת האלמנטים (גם אם כתובת האימייל נמצאה כבר בהתחלה) וגם ובעיקר כי רשימה של מיילים ייחודיים הרבה יותר הגיוני לשמור כאובייקט, ואז הבדיקה תוכל פשוט להיות:

if ( ! history[email] ) {
  // add item
}

2. חכם אנגולר אומר: שמרו את המידע כמידע ואת הממשק כממשק

וכאן מגיע הרעיון של ספריות Model/View ואנגולר ביניהן. אם אתם הולכים לשמור היסטוריה כמשתנה אתם תצטרכו הרי דרך להפוך את המשתנה הזה לרשימת אלמנטים בממשק המשתמש. תרצו אולי להוסיף לוגיקה בכל פעם שלוחצים על פריט מהרשימה או להוסיף קלאסים מסוימים לפריטים (למשל קלאס danger עבור פריט המייצג כתובת אימייל שדלפה).

המטרה של ספריות Model/View היא לייצר מנגנון בו המידע נשמר כמשתנים ומבני נתונים באופן היעיל ביותר עבור ניהולו, והתשתית ״הופכת״ את המידע לאלמנטים ב DOM כך שכל שינוי במידע ישתקף אוטומטית באלמנטים אלו.

יישום אנגולר מקביל יכלול למשל את הלולאה הבאה להצגת ההיסטוריה, כחלק משכבת התצוגה ובתוך קוד ה HTML:

<ul class="list-group col-xs-12">
    <li ng-repeat="(email,state) in vm.emails" ng-bind="email" ng-class="vm.cls(state)"></li>
</ul>

הרי ממילא יש לנו אובייקט history המחזיק את כל רשימות המייל שנבדקו, ולכן כל האתגר הוא להמיר אובייקט זה לאלמנטים ב DOM, ולשמור על הסינכרון כך שברגע שמתקבל מייל נוסף להיסטוריה מיד נעדכן את הממשק. 

כך נראה יישום האנגולר המלא לאותו התרגיל:

הרעיון של הפרדת מצב היישום מהממשק הוא רעיון די טוב והוא פופולרי היום כי הממשקים מורכבים בהרבה ממה שהיו פעם, זמני התגובה של אתרים מהירים בהרבה מהעבר ומצב היישום כולל הרבה יותר מידע מאשר בעבר. תשתיות שעוזרות לנו להפריד את המידע מהממשק הן כורח המציאות. כל זה כמובן לא בא להמליץ ספציפית על אנגולר כתשתית כזו. אנגולר מקולקלת בהרבה מאוד מקומות וככל הנראה תסבך אתכם בהמשך הדרך. אבל זה כן בא להמליץ לכם לבדוק פתרונות ניהול מצב אחרים ליישום לפני שאתם רצים חזרה ל jQuery.