שאלות מראיונות עבודה: אנגולר
פוסט זה כולל טיפ קצר בנושא פיתוח Front End. אם אתם רוצים ללמוד יותר לעומק על פיתוח Front End מהבסיס ועד הנושאים המתקדמים תשמחו לשמוע שבניתי קורס וידאו מקיף בנושא זה הכולל מעל 50 שיעורי וידאו והמון תרגול מעשי.
למידע נוסף והצטרפות לקורס בקרו בדף קורס Front End באתר.
הבעייה עם ספריות תשתית שעושות יותר מדי היא שמהר מאוד אנו נתחיל לפתח ציפיות ונשכח שמדובר בסך הכל בקוד, ובדיוק אז נתקל במגבלות הטבעיות של הספריה. כך גם אנגולר כפי שנראה בשאלה הבאה.
1. השאלה
מה השגיאה שתקבלו בעת הפעלת הקוד הבא? מה גורם לה וכיצד כדאי לתקן?
<div ng-app="myApp" class="container">
<div ng-controller="mainCtrl as vm">
<ul>
<li ng-repeat="user in vm.slice(4) track by $index">{{user.name}}</li>
</ul>
</div>
</div>
var app = angular.module('myApp', []);
app.controller('mainCtrl', MainCtrl);
function MainCtrl() {
var vm = this;
vm.users = ['martin', 'jane', 'bill', 'barbara', 'tim', 'layla', 'martha', 'harry'];
vm.slice = function(n) {
return vm.users.slice(0,n).map(function(name) { return { name: name } });
};
}
2. תיאור הבעיה
הקוד עובד ומציג רשימה של 4 שמות מתוך המערך. יחד עם זאת הוא גם בקונסול את הודעת השגיאה Infinite $digest Loop. הגורם לשגיאה הוא פשוט קסום: אנגולר יפעיל את הפונקציה slice כדי לייצר את הרשימה ולאחר מכן יפעיל אותה שוב בלולאה עד ש״הערך יתייצב״. הרעיון הוא שפונקציה זו יכולה להביא לשינוי במשתנים מסוימים או מקומות אחרים שידרשו שערוך מחדש ולכן זיהוי השינויים ב Scope מתבצע בלולאה.
אבל רגע הרי הפונקציה slice מחזירה מערך עם אותם הערכים כל פעם— למה שתהיה כאן בעיה? בכל הפעלה לכאורה אנו מקבלים מערך עם שמות ארבעת האנשים הראשונים.
התשובה היא שאנגולר אכן מסתכל על הערכים במערך אך במקרה שלנו אלו לא אותם ערכים בשתי הפעלות עוקבות, מאחר ובכל הפעלה הפוקנציה מייצרת אובייקטים חדשים בתוך המערך (שימו לב שאין בעיה להחזיר מערך חדש עם אותם האובייקטים, לכן slice לבד לא תגרום לבעיה).
פונקציה שמחזירה מערך ונקראת מתוך ה Digest Loop חייבת להחזיר בשתי הפעלות עוקבות מערך עם אותם הערכים בדיוק (אם אכן שום דבר לא השתנה).
3. רעיונות לפתרון
אחרי שמבינים את הבעיה אפשר לדבר על הפתרון, ולמעשה זה החלק הקל. כך למשל אפשר להעביר את ה map מחוץ לפונקציית slice:
function MainCtrl() {
var vm = this;
vm.users = _.map(['martin', 'jane', 'bill', 'barbara', 'tim', 'layla', 'martha', 'harry'], function(name) { return { name: name }} );
vm.slice = function(n) {
return vm.users.slice(0,n);
};
}