RSS

קטגוריה: Uncategorized

Angular2 in memory web api

Angular2 in memory web api

 

באנגולר 2 אפשר להשתמש בספריה ‘angular2-in-memory-web-api’ כדי לבטל את התקשורת הפיזית לשרת ולעבוד מול מידע שנמצא בזיכרון, טוב לבדיקות.

שלב ראשון מחלקה שתחזיק את המידע בזיכרון. ראו קוד:

export class InMemoryDataService {
createDb() {
return { users:[
// users resource
{…},
// user object
{…},
// user object
…   
// users objects
]};
}
}

 

הדגשים:

1.     אנגולר יקרה למתודה createdDb בפעם הראשונה שתנסו לפעיל את המחלקה Http.

2.     ה- users מחליפים את ה- resource ב- web-API שעליו ניתן לעשות פעולות CRUD ע"פ החוקים של REST. למשל ‘app/users/12’ תביא את המשתמש עם id שווה ל- 12.

 

שלב שני בניית מערך לשימוש ה- Injector הראשי.

 

export const HTTP_IN_MEMORY = [
    HTTP_PROVIDERS,
    { provide: XHRBackend, useClass: InMemoryBackendService },
    { provide: SEED_DATA , useClass: InMemoryDataService },
    { provide: InMemoryBackendConfig, useValue: { delay: 600 } }
];
 
דגשים:

1.     השרות XHRBackend הוא זה שמבצע בפועל את התקשורת לשרת, לכן 
צריך להחליף אותו עם השרות InMemoryBackendService שבמקום לבצע
תקשורת יקרא ל- SEED_DATA, שזה בעצם המחלקה שאנחנו כתבנו, 
שיוצרת את מבנה הנתונים בזיכרון.

2.     השרות InMemoryBackendConfig מאפשר לנו לתת הגדרות של התנהגות,
כמו למשל המתנה של 600 MS בין הקריאה לחזרת התשובה. 
ניתן לראות את כל האפשרויות בממשק הבא:

export interface InMemoryBackendConfigArgs {
    // default response options
    defaultResponseOptions?: ResponseOptions;
    // delay (in ms) to simulate latency
    delay?: number;
    // false (default) if ok when object-to-delete not found; else 404     
    delete404?: boolean;
    // host for this service
    host?: string;
    // root path before any API call
    rootPath?: string;
}
 
 
שלב אחרון: חיבור ל- bootstrap.
 
bootstrap(App,[ HTTP_IN_MEMORY ]);
 
סיכום:

 

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

 

מאמר זה הוא חלק התוכן שאני מעביר בקורסים שלי.
הקורס הבא יהיה ב- 18 לספטמבר. לפרטים נוספים הירשמו כאן: ng-course.org
.

 

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

פורסם ע"י ב- יולי 4, 2016 ב- Angular 2.0, Uncategorized

 

Angular 2 The Clock Component

באנגולר 2 אחרי כל אירוע אסינכרוני יש tick שנקרה ע"י ה-zone. אם יש הרבה אירועים אסינכרוניים בשנייה אנחנו יכולים לגרום לבעיית ביצועים.

בפוסט זה אני רוצה להסביר איך לכתוב רכיב שעון בדיוק של 50 ms. בחרתי את הקוד הבסיסי  לשעון שלי:

setTime(){
let t = new
Date();
this.time =
`
${t.getHours()}

        :
${this.formatNum(t.getMinutes())}
        :
${this.formatNum(t.getSeconds())}
        :
${t.getMilliseconds()}`;
setTimeout(
this.setTime.bind(this),50
);
}
formatNum(i){
return i < 10 ? `0${i}`
: i; }

 

שימו לב:

אני משתמש ב- setTimeout ולא ב- setInterval כדי לא ליצור עומס על ה- queue במידה וה- UI Thread עמוס ואז הוא לא מצליח למשוך מהתור את הפונקציות בקצב שה- setInterval מיצר אותם.

 

שלב א: לעבוד מחוץ לאנגולר

אני לא רוצה שכל 50 ms יבוצע tick במערכת. (המשמעות של tick  היא שאנגולר עובר על עץ הרכיבים ובודק מה השתנה ואז מעדכן את ה- UI. ראו פוסטים בנושא. ) לכן אני אשתמש ברכיב ה- NgZone.

constructor(zone:NgZone) {}
ngOnInit(){
    this.zone.runOutsideAngular(()=> {
        this.setTime();
    });
}
 
הקוד הנ"ל מוציא את ה- setTimeout ממנגנון ה- zone. כלומר עכשיו ה- 50 ms לא גורמים ל- tick.
 

שלב ב: לעדכן את המסך

אני אשתמש ביכולות של ה- ChangeDetectorRef והפונקציה detectChanges, מחשבת את כל החלקים הדינאמים בתבנית (למשל {{}} או [] ). ראו קוד:

