Cơ chế dependency Injection (cơ chế tiêm phụ thuộc) trong angularJS
- 29-04-2022
- Toanngo92
- 0 Comments
DI là một cơ chế mạng mẽ của angularJS, nó giúp đưa một đối tượng được định nghĩa từ thư viện bên thứ 3 vào ứng dụng angular, được truyền vào như phần tử trong mảng ở tham số thứ 2 khi khởi tạo module angularJS, dựa theo cách code chúng ta hiểu, nó giúp tham chiếu tới đối tượng thư viện nhưng không cần sử dụng câu lệnh tham chiếu trực tiếp, là kỹ thuật đưa một chức năng phụ thuộc vào module tại thời điểm thực thi mà không cần coding cho nó.
Xem thêm khái niệm về dependency injection tại wikipedia: https://en.wikipedia.org/wiki/Dependency_injection
Lập trình viên có thể chia ws dụng thành nhiều thành phần (component) khác nhau, và có thể tiêm từ thành phần này sang thành phần khác, cơ chế module hóa trong ứng dụng angularJS giúp dễ dàng cấu hình, sử dụng lại, cập nhật và kiểm tra các components. Các builtin injector(đối tượng được tiêm mặc định) sẽ chịu trách nhiệm tạo các components ( thành phần), phân loại ra các phụ thuộc, cung cấp chúng cho các thành phần khác khi được yêu cầu
Như đã đề cập, cơ chế tiêm giúp cho code có tính sử dụng lại hơn, ví dụ nếu chúng ta muốncos một tính năng cần sử dụng lại ở vài tình huống khác nhau trong ứng dụng, hãy nghĩ tới việc định nghĩa ra một nghiệp vụ chung và sử dụng lại chúng bằng cách tiêm vào như một phụ thuộc.
Một số các components (thành phần) và objects (đối tượng) mà angularJS tiêm vào ứng dụng thông qua cơ chế tiêm:
- value
- Provider
- Constant
- Factory
- Service
Mục lục
Value
Đây là một phương thức của module, nó giúp lập trình viên định nghĩa ra một đối tượng (object), chuỗi(number), hay số(number) và tiêm chúng vào controller trong giai đoạn config (bootstrapping – giai đoạn khởi động). Nó thường được sử dụng để tiêm giá trị vào server, controller, facetory.
Xem ví dụ dưới đây:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dependency injection</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
</head>
<body ng-app="myApp">
<div ng-controller="myController">
</div>
</body>
<script>
var myApp = angular.module('myApp', []);
myApp.value("number",10);
myApp.value("string","Hello");
myApp.value("object",{name:"Nguyen Van A",age:20});
myApp.value("array",["Nguyen Van A","Nguyen Van B","Nguyen Van C"]);
myApp.controller('myController', function($scope,number,string,object,array){
$scope.number = number;
$scope.string = string;
$scope.object = object;
$scope.array = array;
console.log($scope.number);
console.log($scope.string);
console.log($scope.object);
console.log($scope.array);
});
</script>
</html>
Kết quả khi chạy chương trình:
Provider
AngularJs sử dụng phương thức provider() để tạo một service hoặc factory trong giai đoạn cấu hình (khi mới bắt đầu khởi chạy và cấu hình ứng dụng) , một provider là một hàm factory riêng biệt cùng với phương thức $get() và trả về giá trị, factory hay service (hơi khó hiểu, nhưng hãy nhìn xuống example.Nó nói cho angualrJS biết cách tạo một service injectable (nghiệp vụ có thể tiêm được, vì thế, provider định nghĩa service và được tạo thông qua service builtin là $provide
Xét ví dụ phía dưới:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Example Provide</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.32/angular.js"></script>
</head>
<body ng-app="myApp">
<div ng-controller="myCtrl">
<button ng-click="DisplayProvider()" ng-disabled="flag">Display</button>
<div ng-bind="ProviderOutput"></div>
</div>
</body>
<script>
var app = angular.module('myApp', []);
app.provider("myProvider", function () {
this.$get = function () {
return {
Display: function () {
return "Display from services";
}
};
};
});
app.controller('myCtrl', function ($scope, myProvider) {
$scope.ProviderOutput = "Provider outoput";
$scope.DisplayProvider = function () {
$scope.flag = true;
$scope.ProviderOutput = myProvider.Display();
}
});
</script>
</html>
Đây là ví dụ cơ bản nhất về cách sử dụng provider giúp tạo các services có thể tiêm được vào controller, như chúng ta thấy, phương thức Display của myProvider đã có thể gọi, và đối tượng myProvider được tiêm vào controller để sử dụng, tương tự như các đối tượng có thể tiêm khác.
Ngoài ra, chúng ta cũng vẫn có thể định nghĩa các hàm thông qua phương thức app.config(), app.run() ( những phương thức sẽ chạy khi bắt đầu config ứng dụng hay ứng dụng bắt đầu chạy), khi đó các hàm cũng có thể tiêm được thông qua cơ chế tiêm.
Constant
Trong angularJS, phương thức config() không thể đưa một thực thể của service hay giá trị được định nghĩa thông qua phương thức value() vào trong nó như tham số, vì vậy,không thể tiêm một value hoặc một thực thể vào nó. Tuy nhiên, vẫn có thể tiêm một hằng số như một provider cho service trong quá trình config.Có nghĩa là hằng số giúp truyền giá trị trong quá trình config, và nó cũng có thể sử dụng trong khi ứng dụng đang chạy (run time)
Chứng minh thông qua ví dụ:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dependency injection</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.js"></script>
</head>
<body ng-app="myApp">
<div ng-controller="myController">
</div>
</body>
<script>
var myApp = angular.module('myApp', []);
myApp.value("testnumber",100);
myApp.config(function($provide,testnumber){
console.log(testnumber);
});
myApp.controller('myController', function($scope,testnumber){
});
</script>
</html>
Sau khi chạy, trình duyệt báo lỗi:
đối với constant, chúng ta làm được việc tiêm giá trị vào config() hoặc run(), thậm chí thay đổi giá trị. Tuy nhiên, cũng không có quá nhiều ý nghĩa vì mặc dù đã thay đổi giá trị của constant trong config, nhưng tầng controller, dữ liệu của biến vẫn nhận diện theo giá trị khi khởi tạo (constant là hằng số, không thay đổi giá trị trong suốt chương trình) Xem ví dụ phía dưới:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dependency injection</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.js"></script>
</head>
<body ng-app="myApp">
<div ng-controller="myController">
{{testnumber}}
</div>
</body>
<script>
var myApp = angular.module('myApp', []);
myApp.constant("testnumber",100);
myApp.config(function($provide,testnumber){
console.log($provide);
testnumber = 1000;
console.log(testnumber);
});
myApp.controller('myController', function($scope,testnumber){
$scope.testnumber = testnumber;
});
</script>
</html>