Sử dụng Dependency Injection trong Angular và RequireJS

Giới thiệu

Nếu bạn đã xây dựng các ứng dụng JavaScript lớn trước, rất có thể bạn phải đối mặt với nhiệm vụ quản lý các dependence. Nó có thể là một chức năng, đối tượng, hoặc một instance. Trong bài viết này, chúng tôi sẽ so sánh hai thư viện lớn, AngularJS và RequireJS. Chúng tôi sẽ phân tích cách chúng sử dụng dependence để chia sẻ các thành phần trên một ứng dụng.

Short Story on Dependency Injection

Dependency injection trở nên cần thiết khi bạn muốn thực hiện thực thi 1 hoặc nhiều components trong ứng dụng . Ví dụ bạn có 2 components database và logger. Trong đó database component thực thi các methods getAll, findById, create, update, and delete. Logger component chỉ có duy nhất 1 method, saveNewLog, và là public API. Giả sử các logger component phụ thuộc vào các database component để hoạt động. Sử dụng Dependency Injection, chúng ta có thể vượt qua trong các database component như là một dependence của logger components trong quá trình tạo.

Ví dụ về Database API:

function database() {
  var publicApis = {
    getAll: function() {},
    findById: function(id) {},
    create: function(newObject) {},
    update: function(id, objectProperties) {},
    delete: function(id) {}
  };

  return publicApis;
}

Logger API:

function logger(database) {
  var publicApis = {
    saveNewLog: function() {}
  };

  return publicApis;
}

như bạn có thể thấy ta đã truyền database component vào trong constructor của logger và giờ thì ứng dụng có thể sử lý instantiation của logger giống như với 1 database component.

Dependency Injection trong AngularJS

Có 3 cách để sử dụng Dependency Injection trong AngularJS

  1. Sử dụng Parameter Reffer
    function UserController(logger) {
      //some controller logic here to use injected logger factory
    }

    myModule.factory('database', function() {
      var publicApis = {
        getAll: function() {},
        findById: function(id) {},
        create: function(newObject) {},
        update: function(id, objectProperties) {},
        delete: function(id) {}
      };

      return publicApis;
    });

    myModule.factory('logger', function(database) {
      //use injected database factory here
      var publicApis = {
          saveNewLog: function() {}
      };

      return publicApis;
    });
  1. Sử dụng $inject
    function UserController(logger) {
      //some controller logic here to use injected logger factory
    }

    UserController['$inject'] = ['logger'];

    myModule.factory('database', function() {
      var publicApis = {
        getAll: function() {},
        findById: function(id) {},
        create: function(newObject) {},
        update: function(id, objectProperties) {},
        delete: function(id) {}
      };

      return publicApis;
    });

    function loggerFactory(database) {
      //use injected database factory here
      var publicApis = {
        saveNewLog: function() {}
      };

      return publicApis;
    }

    loggerFactory['$inject'] = ['database'];
    myModule.factory('logger', loggerFactory);
  1. Sử dụng Array Notation
    function UserController(loggerFactory) {
      //some controller logic here to use injected logger factory
    }

    myModule.controller('UserController', ['logger', UserController]);

    myModule.factory('database', function() {
      var publicApis = {
        getAll: function() {},
        findById: function(id) {},
        create: function(newObject) {},
        update: function(id, objectProperties) {},
        delete: function(id) {}
      };

      return publicApis;
    });

    function loggerFactory(database) {
      //use injected database factory here
      var publicApis = {
        saveNewLog: function() {}
      };

      return publicApis;
    }

    myModule.factory('logger', ['database', loggerFactory]);

Sử dụng dependency injection với RequireJS

Dependency Injection với RequireJS hoạt động bằng các thành phần trong các tập tin. Mỗi thành phần sống trong tập tin riêng biệt của nó. Trong khi AngularJS tải các thành phần trả trước, RequireJS chỉ tải một phần khi cần thiết. Nó làm điều này bằng cách làm cho một cuộc gọi Ajax đến máy chủ để có được các tập tin cần thiết.

  1. Khai báo các function
    //filename: database.js
    define([], function() {
      var publicApis = {
        getAll: function() {},
        findById: function(id) {},
        create: function(newObject) {},
        update: function(id, objectProperties) {},
        delete: function(id) {}
      };

      return publicApis;
    });

    //filename: logger.js
    define(['database'], function(database) {
      //use database component here somewhere
      var publicApis = {
        saveNewLog: function(logInformation) {}
      };

      return publicApis;
    });
  1. Require Function
    Để cho logger component có thể sử dụng đc function của nó,chúng ta cần đấy vào 1 require function.
    require(['logger'], function(logger) {
      //some code here
      logger.saveNewLog('log information');
    });

Như bạn có thể thấy ở trên, các yêu cầu chức năng chỉ được sử dụng để chạy một số mã và không trả lại bất cứ điều gì. Tham số đầu tiên nó chấp nhận là một mảng của các module phụ thuộc. Thứ hai là các chức năng để chạy khi những người phụ thuộc đã được tải. Hàm này nhận nhiều thông số như có phụ thuộc vào tải. Mỗi một đại diện cho các thành phần tương ứng.