RSS

קטגוריה: AngularJS

Filter Performance Issue

בפעם הראשונה שקראתי על Filter של אנגולר חשבתי שזה אחד הדברים היפים שיש באנגולר, בעיקר בגלל הפשטות שלו.

בקוד הבא אנחנו רואים דוגמא קלאסית לכוח והפשטות של Filter באנגולר.

clip_image002

בדוגמאות קוד זו אנחנו רואים איך אפשר לכתוב ביטוי שלוקח את רשימת השמות ומכניס אותם לפונקציה OrderBy וארגומנט שני 'name' התוצאה נכנסת לפונקציה filter וארגומנט השני הוא הערך של שדה ה- search. הערך שמוחזר מהפונקציה filter הוא רשימת השמות שתכנסת ל- ng-repeat.

בנוסף אפשר גם לכתוב custom filter ולהשתמש בהם באותו אופן.

בעיות ביצועים עם Filters:

אנגולר מעדכן את המסך כל פעם שהוא מזהה שינוי על העץ של ה- scopes ע"י בדיקה של ה- watchers שמאוחסנים על ה- scopes. בדיקה זו מתבצעת כאשר קוראים למתודה $scope.$apply(), למשל שמשתמשים ב- ng-click, ng-model, $http. למעשה כל directive שמאזין לאירוע ( למשל UI , תקשורת ) מבצע בסוף הפעלה של פונקצית $apply. כל פעם ש- directive מפעיל את $apply עושים בדיקה לכל ה- watchers שקיימים על ה- scopes כלומר מפעילים גם את הביטוי:

names| orderBy:'name'| filter:search

גם אם הערכים של ה- search וה- names לא השתנו. יותר גרוע מזה, אם אחד ה- watchers מזהה שהיה שינוי חוזרים ובודקים את כל ה- watchers שוב, כלומר גם את הביטוי של ה- filters.

סיכום הבעיה:

אם האפליקציה שלנו מתעדכנת בתדירות גבוהה, כלומר הפונקציה $apply נקראת בתדירות גבוהה, אנחנו נסבול מהפעלה מרובה של הפונקציות filters גם במקרים שבטוח שהתוצאה לא תשתנה.

פתרון:

 להוציא את חישוב ה- filters מה- watchers, כלומר שהם לא יכתבו בתוך ה-HTML.

ראו קוד לדוגמא:

clip_image004

clip_image006

הסבר:

פונקציה calc רצה רק כאשר השדה ה- search או השדה names משתנה ולא כל פעם שמתבצעת פונקציה $apply.

 

סיכום:

השימוש ב- filters ב-HTML יצור watchers שרצים כל $apply וזה יכול ליצור לנו בעיית ביצועים, בעיקר אם התדירות של הפעלת הפונקציה $apply גבוהה וה- Filters השונים רצים על רשימות גדולות.

הפתרון לעביר את החישוב מ- HTML לקוד. הפעלת החישוב תתבצע רק כאשר שדה שיכול להשפיע על החישוב שונה.

 
תגובה אחת

פורסם ע"י ב- אוקטובר 22, 2015 ב- AngularJS, AngularJS Tips, ng-course.org

 

Upgrading the $controllerProvider

אחד הדברים המציקים לי באנגולר זה העבודה המסיבית סביב ה-this לדברים שלא אמורים להיות עליו.

כתבתי כמה טריקים איך לשפר את המצב (AngularJS Tip 5: AngularJS Arguments , AngularJS Tip 4: Dynamic Prototype Pattern ). למעשה הבעיה קיימת רק שמגדירים controller. כאשר עובדים עם factory אני כותב את הקוד בסגנון הבא:

var mi = angular.module('myApp', ['ngRoute'])            
.
factory('User'
, UserTypeFactory);

 

function UserTypeFactory($log,$http){
// constructor
function User
(name){
this.name
= name;
}

// methods
User.prototype.setName = function
(newName){
this.name
= newName;
};

return User;
}

 

עכשיו כל מי שרוצה לעבוד עם Class מסוג User רק צריך לבקש וה-$injector יתן לו אותו. שימו לב שאם אני רוצה לעשות ירושה אני יכול לבקש שיזריקו לפונקציה UserTypeFactory  את BaseUser ואז בתוך הפונקציה אני בונה את הירושה. המתודה UserTypeFactory רצה רק פעם אחת בלבד, כך אנגולר עובד.

