AngularJS -Dependency Injection: Hướng dẫn cho người mới bắt đầu

Xin chào các bạn muốn trở thành lập trình viên! Hôm nay, chúng ta sẽ bắt đầu một hành trình thú vị vào thế giới của AngularJS và một trong những tính năng mạnh mẽ nhất của nó: Dependency Injection (DI). Đừng lo lắng nếu những thuật ngữ này听起来 như là tiếng lóng right now - đến cuối bài hướng dẫn này, bạn sẽ sử dụng chúng như một chuyên gia!

AngularJS - Dependency Injection

什么是Dependency Injection?

Trước khi chúng ta đi sâu vào chi tiết, hãy hiểu Dependency Injection là gì. Hãy tưởng tượng bạn đang nướng một chiếc bánh. Thay vì tự 收集 tất cả các nguyên liệu, có phải sẽ tốt hơn nếu có ai đó đưa cho bạn chính xác những gì bạn cần, khi bạn cần nó? Đó chính là điều mà Dependency Injection làm trong lập trình - nó cung cấp các thành phần (nguyên liệu) mà mã của bạn (chiếc bánh) cần để hoạt động đúng cách.

Bây giờ, hãy khám phá các cách khác nhau mà AngularJS thực hiện Dependency Injection.

Value

Value là hình thức đơn giản nhất của dependency injection. Nó giống như truyền một nguyên liệu đơn lẻ vào hàm nướng bánh của bạn.

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

app.value('playerName', 'LeBron James');

app.controller('PlayerCtrl', function($scope, playerName) {
$scope.name = playerName;
});

Trong ví dụ này, chúng ta đang tạo một giá trị叫做 'playerName' và chích vào controller của chúng ta. Controller sau đó có thể sử dụng giá trị này như thể nó là một biến cục bộ.

Factory

Factory giống như một hỗn hợp bánh - nó là một hàm tạo và trả về một đối tượng. Nó phức tạp hơn Value nhưng cho bạn nhiều tính linh hoạt hơn.

app.factory('playerFactory', function() {
return {
name: 'Stephen Curry',
team: 'Golden State Warriors',
getInfo: function() {
return this.name + ' plays for ' + this.team;
}
};
});

app.controller('PlayerCtrl', function($scope, playerFactory) {
$scope.playerInfo = playerFactory.getInfo();
});

Ở đây, chúng ta đang tạo một factory trả về một đối tượng với các thuộc tính và phương thức. Controller sau đó có thể sử dụng factory này để truy cập thông tin của cầu thủ.

Service

Service tương tự như Factory, nhưng thay vì trả về một đối tượng, nó trả về một thể hiện của một hàm. Hãy tưởng tượng nó như một tiệm bánh chuyên nghiệp chỉ làm một loại bánh.

app.service('PlayerService', function() {
this.name = 'Kevin Durant';
this.team = 'Phoenix Suns';
this.getInfo = function() {
return this.name + ' plays for ' + this.team;
};
});

app.controller('PlayerCtrl', function($scope, PlayerService) {
$scope.playerInfo = PlayerService.getInfo();
});

Sự khác biệt chính giữa Factory và Service là cách chúng được khởi tạo. Service luôn là một singleton - chỉ có một thể hiện của nó trong toàn bộ ứng dụng của bạn.

Provider

Provider là hình thức phức tạp nhất của dependency injection trong AngularJS. Nó giống như có một tiệm bánh đầy đủ trang thiết bị có thể làm bất kỳ loại bánh nào, với bất kỳ nguyên liệu nào, theo bất kỳ cách nào bạn muốn.

app.provider('playerProvider', function() {
var defaultName = 'Giannis Antetokounmpo';

return {
setName: function(name) {
defaultName = name;
},
$get: function() {
return {
getName: function() {
return defaultName;
}
};
}
};
});

app.config(function(playerProviderProvider) {
playerProviderProvider.setName('Luka Doncic');
});

