פוסט

Main conrainer

הכרות עם AngularJS Services

בעולם הAngularJS, ה –Services  הם אובייקטים או פונקציות שתפקידם הוא לבצע משימות ספציפיות ע"י לוגיקה עסקית. SoC –Seperation Of Concern הינה גישה שמהווה את הלב הפועם של אפליקציית AngularJS, את עיקרי הגישה (שלא ניכנס אליה לעומק בפוסט זה) ניתן לסכם בשאלה אחת שמפנים לכיוון ה Controller  שלנו : האם הוא מבצע יותר מתפקיד אחד בודד? אם התשובה שלנו חיובית זה אומר שלא עקבנו בצורה מדוייקת אחרי ה SoC.

התפקיד של ה-Controller  שלנו צריך להיות מזוקק לפעולה \ תפקיד אחד בלבד לדוגמא לבצע Binding  של ה-ViewModel ל-View, בשביל למשוך את המידע הזה מהשרת נצטרך Service  או Factory ובעצם להזריק )המקבילה של Inject  בעברית) את ה-Service  לתוך ה-Controller  שלנו או כל מודול אחר באפליקציה.

ל-Services  יש הרבה יתרונות, הראשונה שבהם היא שמירה על העקרון של SoC, לכל קומפוננט יש את התפקיד שלו מה שעושה את האפליקציה הרבה יותר קלה לתחזוקה  - נגיד וכתובת ה API שונתה, - במקום לחפש בכל הקוד איפה השתמשנו בכתובת הזו יש לנו מקום אחד שדואג לכך ולשם נפנה, יתרון גדול(מאוד) נוסף הוא Unit Testing בקלות רבה ניתן לכתוב Unit Test  ל – Service שלנו ולחסוך זמן רב של פיתוח.

angularjs service diagram


ניקח לדוגמא את הדיאגרמה שלמעלה, חילקנו את האפליקציה שלנו ל-2 Controllers :

  • Clients
  • Dashboard


כל אחד מה-Controllers  משתמש במידע של ה Current User, אבל במקום לשכפל את הקוד שמחזיר לנו את הDATA מהשרת אנחנו "נחביא" את הלוגיקה בתוך Service ו-AngularJS כבר יעשה את העבודה בשבילנו ויזריק לנו את ה-Service  לתוך הקונטרולרים שלנו (באם נרצה בכך).

כמובן שזו דוגמא פשוטה ביותר שהיתה ניתנת לפיתרון בדרכים הרבה יותר אלגנטיות (משהו אמר $rootScope), אבל זה יהיה יותר ממספיק עבור הדוגמא שלנו.

השירותים הפנימיים של AngularJS

AngularJS  מספק הרבה Services   פנימיים שאנחנו יכולים להשתמש בהם ברחבי האפליקציה שלנו. $http  הוא דוגמא טובה ופופולארית.  כל ה-Services  הפנימיים מלווים בתו דולר ($) לפני השם.

השירותים האלו יכולים להיות בשימוש ע"י הכרזה עליהם כ Dependencies לדוגמא:

module.controller('FooController', function($http){
    //...
});

module.controller('BarController', function($window){
    //...
});
  

השירותים שלנו ב- AngularJS

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

var module = angular.module('app', []);

module.service('clientService', function(){
    this.clients = ['Alfa', 'Bravo', 'Charlie'];
});
  

או שאנחנו יכולים להשתמש ב Factory:

module.factory('clientsService', function(){

    var obj = {};

    obj.clients = ['Alfa', 'Bravo', 'Charlie']; 

    return fac;

});
  

שתי הדרכים להגדרת השירות הינן כשרות, בואו נבין את ההבדל בין ()factory  ו- ()service.

Services Vs Factory

AngularJs Services כמו שראינו הוא אובייקט בודד ועוד ראינו שישנן 2 דרכים (למעשה יש יותר אבל נתמקד ב 2 היותר נפוצות) להגדרת השירות:

module.service( 'serviceName', function );

module.factory( 'factoryName', function );
  

כשמכריזים על serviceName כארגומנט שמוזרק במודול\קונטרולר וכד' למעשה אנחנו מקבלים Instance של הפונקציה במילים אחרות :