אם אני מחזיר new User() בפונקציה UserTypeFactory במקום רק User קבלתי את האפקט של פונקציה service אך עם היתרון שהצלחתי ליצור private static משתנים ( הכוונה ל- $ log ו- $http ).

ומה עם Controllers?

כאן יש בעיה קשה כי ה- controllers מקבלים גם שרותים כמו $log ו- $http אך גם $scope. ה-$scope הוא לא singleton ואחרים כן. ( אישית אני חושב שזה תכנון רע מאוד מה שהצוות של אנגולר עשה כאן)

פתרון פשוט:

function UserCtrlFactory($scope,userBL,$log,$q){
   function UserCtrl
($scope) {
      this.id = $scope.$id
;
      this.name = userBL.name;       

   
}
   UserCtrl.
prototype.update = function
(name) {
     $log.
debug('update'
);
     name +=
'!'
;
     userBL.
update.call(this
, name);

    };
  angular.extend( UserCtrlFactory.
prototype
,
  UserCtrl.
prototype
);
  UserCtrl.
apply(this, arguments
);
}

 

צורת כתיבה זו מאפשרת לי לכתוב controller שבתוכו כתוב ה-controller כמחלקה. בנוסף הצלחתי להגדיר את $log ו- $http כ- private static ואילו ה- $scope יעבור ל-controller הפנימי דרך ה- constructor.

יש פה הרבה טריקים של JavaScript בשתי השורות האחרונות, אך כאן לא המקום להסביר אותם.

הפתרון הזה פשוט אך לא טוב לביצועים כי כל פעם שיוצרים את ה-controller (למשל מעבר בין דפים ) ה- controller הפנימי גם נוצר וכל הפונקציות שמוגדרות ב- prototype שלו. זה בדיוק אותה הבעיה שעובדים עם $scope ולכן מומלץ מאוד לא להגדיר מתודות על ה-$scope.

מכאן הגעתי להחלטה שאין ברירה או שכותבים ng-controller חדש שיטפל בבעיה או פתרון יותר תשתיתי זה לשדרג את $controllerProvider.

אחרי השדרוג אפשר לכתוב controller בצורה הבאה:

var mi = angular.module('myApp', ['ngRoute'])

                .controller('UserCtrl',UserCtrlFactory);

 

UserCtrlFactory.isFactory = true;
function UserCtrlFactory(userBL,$log,$q){
  function UserCtrl
($scope) {
    this.id = $scope.$id
;
    this.name = userBL.name;       

    }
  UserCtrl.
prototype.update = function
(name, address) {
    $log.
debug('update'
);
    name +=
'!'
;
    userBL.
update.call(this
, name);
  };
  return UserCtrl
;
}

 

הערות:

על מנת שאנגולר ידע שהפונקציה UserCtrlFactory היא מיצרת controller ולא ה- controller עצמו, אני מוסיף לה שדה isFactory עם ערך true.

התיקון שעשיתי בקוד של אנגולר זה להוסיף את השורות הבאות כאן.

// Start : Eyal Vardi
if(expression.isFactory){

  expression = $injector.invoke(expression);
 
controllers[constructor
] = expression; } // End : Eyal Vardi

הסבר:

כאשר אנגולר מוצא את שם ה- controller הוא מאחסן אותו במשתנה בשם expression. אני בודק אם זה באמת הקונטרולר או הפונקציה שעוטפת את הקונטרולר, אם זה מעטפת אני מריץ אותה ומאחסן את ה-controller האמיתי ב- expression וגם ב- controllers[constructor] כדי שפעם הבאה נקבל רק את הקונטרולר האמיתי ולא את העטיפה.

שיקולים בעד:

הכתיבה עכשיו של controllers הרבה יותר אלגנטית ויהיה קל יותר להפוך את הקוד ל- ES6 או לאנגולר 2.

שיקולים נגד:

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

 

מה אתם חושבים?

רוצים להכיר עוד טריקים מהסוג הזה, בואו ליום של Angular Hacking.

 

 

 

 
השארת תגובה

פורסם ע"י ב- ספטמבר 27, 2015 ב- AngularJS

 

Master Template in AngularJS

Master Template in AngularJS

 

אנגולר מאפשר לנו לכתוב תבניות מאוד חכמות, וע"י Directives אנחנו יכולים לארוז אותם לתוך תג. למשל בדוגמא של accordion ו- expander, התוצאה הסופית היא שזה מתורגם לHTML מאוד גדול ביחס לתבנית.

