Rumah > Artikel > hujung hadapan web > Menyelam secara mendalam ke dalam modularisasi dan suntikan kebergantungan dalam AngularJS
AngularJS disertakan dengan mekanisme suntikan pergantungan terbina dalam. Anda boleh membahagikan aplikasi anda kepada berbilang komponen daripada jenis yang berbeza yang boleh disuntik oleh AngularJS ke dalam setiap satu. Memodulasi aplikasi anda memudahkan penggunaan semula, konfigurasi dan komponen ujian aplikasi. [Cadangan tutorial berkaitan: "tutorial sudut"]
AngularJS termasuk jenis teras objek dan komponen berikut:
Jenis teras ini boleh disuntik ke dalam satu sama lain menggunakan mekanisme suntikan kebergantungan AngularJS. Sepanjang artikel ini, saya akan menerangkan cara untuk menentukan dan menyuntik komponen ini ke dalam satu sama lain.
Nilai dalam AngularJS ialah objek ringkas. Ia boleh menjadi nombor, rentetan atau objek JavaScript. Nilai biasanya digunakan sebagai konfigurasi untuk menyuntik ke dalam kilang, perkhidmatan atau pengawal.
Nilai mesti dimiliki oleh modul AngularJS. Berikut ialah tiga contoh nilai yang ditambahkan pada modul AngularJS:
var myModule = angular.module("myModule", []); myModule.value( “numberValue”,999); myModule.value( “stringValue的”, “ABC”); myModule.value("objectValue", { val1 : 123, val2 : "abc"} );
Nilai ditakrifkan menggunakan fungsi pada modul value()
. Parameter pertama ialah nama nilai, dan parameter kedua ialah nilai itu sendiri. Kilang, perkhidmatan dan pengawal kini boleh merujuk nilai ini dengan nama mereka.
Nilai suntikan
Nilai suntikan ke dalam fungsi pengawal AngularJS dilakukan dengan menghantar parameter Have nama yang sama dengan nilai (yang diluluskan kepada parameter pertama hanyalah nilai apabila fungsi value()
ditakrifkan). Berikut ialah contoh:
var myModule = angular.module("myModule", []); myModule.value( “ numberValue ”,999); myModule.controller( “myController的”功能($范围,numberValue){ 的console.log(numberValue); });
Memberitahu pengawal bagaimana parameter kedua fungsi mempunyai nama yang sama dengan nilai.
Kilang ialah fungsi yang mencipta nilai. Apabila perkhidmatan, pengawal, dsb. memerlukan nilai yang disuntik daripada kilang, kilang mencipta nilai atas permintaan. Setelah dibuat, nilai ini akan digunakan semula untuk semua perkhidmatan, pengawal, dsb. yang perlu disuntik. Jadi kilang berbeza daripada nilai kerana ia boleh menggunakan fungsi kilang untuk mencipta objek yang dipulangkan. Anda juga boleh menyuntik nilai ke dalam kilang untuk digunakan semasa membuat objek. Anda tidak boleh melakukan ini dengan nilai.
Berikut ialah contoh mentakrifkan kilang pada modul dan pengawal yang menyuntik nilai ciptaan kilang:
var myModule = angular.module("myModule", []); myModule.factory("myFactory", function() { return "a value"; }); myModule.controller("MyController", function($scope, myFactory) { console.log(myFactory); });
Seperti yang anda lihat, ia sangat serupa dengan mentakrif dan menyuntik nilai persamaan objek. Ingat, bukan fungsi kilang yang disuntik, tetapi nilai yang dihasilkan oleh fungsi kilang.
Nilai yang disuntik ke dalam kilang
Anda boleh menyuntik nilai ke dalam kilang . Ia berfungsi sama seperti menyuntik nilai ke dalam pengawal. Berikut ialah contoh:
var myModule = angular.module("myModule", []); myModule.value("numberValue", 999); myModule.factory("myFactory", function(numberValue) { return "a value: " + numberValue; });
Dalam contoh ini, nilai yang disuntik digunakan untuk mencipta objek yang dicipta oleh fungsi kilang.
Perkhidmatan dalam AngularJS ialah objek JavaScript tunggal yang mengandungi set fungsi. Fungsi ini mengandungi sebarang logik yang diperlukan oleh perkhidmatan untuk menjalankan tugasnya.
Perkhidmatan AngularJS dicipta menggunakan fungsi pada modul service()
. Berikut ialah contoh:
function MyService() {this.doIt = function() {console.log("done");}} var myModule = angular.module("myModule", []); myModule.service("myService", MyService);
Seperti yang anda lihat, takrif perkhidmatan adalah berbeza daripada kilang dan nilai. Pertama, perkhidmatan ditakrifkan sebagai satu fungsi bernama. Ini kerana perkhidmatan dalam AngularJS dibuat menggunakan kata kunci new
. Jadi AngularJS akan melakukan ini secara dalaman:
var theService = new MyService();
Selain mentakrifkan perkhidmatan sebagai fungsi dengan fungsi di dalam, anda juga boleh menambahkannya dan menggunakannya dengan AngularJS, Sama seperti menggunakan nilai atau fungsi. Anda boleh menyuntik perkhidmatan ke dalam pengawal seperti ini:
function MyService() { this.doIt = function() { console.log("done"); } } var myModule = angular.module("myModule", []); myModule.service("myService", MyService); myModule.controller("MyController", function($scope, myService) { myService.doIt(); });
Suntikan Nilai ke dalam Perkhidmatan
Anda boleh menyuntik nilai ke dalam perkhidmatan, sama seperti anda boleh menyuntik nilai ke dalam pengawal, atau perkhidmatan ke dalam pengawal, dsb. Berikut ialah contoh:
var myModule = angular.module("myModule", []); myModule.value ("myValue" , "12345"); function MyService(myValue) { this.doIt = function() { console.log("done: " + myValue; } } myModule.service("myService", MyService);
Perhatikan bagaimana parameter fungsi MyService
dinamakan sama dengan nilai yang didaftarkan pada modul. Oleh itu, nilai ini akan disuntik ke dalam perkhidmatan pada penciptaan.
AngularJS 中的提供者是您可以创建的最灵活的工厂形式。您可以像使用服务或工厂一样使用模块注册提供者,但您要使用该 provider()
函数。这是一个 AngularJS 提供程序示例:
var myModule = angular.module("myModule", []); myModule.provider("mySecondService", function() { var provider = {}; provider.$get = function() { var service = {}; service.doService = function() { console.log("mySecondService: Service Done!"); } return service; } return provider; });
如您所见,该provider()
函数采用 2 个参数。第一个参数是提供者创建的服务/对象的名称。在这种情况下,名称是mySecondService
。第二个参数是创建提供程序的函数。注意:提供者本身是一个工厂,因此此时没有从提供者创建实际的服务或对象。仅定义了创建提供程序的函数。
当您查看创建提供程序的函数时,您可以看到提供程序是一个 JavaScript 对象。
JavaScript 提供程序对象包含一个$get()
函数。这是提供者的工厂函数。换句话说,该$get()
函数会创建提供者创建的任何内容(服务、值等)。在上面的例子中,提供者创建了一个服务对象,其中包含一个名为 的服务函数(标准 JavaScript 函数)doService()
。
为了将提供者的产品注入控制器,请指定对提供者的依赖,就像使用服务一样。注入控制器的是提供者创建的产品,而不是提供者本身。这是一个 AngularJS 提供程序注入示例:
myModule.controller("MyController", function($scope, mySecondService ) { $scope.whenButtonClicked = function() { mySecondService.doIt(); } });
如您所见,提供者的名称用作控制器函数中的参数。提供者的$get()
函数创建的对象将被注入到这个参数中。
配置提供商
可以在模块的配置阶段通过调用其函数来进一步配置提供者。下面是一个例子:
var myModule = angular.module("myModule", []); myModule.provider("mySecondService", function() { var provider = {}; var config = { configParam : "default" }; provider.doConfig = function(configParam) { config.configParam = configParam; } provider.$get = function() { var service = {}; service.doService = function() { console.log("mySecondService: " + config.configParam); } return service; } return provider; }); myModule.config( function( mySecondServiceProvider ) { mySecondServiceProvider.doConfig("new config param"); }); myModule.controller("MyController", function($scope, mySecondService) { $scope.whenButtonClicked = function() { mySecondService.doIt(); } });
注意 provider 对象现在如何有一个名为 的额外函数doConfig()
。此函数可用于在提供程序上设置配置参数。
还要注意对myModule.config()
函数的调用。该config
函数接受一个函数作为参数。该函数可以配置模块。传递给的函数 config()
采用名为 的单个参数mySecondServiceProvider
。这与提供者注册的名称相同Provider
,后缀为 plus 。后缀告诉 AngularJS 注入提供者本身,而不是提供者创建的对象。在传递给config()
函数的mySecondServiceProvider.doConfig()
函数内部调用该函数,该函数在提供程序上设置 config 参数。
示例中稍后定义的控制器仅依赖于提供者创建的对象(而不是提供者本身)。它通过获取一个名为mySecondService
name 的参数来实现,该参数是服务提供者注册的名称。如您所见,从$scope.whenButtonClicked()
函数内部使用的服务 。
在上一节有关提供程序的部分中,您看到了如何通过module.config()
函数配置提供程序。不幸的是,您不能将值注入到module.config()
函数中。相反,您可以注入常量。
AngularJS 中的常量是使用module.constants()
函数定义的。这是一个 AngularJS 常量示例:
myModule.constant("configValue", "constant config value");
这个常量现在可以module.config()
像这样注入到函数中:
myservices.config( function( mySecondServiceProvider, configValue ) { mySecondServiceProvider.doConfig(configValue); });
如您所见,该参数configValue
与常量的名称相匹配,该名称也是 configValue
. 因此常量的值将被注入到这个参数中。然后将常量值作为参数传递给提供程序doConfig()
上的函数 mySecondServiceProvider
。
如您所见,值、工厂和服务被添加到 AngularJS 模块中。一个模块可以使用另一个模块的值、工厂和服务。为此,模块需要声明对包含它要使用的值、工厂和服务的模块的依赖关系。下面是一个例子:
var myUtilModule = angular.module("myUtilModule", []); myUtilModule.value("myValue", "12345"); var myOtherModule = angular.module("myOtherModule", [ 'myUtilModule' ]); myOtherModule.controller("MyController", function($scope, myValue ) { });
注意第二个模块 ( myOtherModule
)如何在myUtilModule
传递给angular.module()
函数的第二个参数(数组内部)中列出第一个模块 ( )的名称。这告诉 AngularJS 中定义的所有值、工厂和服务也myUtilModule
应该在myOtherModule
模块中可用。换句话说,myOtherModule
取决于 myUtilModule
。
其次,注意MyController
控制器函数现在如何声明一个名为 的参数myValue
。该值将从在myUtilModule
模块上注册的值提供。
当您缩小 JavaScript 时,JavaScript minifier 会用较短的名称替换局部变量和参数的名称。然而,AngularJS 使用控制器函数、工厂、服务和提供者的参数名称来决定将什么注入到他们的工厂函数中。如果名称更改,AngularJS 将无法注入正确的对象。
为了使您的 AngularJS 代码压缩安全,您需要提供要作为字符串注入的对象的名称。您将这些字符串与需要注入值的函数一起包装在一个数组中。这是一个 AngularJS 压缩安全依赖注入示例:
var myapp = angular.module("myapp", ['myservices']); myapp.controller("AController", ['$scope', function(p1) { p1.myvar = "the value"; }]);
本示例将$scope
对象注入到p1
控制器函数的参数中。
注意控制器函数是如何注册的。不是angular.controller
直接将控制器函数传递给函数,而是传递一个数组。该数组包含要注入控制器函数的值的名称,以及控制器函数本身。控制器函数始终是该数组中的最后一个值。如果需要注入多个值,则值名称列在数组的开头,并按它们要注入函数的顺序列出。这是一个缩小安全的多值示例:
var myapp = angular.module("myapp", ['myservices']); myapp.controller("AController", ['$scope', '$http', function(p1, p2) { p1.myvar = "the value"; p2.get("/myservice.json"); }]);
此示例将$scope
对象注入p1
参数,并将$http
服务注入p2
控制器函数的参数。
现在,控制器函数的参数名称不再重要。AngularJS 将使用数组开头的字符串来确定要注入到控制器函数中的内容。
相同的机制可用于工厂、服务和提供者,以提供缩小安全的依赖注入。这是一个小型化安全工厂、服务和提供程序示例:
var myutil = angular.module("myutil", []); myutil.value("safeValue", "a safe value"); myutil.factory("safeFactory", ['safeValue', function(p1) { return { value : p1 }; }]); function MySafeService(p1){ this.doIt = function() { return "MySafeService.doIt() called: " + p1.value; } } myutil.service("safeService", ['safeFactory', MySafeService]); myutil.provider("safeService2", function() { var provider = {}; provider.$get = ['safeService', function(p1) { var service = {}; service.doService = function() { console.log("safeService from provider: " + p1.doIt()); } return service; }]; return provider; }); myapp.controller("AController", ['$scope', 'safeService2', function(p1, p2) { p1.myvar = "the value"; p2.doService(); }]);
尤其要注意的provider的声明。注意,此时的依赖不会对provider工厂函数指定,但对$get()
从provider工厂函数内部返回的供应商的功能。实际上,使用具有依赖项名称和函数实现的数组而不仅仅是$get()
函数。
更多编程相关知识,请访问:编程视频!!
Atas ialah kandungan terperinci Menyelam secara mendalam ke dalam modularisasi dan suntikan kebergantungan dalam AngularJS. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!