()Myservice = new functionofmyservice

האובייקט שנוצר הוא זה שיוזרק אחר כך למודולים\קונטרולרים\directives  וכד'. למעשה קיבלנו את הפונקציה עצמה.

כשמכריזים על factoryName כארגומנט שמוזרק במודול\קונטרולר וכד' למעשה אנחנו מקבלים את הערך שמוחזר מהפונקציה ע"י הפעלה  של הפונקציה.

בדוגמא שלמטה אנחנו מגדירים את השירות myService בשתי הדרכים, שימו לב איך ב .service  אנחנו יוצרים את המתודות בעזרת this.methodname  וב-.factory  אנחנו מייצרים אובייקט ריק ובעצם מצוותים לו מטודה – זו שקראה לservice מלכתחילה

AngularJS .service

module.service('MyService', function() {
    this.method1 = function() {
            //..
        }

    this.method2 = function() {
            //..
        }
});
  

AngularJS .factory

module.factory('MyService', function() {

    var factory = {}; 

    factory.method1 = function() {
            //..
        }

    factory.method2 = function() {
            //..
        }

    return factory;
});
  

בואו נחבר את הקצוות:

נגדיר מודול חדש שייצג את הClients  באפליקציה שלנו:

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

במודול נגדיר את ה factory שיהיה אחראי על פעולות ה CRUD:

clients.factory('clientsFactory', ['$http', function ($http)
    return {
//מחזיר לקוח בודד לפי פרמטר שנשלח לפונקציה
        get: function (id) {
            return $http.get('/api/Clients/' + id);
        },
//מחזיר רשימה של לקוחות
        list: function () {
            return $http.get("/api/Clients");
        },
//פעולת עריכה של לקוח קיים
        Edit: function (id, model) {
            return $http.post('/api/Clients', {Id: id,  category: model });
        },
//פעולת הוספה של לקוח חדש
        Create: function (model) {
            return $http.post('/api/Clients', { category: model });
        },
//מחיקה של לקוח קיים
        Delete: function (id) {
            return $http.post('/api/Clients/' + id);
        }
    }
}]);
  

לאחר מכן במודול נגדיר את ה controller שלנו:

clients.controller('ClientsController', function ($scope, clientsFactory) {

   $scope.clients = clientsFactory.list();
   $scope.client ={};

   $scope.getClient = function (id) {
        clientsFactory.get(id);
    }

    $scope.saveClient = function (client) {
        clientsFactory.Edit(client.id, client);
    }

    $scope.createClient = function () {     
        clientsFactory.Create($scope.client);
    }

    $scope.delete = function (id) {
        clientsFactory.delete(id);
    }
});
  

המודול בשלמותו:

var clients = angular.module('myApp.clients', [ ]);

clients.factory('clientsFactory', ['$http', function ($http) {

    return {
        get: function (id) {
            return $http.get('/api/Clients/' + id);
        },
        list: function () {
            return $http.get("/api/Clients");
        },
        Edit: function (id, model) {
            return $http.post('/api/Clients', {Id: id,  category: model });
        },
        Create: function (model) {
            return $http.post('/api/Clients', { category: model });
        },
        Delete: function (id) {
            return $http.post('/api/Clients/' + id);
        }
    }
}]);

clients.controller('ClientsController', function ($scope, clientsFactory) {

   $scope.clients = clientsFactory.list();
   $scope.client ={};

   $scope.getClient = function (id) {
        clientsFactory.get(id);
    }

    $scope.saveClient = function (client) {
        clientsFactory.Edit(client.id, client);
    }

    $scope.createClient = function () {     
        clientsFactory.Create($scope.client);
    }

    $scope.delete = function (id) {
        clientsFactory.delete(id);
    }
});
  

זה הכל!

ראינו את הבסיס של service / factory ושל dependency injection באפליקציית  AngularJS, השילוב של השתיים מספק גמישות ענקית ומודולאריות של הקוד באופן שמקל מאוד על תחזוקה וניהול של הקוד ומאפשר לבצע בדיקות נקודתיות לכל רכיב במערכת.

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

תגובות (0)