AngularJS - 依賴注入:初學者指南

Hello, 動手程式設計師!今天,我們將踏上一段令人興奮的旅程,進入 AngularJS 的世界,以及它最強大的功能之一:依賴注入(DI)。別擔心這些術語現在聽起來像是一堆亂碼 - 到了這個教學的結尾,你將能夠像專業人士一樣輕鬆地使用它們!

AngularJS - Dependency Injection

什麼是依賴注入?

在我們深入細節之前,讓我們先了解什麼是依賴注入。想像你正在烤蛋糕。如果你不需要自己收集所有的材料,而在你需要時有人遞給你正確的材料,那不是很好嗎?這就是依賴注入在編程中做的事情 - 它為你的代碼(蛋糕)提供運行所需的組件(材料)。

現在,讓我們探討 AngularJS 實現依賴注入的不同方式。

Value

Value 是最簡單形式的依賴注入。這就像傳遞一個單獨的材料給你的蛋糕製作函數。

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

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

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

在這個例子中,我們創建了一個名為 'playerName' 的 value,並將它注入到我們的控制器中。控制器然後可以像本地變量一樣使用這個值。

Factory

Factory 就像蛋糕預拌粉 - 它是一個創建並返回對象的函數。它比 Value 更複雜,但給你更多的靈活性。

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();
});

在這裡,我們創建了一個返回對象的 factory,該對象具有屬性和方法。控制器然後可以使用這個 factory 來訪問球員的信息。

Service

Service 與 Factory 相似,但它返回的是函數的實例,而不是返回對象。把它想像成只做一種蛋糕的專業烘焙店。

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();
});

Factory 與 Service 之間的主要區別在於它們是如何實例化的。Service 嚴格上是單例的 - 在你的應用程序中只有一個實例。

Provider

Provider 是 AngularJS 中最複雜形式的依賴注入。它就像一個設備齊全的烘焙店,可以按照你想要的任何方式製作任何類型的蛋糕,使用任何材料。

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 讓你能在應程序運行之前配置服務。在這個例子中,我們在配置階段設置了球員的名字,這個階段在主應程序之前運行。

Constant

Constant 與 Value 相似,但它可以在你的應程序的配置階段被注入。這就像有一個你總是精準遵循的配方,無論你做的是哪種蛋糕。

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 對於在整個應程序中永不更改的值非常有用。

示例:建立一個籃球隊伍管理器

現在我們已經涵蓋了所有的依賴注入類型,讓我們在更複雜的例子中將它們全部整合起來。

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!');
}
};
});

輸出

當你運行這個應程序時,你將會有一個完全功能的籃球隊伍管理器。你可以將球員添加到你的隊伍(直到達到允許的最大數量),看教練的鼓勵,以及知道比賽在哪裡進行。

這裡是一個總結我們所涵蓋的不同依賴注入類型的表格:

類型 描述 使用案例
Value 簡單值注入 用於注入簡單值
Factory 返回一個對象 用於創建具有複雜邏輯的服務
Service 返回函數的實例 用於單例服務
Provider 可配置的服務工廠 用於運行前需要配置的服務
Constant 不變的值,可在配置中注入 用於應程序範圍內常數值

記住,精通依賴注入的關鍵是實踐。從簡單的注入開始,然後逐漸進階到更複雜的情節。在你還未意識到之前,你將能夠像專業人士一樣創建模塊化、可維護的 AngularJS 應程序!

祝賀你,未來的 AngularJS 大師!快樂編程!

Credits: Image by storyset