<accordion>

   <h1>Eyal – {{date}}</h1>

   <expander class='expander'

             ng-repeat='item in expanders'

             expander-title='{{item.title}}'>

        {{item.text}}

   </expander>

</accordion>

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

דוגמאות למצבים שאני חושב שגישה זו עושה הגיון.

דוגמא 1: Binding Once or Not

תבנית עם Binding Once שלפעמים אני רוצה לבטל את ה- Binding Once. למשל התבנית הבאה:

clip_image002כאשר אני מסתכל על רשימה של פריטים אני רוצה שהתבנית של המוצר תיהיה עם יכולות של Binding Once ואילו כשאני מסתכל על מוצר בודד אני רוצה שאותה תבנית תיהיה Two way Data-binding. כלומר ההבדל היחידי בין התבניות זה ה- "::" שצריך להוסיף לפני שם המשתנה כדי לקבל binding once {{expression::}}. זה מקרה קלאסי לבנות Master Template שיקבע עם יהיה לפני שם המשנה ה-"::" או לא ע"י פרמטר.

 

דוגמא 2: שפות

כאשר אנחנו רוצים תמיכה של שפות בתוך התבניות אפשר להשתמש ב- angular-translate. אבל אפשר גם להשתמש בפתרון של Master Template ואז אנגולר יעבוד פחות קשה וגם יהיה יותר קל להבין את התבניות.

מה משותף לשתי הדוגמאות האלו? שה-MT יכול להכין את התבניות ע"פ מידע שקיים בזמן "קימפול" ואנגולר עובד על התבניות שנוצרו בזמן ריצה. ראו שרטוט.

clip_image004

אם לא רוצים להכין מראש את התבניות ע"פ שפה, אפשר להעביר את ה-MT לצד השרת ואז להוסיף ל-URL ערך שמציין את השפה הרצויה. ( לדוגמא : http://evardi.com/product.html?lag=heb  ) פתרון לגישה זו פרסמתי בפוסט AngularJS Tips 1–Directive TemplateURL.

כאשר לא רוצים לערב את השרת, אפשר לעשות אותו דבר בצד של אנגולר.

השאלה שמתעוררת היא  באיזה טכנולוגיה נשתמש כדי ליצור את התבניות של אנגולר? אפשר handlebars למשל, אבל למה לא להשתמש בפתרון ש- EcmaScript 6.0 מביא לשולחן?

לדוגמא:

(function (angular) {
"use strict"
;
///////////// AngularJS Code ///////
var mi = angular.module('myApp'
, [])
.factory(
'lang'
,langFactory)
.directive(
'helloWorld'
,helloWorldDirective);

function langFactory(){
return
{
he:{ hello : "
שלום" },
en :{ hello : "hello"
}
};
}

function helloWorldDirective(lang,$log){
return
{
template :
function
($compileNode, templateAttrs){
var
template = `<div>
<b> ${lang.he.hello}<b> : {{
name}}

                  </div>`;
return template.toString();
}
};
}
})(
angular
);

 

הסברים:

כאשר אנגולר מקמפל קטע HTML והוא מזהה את הדיראקטיב hello-world הוא קורא ל-template. ואז נוצרת תבנית עם השפה הרצויה שאותה אנגולר מקמפל. הבעיה שאם הדיראקטיב נמצא מספר פעמים על הדף הפונקציה של template תקרא מספר פעמיים. לכן צריך להוסיף מנגנון של Chace. אם חושבים על זה פעם שניה אפשר בשלב ה-run לעבד את התבניות ולהכניס אותם ל- $templateChaceואז הדראקטייב לא צריך פונקציה מיוחדת ואפשר לחזור לעבוד עם templateUrl.

 

דוגמא:

(function (angular) {
    "use strict";
    ///////////// AngularJS Code ///////
    var mi = angular.module('myApp', [])
        .factory('lang',langFactory)
        .directive('helloWorld2',helloWorldDirective2)
        .run(function($templateCache,lang){
            var template = `<div>
            <b> ${lang.he.hello}<b> : {{name}}
            </div>`;
            $templateCache.put("helloworld.html",template.toString());
        });
    function langFactory(){
        return{
          he:{ hello : "שלום" },
          en :{ hello : "hello" }
        };
    }
    function helloWorldDirective2(lang,$log){
        return{
            templateUrl : "helloworld.html"
        };
    }
})(angular);
 
הסברים:
בשלב העלייה של אנגולר אנחנו בונים את התבניות ומכניסים להם את התרגומים. 
כמובן שאפשר להמשיך לשפר את המנגנון ולעבוד עם קבצים, לעבד אותם ואז להכניס אותם 
ל-$templateCache. אני אישית חושב שצריך לבצע את זה בצד השרת, הכי טוב מבחינת ביצועים.
 
דוגמא 3:
יש הרבה דיראקטייב שהם statics, כלומר הם מקבלים דרך ה- attributes ערכים קבועים כלומר 
אי אפשר לחבר את ה-attributes האלה ל-data binding ואז הם מוחלפים בתבנית. 
כלומר הערכים של ה- attributesנקבעים בזמן כתיבת ה-HTML.

למשל:
<image-button img="face.jpg" imgAlign="left">
    Hello World
</image-button>
 
הדיראקטייב הזה מיצר כפתור שבנוי מתמונה וטקסט ואפשר לקבוע עם התמונה תהייה באחד 
מהצדדים ימין, שמאל, למטה או למעלה. הדראקטייב הזה הואstatic  הוא נועד רק כדי לחסוך 
שורות קוד ב- HTML. 
 
דארקטייב כזה מאוד קל כאשר כותבים אותו באנגולר בצורה נאיבית. הבעיה שמהר מאוד י
וצרים scope ו- watchים, דברים אלו יוצרים בעיות ביצועים שלא לצורך.
 
פתרון:
 
function imageButtonDirective($log){
    return{
        template : function($compileNode, attrs){
            var template = `<div>
            <img src=${attrs.img} align=${attrs.imgalign}/>
            ${$compileNode.html()}
            </div>`;
            $log.debug(template.toString());
            return template.toString();
        }
    };
}
 
כאשר אנחנו בונים את התבנית ב- template אנחנו מקבלים מספר יתרונות:
1. שימוש בדראקטייב זה ב- ng-repeat הפונקציה ליצירת התבנית תופעל רק פעם אחת. שימו לב, 
אפשר לעשות את זה גם במתודה compile, אך יש בזה שתי חסרונות:
A.      אי אפשר להוסיף דראקטייב בשלב ה- compile בלי לקמפל שוב את התבנית עם $compile.
B.      קידוד תבניות הרבה יותר נוח בשיטה declarative מאשר בשיטה של imperative.
2. אפשר לעבוד עם Chace ע"פ הערכים שמקבלים ב- attributes ולכן מקבלים ביצועים טובים יותר.
3. גם במקרה הזה אפשר היה לעבד את המידע בצד השרת ואפילו להשתמש בתוכנה כמו grant כלומר 
לבצע את העיבוד בזמן ה- build.
 
סיכום:
החיים הם לא שחור או לבן, יש הרבה מאוד אפור...
במקרים מסוימים כאשר אפשר לעבד את ה-HTML בזמן ה-build עדיף לא להשתמש בטכנולוגית 
האנגולר כי נשלם על זה בביצועים שלא לצורך.
 
אשמח לקבל תגובות !!!
 
אם אהבתם את הפוסט ואתם רוצים להמשיך ולהעמיק בנושא, אשמח לראות אותם בקורס 
שלי על אנגולר למתקדמים.

 

 

 

 
2 תגובות

פורסם ע"י ב- פברואר 14, 2015 ב- AngularJS, AngularJS Tips

 

AngularJS Tip 3 – JavaScript Properties in AngularJS


אחת השאלות השכיחות ששואלים אותי, מה הדרך לחבר את
bl שלנו ל- Controller כך שיהיה לנו קל לחבר אותו ב- Binding ב- HTML (ng-model) ?

אפשרות 1:

function UserCtrl(userBL){
    this._bl = userBL;
    this.name    = userBL.name;
    this.address = userBL.address; // address is an object.

}

 

<div ng-controller="UserCtrl as vm">
    <input type="text" ng-model="vm.name" placeholder="name"><br>
    <input type="text" ng-model="vm.address.street" placeholder="street"><br>
    <input type="text" ng-model="vm.address.house" placeholder="house"><br>   
    <br>
    name : {{vm._bl.name}}<br>
    Address : {{vm._bl.address | json }}<br>
</div>

 

 

שפת ה-JavaScript תעתיק את name כ- Copy By Value, ולכן כאשר תעדכנו את הערך ע"י תג input לא יהיה קישור ל- userBL.name.  ב- address (אוביקט) ה-JS מעתיקה את ה-reference כ- Copy By Value ולכן הקישור נשמר.

שימו לב, אם בזמן ריצה יבצעו:

userBL.address = {strees:’abc’, house: 1};
 
נקבל ניתוק מה- this.address, הוא יצביע על האוביקט הישן.
 
אפשרות 2:
 
function UserCtrl(userBL){
    this._bl = userBL;
    Object.defineProperties(this,{
       name : {
           get : function(){
               return userBL.name;
           },
           set : function(value){
               userBL.name = value;
           }
       },
       address : {
           get : function(){
               return userBL.address;
           },
           set : function(value){
               userBL.address = value;
           }
       }
    });
}
 
באפשרות זו יצרתי properties ולכן ה- set’sעובדים על ה-userBL ישירות וכך לא נאבד את ה- binding.
אפשר להמשיך את הגישה הזו גם לקשר שבין ה- BLוה-DAL.
 
(function (angular) {
    ‘use strict’;
    //////////////// AngularJS //////////////
    var mi = angular.module(‘myApp’, [])
    .factory(‘userBL’,blFactory)
    .factory(‘userDTO’,dtoFactory)
    .controller(‘UserCtrl’,UserCtrl);
    //////////////// JavaScript //////////////
    function dtoFactory($log){
        return {
            name: ‘bl-name’,
            address: {
                street: ‘abc’,
                house: 47
            }
        };
    }
    function blFactory($log,userDTO){
        var blUser = Object.defineProperties({},{
            name : {
                get: function(){
                    return userDTO.name;
                },
                set : function(value){
                    userDTO.name = value;
                }
            },
            address : {
                get: function(){
                    return userDTO.address;
                },
                set : function(value){
                    userDTO.address = value;
                }
            }
        });      
        return blUser;
    }

    function UserCtrl(userBL){
        this._bl = userBL;
        Object.defineProperties(this,{
           name : {
               get : function(){
                   return userBL.name;
               },
               set : function(value){
                   userBL.name = value;
               }
           },
           address : {
               get : function(){
                   return userBL.address;
               },
               set : function(value){
                   userBL.address = value;
               }
           }
        });
    }   
})(angular);
 
 

הכתיבה של property קצת ארוכה מבחינת syntax אז כתבתי מתודה עזר:

function createProperty(source,wrapper,property){
    Object.defineProperty(wrapper,property,{
        get: function(){
            return source[property];
        },
        set : function(value){
            source[property] = value;
        }
    });
}
 
ועכשיו ה-controller יכתב כך:
function UserCtrl(userBL){
    this._bl = userBL;
    createProperty(userBL,this,’name’);
    createProperty(userBL,this,’address’);
}
 

שימו לב שבניתי את ה- properties על ה- this, אפשר לבנות אותו ישירות על ה- $scope, לא רעיון טוב. אני הייתי בונה אותו על ה- prototype כדי לא לשכפל פונקציות, של ה- get וה- set לכל מופע של ה- Controller.

function UserCtrl (userBL){
    this._bl = userBL;
    createProperty(userBL,UserCtrl.prototype,'name');
    createProperty(userBL,UserCtrl.prototype,'address');
}

 

הערה אחרונה: ngModelOptions

יש אפשרות באנגולר 1.3 להשתמש ב- ng-model-options="{ getterSetter: true }"זה תחליף ל-properties ע"י הטכנולוגיה של אנגולר, אך אני מאמין שכתיבה של property אמיתי יותר נכונה ויכולה לעבוד בכל השכבות. ראו דוגמא.

 

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

חומר זה הוא חלק מהקורס AngularJS  שאני מעביר בחברות.

 
3 תגובות

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

 

ngModelController 1.3 Internal

 

יש הרבה מאמרים על מה חדש באנגולר 1.3 בנושא הטפסים. אחד הטובים שבהם הוא Taming Forms in AngularJS 1.3. מה שלי היה חסר זה להבין לעמוק את סדר הפעולות של הדברים.

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

Capture

לינק לקוד שמדגים את הדברים, לחצו כאן.

למאמר בנושא שכתבתי על גירסה 1.2 לחצו כאן.

 

 
השארת תגובה

פורסם ע"י ב- נובמבר 3, 2014 ב- AngularJS

 

קורס AngularJS מחזור 5

בעקבות הביקוש הרב לפתיחת קורס ציבורי נוסף. החלטתי לפתוח בספטמבר סדנא של 3 ימים על Angular ו-JavaScript.  היום הראשון של הקורס על JavaScript ושאר הימים על AngularJS.

תאריכים: יום שלישי ה-16 עד יום חמישי ה-18 לספטמבר.

קהל יעד: מפתחים מקצועיים שיכולים שיכולים לקלוט הרבה חומר בשלושה ימיים.

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

1.     ביצוע הקורס האון-לין החינמי של Code School.

2.     ביצוע התרגיל TV Show, בכיתה נקח את התרגיל הזה ונבנה אותו מחדש כמו שצריך.

3.     להסתכל על הסרט http://www.objectplayground.com/

4.     לעבור על אתר הקורס http://ng-course.org

מי שיתכונן לפני הקורס יוכל לקבל מהקורס הרבה יותר !!!

לרישום ופרטים נוספים לחצו כאן.

 

Become an expert in AngularJS with this 3 days in-depth training course. This course will teach you the AngularJS fundamentals and the internal. The course will cover directives, binding, filters, ngRepeat, testing, isolate scopes and much more, with real-world examples. ng-course, the best course in Israel.

JavaScript fundamentals

·        Scope & Function Context

·        Closures

·        this keyword

·        Object-Oriented in JavaScript (slides)

·        Async and Parallel in JavaScript (slides)

·        JavaScript Design Pattern

AngularJS Building Blocks for Building SPA (slides)

·        Template & live data binding ( Directives & $scope )

·        Model, View & Controller (MVC)

·        Dependency Injection ( AngularJS services )

·        Modules

·        LAB : TV Show SPA

Forms in AngularJS (slides | post)

·        ng-model directive

·        ngModelController & FormController

·        Custom Validation

·        Input directive

AngularJS Filters (slides)

·        Filter Syntax

·        AngularJS Filters

·        Custom filters

Communication (slides)

·        $.Ajax vs. $http

·        $resource

·        Promises ($q) vs. Calbacks

·        Offline / Online

·        LAB: Full TV Show Web App

Custom Directive (slides)

·        Template

·        Scope (post)

·        Compile function

·        Link function

·        Controller

·        Transclude

·        Animation (slides)

·        Tips & tricks

Routing and Navigation (slides)

·        $location service

·        ng-view directive

·        $route service and route object

·        Navigation flow

·        Routing broadcasted events

·        Resolve option and promise

·        Cancelling route changes

AngularJS Testing (slides)

·        Unit Testing (Jasmine.js)

·        AngulrJS Mock API's (ngMock)

·        Unit Testing Tools

·        E2E Testing

·        ngMockE2E – $httpBackend

·        Protractor Tool

AngularJS Animation (slides)

·        CSS3-enabled Animations

·        Directive That Support Animation

·        JavaScript-enabled Animations

Using Animations in your own directives

 
2 תגובות

פורסם ע"י ב- אוגוסט 11, 2014 ב- AngularJS, Course, ng-course.org

 

AngularJS AMD Style

הצלחתי לגרום לקוד הזה לעבוד J J J J

var mi = angular.module('myApp', [

        './ngXXX', // load async

        './ngYYY', // load async

        {

            name: 'ngRoute',

            url: '/scripts/angular-route.js'

        }

    ]);

מה מיוחד בקוד הזה?

1.     לא צריך לשים על ה-HTML את התג <script src="ngXXX.js">, חוץ מהקובץ של המודול הראשי.

2.     אנגולר עובד כאן בסגנון של require של נוד. כלומר הוא מזהה את ההתחלה של "./" ואז הוא עושה בקשה לשרת להביא את הקובץ.

3.     אם שם המודול לא תואם את שם הקובץ אפשר לתת אובייקט עם שני השמות, ראו דוגמאות הקוד.

4.     כל המודולים נטענים אסינכרונית ורק שכולם נטענו אנגולר רץ.

5.     לא נגעתי בקובץ angular.js.

 

אני אפרסם את הקוד בהמשך. אני רוצה להוסיף תכונה של on Demand , שרק שצריך שרות מהמודול הוא יטען.

ההצלחה הזאת עשתה לי אושר קטן בתקופה הקשה הזאת.

אשמח לשמוע דעות ורעיונות לתוספות.

 
2 תגובות

פורסם ע"י ב- יולי 23, 2014 ב- AngularJS