app.controller('PlayerCtrl', function($scope, playerProvider) {
$scope.playerName = playerProvider.getName();
});

Provider cho phép bạn cấu hình dịch vụ trước khi ứng dụng chạy. Trong ví dụ này, chúng ta đang đặt tên của cầu thủ trong phase cấu hình, chạy trước ứng dụng chính.

Constant

Constant tương tự như Value, nhưng nó có thể được chích vào phase cấu hình của ứng dụng. Nó giống như có một công thức bạn luôn tuân theo chính xác, không matter what cake bạn đang làm.

app.constant('GAME_DURATION', 48);

app.config(function(GAME_DURATION) {
console.log('A basketball game lasts ' + GAME_DURATION + ' minutes');
});

app.controller('GameCtrl', function($scope, GAME_DURATION) {
$scope.duration = GAME_DURATION;
});

Constants hữu ích cho các giá trị không thay đổi suốt toàn bộ ứng dụng của bạn.

Ví dụ: Xây dựng một Trình Quản lý Đội Bóng Rổ

Bây giờ chúng ta đã bao gồm tất cả các loại dependency injection, hãy kết hợp chúng lại trong một ví dụ phức tạp hơn.

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

// Constant
app.constant('MAX_PLAYERS', 15);

// Value
app.value('teamName', 'Angular All-Stars');

// Factory
app.factory('PlayerFactory', function() {
var players = [];
return {
addPlayer: function(name) {
players.push(name);
},
getPlayers: function() {
return players;
}
};
});

// Service
app.service('CoachService', function() {
this.name = 'Coach Angular';
this.motivate = function() {
return this.name + ' says: Let\'s win this game!';
};
});

// Provider
app.provider('gameProvider', function() {
var venue = 'Home Court';

return {
setVenue: function(v) {
venue = v;
},
$get: function() {
return {
getVenue: function() {
return venue;
}
};
}
};
});

app.config(function(gameProviderProvider) {
gameProviderProvider.setVenue('Angular Arena');
});

app.controller('TeamCtrl', function($scope, MAX_PLAYERS, teamName, PlayerFactory, CoachService, gameProvider) {
$scope.teamName = teamName;
$scope.maxPlayers = MAX_PLAYERS;
$scope.players = PlayerFactory.getPlayers();
$scope.coachMotivation = CoachService.motivate();
$scope.gameVenue = gameProvider.getVenue();

$scope.addPlayer = function(playerName) {
if ($scope.players.length < MAX_PLAYERS) {
PlayerFactory.addPlayer(playerName);
$scope.playerName = '';
} else {
alert('Team is full!');
}
};
});

Output

Khi bạn chạy ứng dụng này, bạn sẽ có một trình quản lý đội bóng rổ hoàn chỉnh. Bạn có thể thêm cầu thủ vào đội (đến giới hạn tối đa cho phép), xem lời khích lệ của huấn luyện viên và biết nơi diễn ra trận đấu.

Dưới đây là bảng tóm tắt các loại dependency injection chúng ta đã bao gồm:

Loại Mô tả Trường hợp sử dụng
Value Chích injection đơn giản Để chích các giá trị đơn giản
Factory Trả về một đối tượng Để tạo dịch vụ với logic phức tạp
Service Trả về thể hiện của một hàm Để dịch vụ singleton
Provider Dịch vụ factory có thể cấu hình Để dịch vụ cần cấu hình trước khi ứng dụng chạy
Constant Giá trị bất biến, có thể chích vào config Để các giá trị bất biến toàn cục

Nhớ rằng, chìa khóa để thành thạo dependency injection là thực hành. Bắt đầu với các injection đơn giản và dần dần làm việc với các tình huống phức tạp hơn. Trước khi bạn biết, bạn sẽ tạo ra các ứng dụng AngularJS modul, dễ bảo trì như một chuyên gia!

Chúc mừng编码, những người sẽ thành thạo AngularJS trong tương lai!

Credits: Image by storyset