RSS

Two directives of the same name

16 מרץ

באחד הימים שעברתי על הקוד של Angular ראיתי דבר מוזר, ng-include ו- ng-view כל אחד מהם הוא למעשה שני directives. במילים פשוטות יש שני directives בשם ng-include ואותו דבר גם לגבי ng-view. ראו קוד של ng-view לדגומא. למה? מה קורה כאן? אני אנסה להסביר את הסיבה בפוסט זה.

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

 

1.    שאלה ראשונה: מה משותף לשני ה-directives?

תשובה: שניהם רוצים להחליף את כל ה- element כאשר משתנה ה-url או ה-view. כאשר רוצים להחליף את כל ה- element וה- scope משתמשים בפונקציה $transclude
ובהגדרה transclude: 'element'. להל"ן פסדו קוד התחלתי:

app.directive('myInclude', function ($animate) {

  return {

   transclude: 'element',

   link: function (scope, element, attrs, ctrl, $transclude) {

                       

        // clone the element.

        $transclude(scope, function (clone) {

               $animate.enter(clone, element, element);

        });

    }

  };

});

 

הסברים:

1.     transclude: 'element' מגדיר את כל ה- element ולא רק את הילדים שלו. אם מוציאים את כל ה- element, צריך סימון לאן לחזור ! לכן Angular שם במקום האלמנט הערה. אלמנט הערה זה האלמנט שנקבל בפונקצית ה-link. לדגומא : <– ngView:  !>

2.     פונקצית ה- $transclude מיצרת העתקה של האלמנט עם ה-scope הרצוי, ב- ng-view וב- ng-include ברירת המחדל היא ליצר scope בן.

3.     השרות $animate.enter מכניס את האלמנט המועתק after ה- element. ראו פוסט קודם שלי.


 

2.    שאלת השאלות !!! למה צריך שני directives לאותו directive?

שגיליתי איך Angular מימש את ng-include שאלתי את עצמאי למה הם לא מכניסים לאלמנט את התוכן החדש ואז מקמפלים אותו אם ה- scope הרצוי? (דוגמא בהמשך) למה הם צריכים שני directives?

תשובה:

<div directive1 directive2>

       Hello World…

</div>

אם directive1  מוגדר כמו בסעיף 1, אז אנחנו רוצים ש- directive2 יפעל רק לאחר הפעלת הפונקציה $transclude של directive1, כלומר סדר הפעולות המתבקש של הפעלת ה- link:

1.     שיכפול ה-div ו-scope חדש.

2.     הפעלת ה- directive1 (השני באותו שם), תפקידו לקמפל את התוכן החדש. ראו דוגמא את ngIncludeFillContentDirective.

3.     הפעלת directive2 על האלמנט החדש עם הבנים החדשים.

כדי להשיג את הסדר הזה אנחנו צריכים להגדיר את ה- priority בהתאם:

1.     directive1 למשל 400, כך זה מוגדר ב-ng-include ו- ng-view.

2.     directive2 למשל 0 או כל מספר שקטן מ-400.

3.     directive1 (השני באותו שם) ב- 400-.

 

3. למה directive1 קטן מ- directive2 ומתבצע לפני?

כמו שהסברתי בפוסט על $compile, סדר הפעולות הוא: ( דומה לצורת "V" )

1.    directive 2 preLink

2.    directive 1 preLink

3.    directive 1 postLink (להזכירכם ש-postLink זה link ).

4.    directive 2 postLink


 

4. אז למה אי היה אפשר לכתוב את זה אחרת? למשל:

$transclude(scope, function (clone) {

     clone.html('<b>I am a Template 1 + 3 = {{1+3}}</b>');

     $compile(clone.contents())(scope);

     $animate.enter(clone, elm, elm);

 });
 

הסבר קשה, לא בטוח 100% בתשובה אך אני מאמין שאני צודק J


אם נכתוב את זה כך למעשה שברנו את סדר הפעולות הטבעי של ה-
directives שמתנהג כמו V, כלמור בהתחלה preLink  העדיפות הגבוה ראשונה ובסוף postLink גם העדיפות הגבוהה, באמצע העדיפויות היותר נמוכות. מכאן שדוגמאת הקוד בסעיף 4 תריץ את directive1 ואחרי זה את directive2 וזה לא ההתנהגות הטבעית של directives שאמורה להיות כמו V.

 

סיכום:

 

1.     למדנו שאפשר לכתוב שני directives באותו שם. Angular משתמש בטכניקה זו ב- ng-include וב- ng-view.

2.     טכניקה זו מאפשרת לנו לשכפל את האלמנט, להכניס לתוכו תוכן ולקמפל את האלמנט. שיטה זו לא פוגעת ב-directives האחרים.

 

3.     ה- directive1 (השני באותו שם) מקבל את ה- Template שצריך לקמפל דרך ה-controller של ה-directive1 (הראשון( רואים את זה יפה ב-ng-include . כאן ההשמה וכאן הקימפול.

 

אשמח כמו תמיד לקבל פידבקים !!! J

 

נ.ב פתחתי פורום בנושא אנגולר כאן.

 

 

מודעות פרסומת
 
השארת תגובה

פורסם ע"י ב- מרץ 16, 2014 ב- AngularJS

 

להשאיר תגובה

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

הלוגו של WordPress.com

אתה מגיב באמצעות חשבון WordPress.com שלך. לצאת מהמערכת / לשנות )

תמונת Twitter

אתה מגיב באמצעות חשבון Twitter שלך. לצאת מהמערכת / לשנות )

תמונת Facebook

אתה מגיב באמצעות חשבון Facebook שלך. לצאת מהמערכת / לשנות )

תמונת גוגל פלוס

אתה מגיב באמצעות חשבון Google+ שלך. לצאת מהמערכת / לשנות )

מתחבר ל-%s

 
%d בלוגרים אהבו את זה: