AngularJS Deep Dive Course

הקורס מיועד לאנשים שעובדים תקופה באנגולר ורוצים לדעת איך עובד אנגולר ולא רק איך עובדים עם אנגולר.

AngularJS Deep Dive Course

 

HTML is great for declaring static documents, but it falters when we try to use it for declaring dynamic views in web-applications. AngularJS lets you extend HTML vocabulary for your application. The resulting environment is extraordinarily expressive, readable, and quick to develop.

 

AngularJS is a structural framework for dynamic web apps. It lets you use HTML as your template language and lets you extend HTML’s syntax to express your application’s components clearly and succinctly. Out of the box, it eliminates much of the code you currently write through data binding and dependency injection.

 

Module 1: AngularJS Bootstrap Process

This module gives a quick overview about Angular startup process.

 

clip_image001      Angular Init

clip_image001[1]      Angular Bootstrap

clip_image001[2]      Injector Service

clip_image001[3]      Module Loading process

clip_image001[4]      Lazy Module Loading

clip_image001[5]      $compile service

o   $parse

o   $interpolate

clip_image001[6]      $scope

Module 2: $provide Services Internals

 

clip_image001[7]      Provider Method

clip_image001[8]      Factory Method

clip_image001[9]      Service Method

clip_image001[10]      Value and Constant

clip_image001[11]      Decorator

Module 3: Directive Internals

clip_image001[12]      Directive Definition Object

clip_image001[13]      Directive Execution Order

clip_image001[14]      Compile method vs. Link method

clip_image001[15]      Compile method vs. $compile

clip_image001[16]      Communication between directive

clip_image001[17]      Directive Scope

o   $id

o   $watch and $watchCollection

o   $apply

clip_image001[18]      Directive animations support

clip_image001[19]      Custom Directive Samples:

o   How to build directive with no scope and Watch

o   Dynamic Template

o   Multi Transclusion

clip_image001[20]      Directive Performance tips

Module 4: Communication Services

 

clip_image001[21]      $http Service

o   Headers

o   Transforming Requests & Responses

o   Caching

o   Response Interceptors

clip_image001[22]      $cacheFactory

clip_image001[23]      Angular-Cache module

clip_image001[24]      $resource Service

clip_image001[25]      $q Service

Module 5: Routing and Navigation

 

clip_image001[26]      $location service

clip_image001[27]      ng-view directive

clip_image001[28]      $route service and route object

clip_image001[29]      Navigation flow

clip_image001[30]      Routing broadcasted events

clip_image001[31]      Resolve option and promise

clip_image001[32]      Cancelling route changes

 

Module 6: Forms in AngularJS

 

clip_image001[33]      ng-model binding

clip_image001[34]      ngModelController & ngFormController

o   Input states and css

o   Custom value formatting and parsing

o   Custom validation

o   Custom validation in ng-repeat

clip_image001[35]      Input directive

AngularJS $injector

אחד מאבני היסוד של AngularJS זה השרות $injector, הוא השרות הראשון שנוצר. כאשר AngularJS עולה הוא מיצר את $injector במתודה doBootstrap(), בתוך המתודה הוא קורא למתודה createInjector(modules) שהיא מיצרת את $injector. המתודה createInjector(modules) מגלה לנו איך עובד השרות וממה הוא מורכב. בציור אנחנו רואים את החלקים מהם מורכב $injector.

 

clip_image002

הסברים:

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 לעבוד איתם, ראו פתרון בפוסט הזה.

 

אשמח לקבל פידבק !!!

נ.ב מידע על קורסים בנושא אתם יכולים למצוא בפוסט הזה.

 

AngularJS $animate in Directive

אחת הטעויות הנפוצות בכתיבת directive היא לא להשתמש ב-$animate. אתם שואלים למה להשתמש בזה עם אתם לא חושבים על אנימציה? התשובה ש-$animate כל מה שהוא עושה זה:

1.     Enter  – להוסיף איבר ל-DOM

2.     Leave – להוריד איבר מ-DOM

3.     Move – להזיז איבר קיים ב-DOM למקום אחר, כלומר שיהיה לו אבא אחר.

4.     addClass ו- removeClass השם אומר הכל.

 

במילים פשוטות $animate מוגדר בקובץ angular.js ושם הוא רק עושה את הפעולות 1-4. כאשר מוסיפים את הקובץ angular-animate.js ומגדירים תלות במודול ngAnimate, המודול ngAnimate מבצע Decorator על $animate ומגדיר מחדש את הפעולות 1-4.

 

לדוגמא פעולת enter איך שהיא מוגדרת בקובץ angular.js:

 

function enter (element, parent, after, done) {

    if (after) {

        after.after(element);

    } else {

        if (!parent || !parent[0]) {

            parent = after.parent();

        }

        parent.append(element);

    }

    async(done);

}

 

מה שאנחנו רואים בקוד שמתודה enter עושה פעולה פשוטה של jQuery ( append() או after() תלוי בארגומנטים ) ולכן שאתם כותבים directive ואתם במתודה של ה-linkמבצעים את הפעולות האלו על element עדיף שתשתמשו $animate כך אם תרצו בעתיד תכלו לקבל תמיכה באנימציה. ( ממליץ בחום להסתכל בקוד של אנגולר על כל המתודות, leave, move, addClass ו- removeClass.

עכשיו נראה את ההגדרה החדשה של enter, כאשר מוסיפים את ngAnimate:

 

$provide.decorator(‘$animate’, function ($delegate,
$injector, $sniffer, $rootElement, $timeout, $rootScope, $document) {

 

    //…

 

    return {       

        enter: function (element, parent, after, doneCB) {

            this.enabled(false, element);

            $delegate.enter(element, parent, after);

            $rootScope.$$postDigest(function () {

                performAnimation(‘enter’, ‘ng-enter’, element, parent, after, noop, doneCB);

            });

        }

        // …

    };

});

הסברים:

1.     ngAnimate מבצע Decorator על השרות $animate ולכן ה-directives שלכם עכשיו מקבלים את $animate החדש. הסברים נוספים על Decorator אתם יכולים למצוא בפוסט הקודם שלי .

2.      delegate.enter(element, parent, after) מפעיל את $animate המקורי.

3.     המתודה performAnimation היא למעשה עושה את האנימציה. הסברים איך המתודה מבצעת את האנימציה בפוסט אחר.

 

סיכום:

עדיף להשתמש ב-$animate בפונקצית ה-link בכל מקום שאפשר במקום לעשות ישירות פעולות על ה-DOM כי כך אנחנו נקבל תמיכה באנימציה אם נרצה והדבר לא פוגע בביצועים.