@Component({
    selector: 'clock',
    template: `<span>{{time}}</span>`
})
export class Clock extends BaseDemo{
    time:string = '00:00:00:000';
    isDestroy:boolean = false;
    constructor(zone:NgZone,
                cd:ChangeDetectorRef) {}
    ngOnInit(){
        this.cd.detach();
        this.zone.runOutsideAngular(()=> {
            this.setTime();
        });
    }
    setTime(){
        if(this.isDestroy) return;
        let t = new Date();
        this.time = `
            ${t.getHours()}
            :${this.formatNum(t.getMinutes())}
            :${this.formatNum(t.getSeconds())}
            :${t.getMilliseconds()}`;
        this.cd.detectChanges();
        setTimeout(this.setTime.bind(this),50);
    }
    formatNum(i){ return i < 10 ? `0${i}` : i; }
    ngOnDestroy(){
        this.isDestroy = true;
    }
}

 

סיכום:

יש הרבה רכיבים שיש להם תדירות גבוהה של עדכון מסך. שימוש ברכים אלו יגרמו ל- tick שיגרום לעדכן את כל האפלקציה. בפוסט זה אני מראה לכם איך לשלוט בתדר העידכון ע"י ניתוק מה- zone וקריאה ל- detectChanges כל פעם שרוצים לעדכן את הרכיב על המסך. עדכון זה לא גורם ל- tick.

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

למידע נוסף בנושא, אשמח לראות אותכם בקורס אנגולר  2 שלי ng-course.

 
תגובה אחת

פורסם ע"י ב- יוני 25, 2016 ב- Angular 2.0, Uncategorized

 

The New Router

ראיתי את המצגת של מישקו בנושא ה-router החדש והתאכזבתי.

 

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

 

1. באתרים גדולים העץ כל כך גדול שה-URL לא יכול לייצג את ה-PATH של העץ, מגבלת אורך. אני מאמין שזה הסיבה שב- UI Router קראו לזה State ואנחנו יכולנו לקבוע לכל State את ה-Path שלו.

 

2. הרעיון של תיקיות עם "+"  זה נחמד ברוב המקרים, אך יש מקרים שהכל דינאמי והקשר בין ה-URL למבנה התיקיות מאוד מגביל. אני חושב שאנחנו צריכים קובץ מיפוי בין ה-URL לאיפה נמצאים ה- Components.

 

האמת שאני מואד אוהב את ה- UI Router וחשבתי שהם ישפרו אך ישמרו על העקרונות. מקווה שבקרוב נראה גירסה יותר מתקדמת של UI Router לאנגולר 2.0.

 

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

 
השארת תגובה

פורסם ע"י ב- מאי 7, 2016 ב- Uncategorized

 

Angular 2.0 Component Decorator

 

בפוסט זה אני רוצה להסביר את כל הפרטים הטכנים על @Component.

כאשר אנחנו כותבים באנגולר מחלקה מסוג component אנחנו חייבים להוסיף @Component עם כל הפרטים, כמו למשל selector, template וכ"ו. הפונקציה Component יוצרת מהמידע הנ"ל מחלקה בשם ComponentMetadata ושומרת את המידע כ-metadata על המחלקה.

: Reflect Metadata API

אנגולר 2 משתמש ב-Reflect Metadata כדי לשמור את המידע שנתנו ב- @Component.  כאן אנגולר מגדיר את הפונקציה Component. והפונקציה makeDecorator משתמש ב-Reflect Metadata כדי לאחסן את המידע ביחד עם המחלקה שלכם.

למה זה מעניין?

בעיה: רוצים לרשת מחלקה מסוג Component וגם את הגדרות שלה ב-@Component.

פתרון:

כתבתי decorator חדש , ngExComponent שיכול לקבל arg נוסף של מחלקה. ה- ngExComponentקורא את ה-metadata מהמחלקה וממזג אותם עם ה-metadata של המחלקה היורשת. ראו קוד:

export function ngExComponent(metadata,component?){
   
var
merageMetadata = component?
        Object.assign(getComponentMetadata(component),metadata):
        metadata;
   
return
Component(merageMetadata);
}

 

דוגמא לשימוש:

@Component({
    selector:'users',
    providers:[UserProxy],
    directives: [User],
})
class BaseUser{}
// Derive class
@ngExComponent({     template: `...`
},BaseUser) export class User extends BaseUser{ ... }
 
הסברים:
היתרון בשיטה זו שאני יכול במחלקה BaseUser להגדיר את כל ה-metadata המשותפים לכל סוגי 
ה-User. המחלקה היורשת יכולה לדרוס את ה-metadata שהיא צריכה.
 
לקוחות שלא אוהבים לעבוד עם ngExComponent, אני מוסיף למחלקה העליונה מתודה סטטית
 בשם getMetadata, ראו קוד:
@Component({
    selector:'users',
    providers:[UserProxy],
    dirctives: [User],
})
class BaseUser{
    static getMetadata():ComponentMetadata{
        var result;
        Reflect.getMetadata('annotations', BaseUser)
            .forEach(metadata => {
                if (metadata.constructor.name === 'ComponentMetadata'){
                    result =  metadata;
                }
            });
        return result;
    }
}
 

בעיה: איך משנים בזמן ריצה את ComponentMetadata, כמו למשל templateUrl או styleUrls?

 

פתרון:

אנגולר משתמש בשרותים מסוג Resolvers כדי לקרוא את ה-metadata של Component.

clip_image002

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

 

אשמח לקבל פידבקים J

נושאים אלו אני מלמד בקורס שלי Angular 2.0 Development לפרטים נוספים לחצו כאן.

 

 
4 תגובות

פורסם ע"י ב- אפריל 21, 2016 ב- Uncategorized

 

Angular 1.x vs. Angular 2.x

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

הרצאה זו לקוחה מתוך הקורס שלי על Angular 2.

תאריכים של פתיחת קורס על Angular 2:

1. בחודש מאי 9,16,23,30 (ימי שני ) לינק לרישום, בירושלים.

2. בחודש יוני, 19,22,26,29 בהרצליה.

 
השארת תגובה

פורסם ע"י ב- אפריל 13, 2016 ב- Uncategorized

 

Angular Injector Round III

בפוסט זה אני מראה איך אפשר לוותר היום על ה- Injector !!! לא נפלתי על הראש (מקווה). בזמן האחרון אני כותב אנגולר 1.x ו-2.0 עם ES 6 או TS, והתחושה שה- Injector פשוט מיותר לגמרי באנגולר 1.0 עם כותבים ב- ES 6.

המטרות של ה- Injector באנגולר 1:

1. הזרקת השירותים שאני רוצה בלי להכיר את המימוש וע"י כך מקל אלי בבדיקות.

2. ה- Injector עובד כ- lazy initialization, עד שלא מבקשים שירות הוא לא נוצר. ראו סרט בנושא.

 

איך מפסיקים להשתמש ב-Injector של אנגולר?

1. בונים תחליף שמשמש כגשר בין השרותים של אנגולר לשרותים שלנו להלן יקרה ngServices.

2. ngServices צריך לתת לי גישה לכל השרותים של אנגולר שהם singleton, שזה כולם חוץ מ- $scope ו- $element. ( אם שכחתי, אנא תעירו לי ).

 // ngServices.js
export var ngServices = {
    $injector : null
};

export function addAngularServices() {
    for(let i = 0; i < arguments.length ; i++){
        let serviceName = arguments[i];
        Object.defineProperty(ngServices,serviceName,{
            get(){
                return ngServices.$injector.get(serviceName);
            }
        });
    }
}

export function ngServicesConfig($injectorProvider){
ngServices.$injector = $injectorProvider.$get();
}

 

 

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

כאשר רוצים לצרוך שרות עושים import ל- ngServices. ראו דוגמא של שרות userProxy שצורך שרותי אנגולר בסיסיים כמו $http.

Capture

הסברים:

שאתם רוצים לכתוב שרות או סתם מחלקה אתם לא צריכים לרשום אותה יותר לאנגולר. אם אתם רוצים להשתמש בשרותים שרשומים באנגולר אתם צורכים אותם דרך ngServices.

כדי ש- ngServices יוכל לצרוך שרותים של אנגולר ולחשוף אותם דרכו את צריכים להוסיף את השורה הבאה למודול הראשי שלכם.

 

import angular from 'angular';
import {ngServicesConfig} from './utils/ngServices'
;

angular.module('app',[])
.config(ngServicesConfig);

 

סיכום:

אני מאמין שברגע שמשתמשים ב-import (systemjs) אין צורך לרשום את השרותים שלנו לתוך המודלים של אנגולר 1. הראתי שזה לא פוגע בשום יכולת קיימית אלה רק מקל אלינו את הפיתוח ומוריד את התלות באנגולר אחד. אני מאמין שזה יקל אלינו גם בשידרוג לאנגולר 2.

 

יש אפשרות לבצע את אותו טריק גם באנגולר 2, אך זה כבר פוסט אחר.

 

צריך לזכור שזה קוד ראשוני ועוד לא עבר את כל הבדיקות לכן אשמח לקבל הערות.

 
2 תגובות

פורסם ע"י ב- מרץ 31, 2016 ב- Uncategorized

 

Async and Parallel in JavaScript (meetup)

תודה לכל האנשים שבאו.  מצ"ב הלינק למצגת.

 
השארת תגובה

פורסם ע"י ב- ינואר 13, 2016 ב- Uncategorized