אחד מאבני היסוד של AngularJS זה השרות $injector, הוא השרות הראשון שנוצר. כאשר AngularJS עולה הוא מיצר את $injector במתודה doBootstrap(), בתוך המתודה הוא קורא למתודה createInjector(modules) שהיא מיצרת את $injector. המתודה createInjector(modules) מגלה לנו איך עובד השרות וממה הוא מורכב. בציור אנחנו רואים את החלקים מהם מורכב $injector.
הסברים:
1. כאשר אנחנו רוצים לקבל שרות ע"י המתודה $injector.get(‘serviceName’) הוא בודק קודם כל האם הוא נמצא ב- Instance Cache אם הוא לא שם הוא קורה ל- providerInjector.get(servicename + providerSuffix). ה- providerInjector בודק אם האוביקט שמיצג את השרות ( האוביקט עם $get ) נמצא בזכרון providerCache אם לא נזרקת טעות. (אני מזכיר לכם את הפוסט על $provide שאחראי לרשום השרותים AngularJS.)
2. אחרי שנוצר ה-$injector (instanceInjector) טוענים את המודולים השונים ע"י המתודה loadModules(modulesToLoad). המשמעות לטעון Module היא להפעיל את כל הפנקציות שרשמתם למודול, לדוגמא : module.factory(‘name’, function(){}). כמו שכתבתי בפוסט $provide רוב המתודות במודול הם עטיפה למתודה provider. ראו קוד של module.
moduleInstance = {
// Private state
_invokeQueue: invokeQueue,
_runBlocks: runBlocks,
// Public Methods
requires: requires,
name: name,
provider: invokeLater('$provide', 'provider'),
factory: invokeLater('$provide', 'factory'),
service: invokeLater('$provide', 'service'),
value: invokeLater('$provide', 'value'),
constant: invokeLater('$provide', 'constant', 'unshift'),
animation: invokeLater('$animateProvider', 'register'),
filter: invokeLater('$filterProvider', 'register'),
controller: invokeLater('$controllerProvider', 'register'),
directive: invokeLater('$compileProvider', 'directive'),
config: invokeLater('$injector', 'invoke'),
run: function (block) { runBlocks.push(block);
return this;
}
};
מה שאנחנו מבינים מהקוד שחוץ מהשרות $provide יש עוד שרותים שיודעים לרשום מתודות כמו למשל $filterProvider, אך כולם בסוף מגיעים לרשום את השרות לתוך ProviderCache.
להל"ן טבלה איך רושם כל שרות שהוא לא $provide:
הקוד שכתוב בתוך ה- Provider |
Provider Type |
$provide.factory(key, factory) |
$animateProvider.register() |
$provide.factory(name + suffix, factory) |
$filterProvider.register() |
מנהל לבד את הרישום |
$controllerProvider.register() |
$provide.factory(name + Suffix, factory) |
$compileProvider.directive() |
עכשיו שאנחנו יודעים איך נוצר ה-$injector ואיך הוא בנוי נשאלת השאלה איך משתמשים בו? את זה אתם יכולים לקורא באתר של AngularJS בלינק הבא.
מסקנות:
1. רק אחרי שנוצר ה-$injector נטענים המודולים, כלומר יוצרים את האוביקט עם $get ומאכסנים אותו ב- providerCache.
2. כאשר ה-$injector צריך לשלוף שרות הוא מחפש ב- InstanceCache אם זה לא שם הוא לוקח את האוביקט מ- providerCacheמפעיל את המתודה של $get ואת התוצאה מכניס ל- InstanceCache. במילים פשוטות זה מתנהג כ- instantiated lazily.
3. אם בזמן ריצה נוסיף אוביקטים ל- providerCache( Lazy Loading ) לא תיהיה בעיה ל-$injector לעבוד איתם, ראו פתרון בפוסט הזה.
אשמח לקבל פידבק !!!
נ.ב מידע על קורסים בנושא אתם יכולים למצוא בפוסט הזה.
דוד
אוקטובר 2, 2014 at 4:38 am
מי שיש לו זמן/ סבלנות ויבין לעומק את מה שכתבת , רק ירוויח