למה כל כך קשה ללמוד אנגולר
פוסט זה כולל טיפ קצר בנושא פיתוח Front End. אם אתם רוצים ללמוד יותר לעומק על פיתוח Front End מהבסיס ועד הנושאים המתקדמים תשמחו לשמוע שבניתי קורס וידאו מקיף בנושא זה הכולל מעל 50 שיעורי וידאו והמון תרגול מעשי.
למידע נוסף והצטרפות לקורס בקרו בדף קורס Front End באתר.
מבין ספריות ה JavaScript לפיתוח יישומים מורכבים אנגולר נחשבת לפופולרית ביותר וגם לקשה ביותר ללמידה. יש שיטענו שהדברים קשורים, ושתמיד יהיה קשה ללמוד טכנולוגיה שמנסה לפתור בעיות גדולות. אני חושב אחרת. הנה רשימה של הסיבות האמיתיות שהופכות את אנגולר לקשה ללמידה, אף אחת מהן לא קשורה לבעיה אותה היא מנסה לפתור.
1. אנגולר לא עקבית
בספריה עקבית אנו כותבים דברים דומים ומצפים לקבל תוצאה דומה. אנגולר לעומת זאת מלאה מקרי קצה. קחו למשל את שתי הפונקציות הבאות:
function get_array() {
return [1, 2, 3];
}
function get_new_array() {
return [ {id: 1}, {id: 2}, {id: 3} ];
}
בפונקציה הראשונה תוכלו להשתמש בביטוי ng-repeat באופן הבא:
<li ng-repeat="n in vm.get_array()" ng-bind="n"></li>
אבל אם תחליפו בביטוי את הפונקציה לפונקציה השניה תקבלו שגיאה. יש כמובן סיבה למה אחת מצליחה ואחת לא, ועדיין אם ng-repeat רץ על מערך הדבר ההגיוני לעשות היה לעבוד בשתי הפונקציות או להכשל בשתיהן.
דוגמא נוספת היא הביטויים באנגולר. הקוד הבא עובד:
<button ng-click="vm.count = vm.count + 1">Click</button>
אך הקוד הבא נכשל (בלי לדווח שגיאה, פשוט לא עושה כלום):
<button ng-click="vm.count += 1">Click</button>
הבחירה להיות עקבי היא קשה, כי זה אומר שהקוד צריך לנקוט בגישת ״הכל או כלום״, וכנראה כוללת וויתור על יכולות שאי אפשר לממש אותן בצורה עקבית. מצד שני הרבה יותר קל לנו ללמוד ספריה עקבית.
2. אנגולר משתמשת במידע חצי-גלובלי
מידע גלובלי הוא מידע שמוגדר במקום אחד וכל שאר הקוד יכול להשתמש בו או לשנות אותו. מידע גלובלי יוצר צימוד נסתר בין קטעי קוד שונים במערכת. כל קטע קוד שמשתמש באותם המשתנים הגלובליים תלוי בכל הקטעים האחרים שמשתמשים בהם. כך שינוי במקום אחד יכול לשבור דברים שלכאורה לא קשורים.
אנגולר עושה הכל כדי שלא תגדירו משתנים גלובליים בקוד, אבל במקומות רבים הספריה מעודדת הגדרת משתנים שמתנהגים כמו גלובליים. ניקח את הדוגמא הבאה של ng-repeat:
<div ng-controller="main as vm">
<p ng-repeat="i in vm.items track by $index”>Demo: {{$index}}</p>
</div>
המשתנה $index מייצג את האינדקס הרץ של הלולאה, אך מהיכן הגיע? מי משנה את ערכו? ההנחיה ngRepeat מתחזקת שישה משתנים כאלו שאתם יכולים להשתמש בהם בתוך בלוק ההנחיה. השם המיוחד $index הוא המידע הגלובלי, שכן הוא יוצר צימוד נוסף בין ההנחיה ngRepeat לכל קוד שישתמש בה.
נשווה עם לולאה מקבילה של ריאקט:
{ items.map(function(item, index) {
return <p>Demo: {index}</p>;
})}
הכתיב בריאקט יותר עמוס בסימנים אבל יש לו ייתרון בולט: הקוד הקורא אחראי על בחירת שם הפרמטר ולא קוד פונקציית הלולאה.
ההתנהגות לא ייחודית ל ngRepeat. כל הנחיה באנגולר יכולה ליצור פרמטרים שיהיו זמינים לקוד הקורא, כולל הנחיות שאתם בונים בעצמכם. זהו הממשק שנבחר בין Directives לבין התבניות שמשתמשות בהן, ממשק שיוצר צימוד מיותר.
במערכת קלה ללמידה קוד מספר סיפור. אפשר להסתכל על קטע קוד גם אם עדיין לא מכירים את הספריה יותר מדי טוב ולהבין מה הוא עושה. באנגולר השימוש בשמות גלובליים הופך את הקוד לשביר עבור מי שלא מכיר שמות אלו.
3. אנגולר לא ממנפת ידע קיים
לפעמים צריך להמציא מחדש את הגלגל, למשל אם הגלגל הקיים שבור. במקרה של אנגולר הגישה היא להמציא מחדש את כל הגלגלים, מה שיכול להרגיז מתכנתי JavaScript מנוסים. הבעיה עם המצאת הגלגל של אנגולר שזה נעשה תוך התעלמות מפתרונות קיימים ועובדים.
מנגנון ניהול התלויות של אנגולר משתמש בממשק ייחודי, למרות שגם כשהתחיל הפיתוח מנגנונים דומים כבר היו קיימים (למשל AMD שהיה מוטמע בספריית Dojo). לימים שוחרר תקן ES6 של JavaScript שכבר כלל התיחסות לנושא התלויות והזרקתן. אנגולר 2 כבר עובר להשתמש במנגנון זה, שזה מצוין, אבל האם באמת אי אפשר היה להוסיף תמיכה באנגולר 1 למנגנוני ניהול תלויות נוספים? תמיכה כזו היתה מקלה את המעבר של מתכנתים לאנגולר 2, וגם מקלה את הכניסה של מתכנתים שכבר מכירים את הסטנדרט.
דוגמא נוספת היא ה Digest Loop: מנגנון זיהוי השינויים של אנגולר מחייב כתיבת קוד נוסף לאחר ביצוע שינויים במידע כדי שאנגולר יזהה את השינוי. כך במקום להשתמש ב XMLHttpRequest אנו צריכים ללמוד על $http, במקום להשתמש ב setTimeout עלינו ללמוד על $timeout ובמקום setInterval יש את $interval.
מינוף ידע קיים הוא דרך מעולה להקל על אנשים ללמוד את הספריה. אם הספריה מיישמת עקרונות שאני מכיר, עובדת לפי תקנים שאני מכיר או מאפשרת לי להשתמש בכלים שאני מכיר יהיה לי יותר קל ללמוד אותה ולהיות פרודוקטיבי. באנגולר עליכם לשכוח את כל מה שידעתם ולהתחיל ללמוד הכל מחדש.
4. אנגולר לא מספרת לכם כשאתם טועים
כשלומדים כלי חדש זה טבעי לטעות ולטעות הרבה. רובנו לא יושבים לקרוא בעיון את התיעוד ואז מגיעים לתכנת, אלא מנסים להבין את הרעיון דרך דוגמא או שתיים ואז מתחילים לכתוב. הטעויות שאנו עושים לאורך הדרך מלמדות אותנו מה מותר ומה אסור לעשות. כל זה בתנאי שמישהו זכר לספר לנו שהיתה טעות.
מקומות רבים באנגולר משתיקים טעויות ובכך מקשים על מתכנתים בתחילת דרכם. כך הקוד הבא שכולל שגיאת כתיב נכשל בלי לדווח שגיאה לקונסול:
<div ng-controller="main as vm">
<p ng-repet="i in vm.items track by $index">Demo: {{$index}}</p>
</div>
גישה למשתנים לא קיימים, ביצוע פעולות לא חוקיות או כל פעולה לא חוקית אחרת תכשל באופן שקט אם היא נכתבת בקוד התבנית. זה בסדר למי שמכיר, אבל הופך את תהליך הלמידה להרבה יותר מסורבל.
5. וקטנה לסיום
אנגולר קשה ללמידה. אני רואה בקורסים איך אנשים מרגישים שהם מבינים את העניין ושניה אחר כך מתעצבנים כשבתרגיל הבא דברים שציפו שיעבדו נכשלים בלי הודעה מסודרת.
ומה לגבי המערכת שאתם עובדים עליה? האם למתכנתים חדשים שמגיעים לצוות קל להוסיף קוד או שלוקח שבועות עד שמתחילים להתמצא? האם אתם יכולים לזהות את אותן התבניות שהופכות את אנגולר לקשה ללמידה גם בקוד שלכם?