ส่วนประกอบการฉีดการพึ่งพาของ AngularJS

⚡ สรุปอย่างชาญฉลาด

ใน AngularJS การฉีดการพึ่งพา (Dependency Injection) จะส่งอ็อบเจ็กต์ที่คอมponent ต่างๆ ใช้งานไปให้ แทนที่จะปล่อยให้คอมponent สร้างอ็อบเจ็กต์เหล่านั้นเอง ดังนั้นคอนโทรลเลอร์จึงได้รับบริการต่างๆ เช่น $http จากตัวฉีดของเฟรมเวิร์กในระหว่างการทำงาน

  • 🔘 ความหมาย: การควบคุมแบบกลับด้าน (Inversion of control) ช่วยให้ตัวฉีดภายนอกสามารถจัดหาส่วนประกอบที่จำเป็นทั้งหมดได้
  • ☑️ สูตร: ค่า, โรงงาน, บริการ, ผู้ให้บริการ และค่าคงที่ ที่สามารถฉีดเข้าไปในรีจิสเตอร์ได้
  • ✅ องค์ประกอบด้านมูลค่า: คู่คีย์-ค่าจะถูกส่งไปยังตัวควบคุมในรูปแบบพารามิเตอร์ฟังก์ชันธรรมดา
  • 🧪 บริการ: อ็อบเจ็กต์แบบซิงเกิลตันจะเปิดเผยฟังก์ชันที่สามารถนำกลับมาใช้ซ้ำได้ ซึ่งคอนโทรลเลอร์จะเรียกใช้โดยระบุชื่อฟังก์ชันนั้น
  • 🛠️ คำอธิบายประกอบ: การใช้ array แบบอินไลน์หรือสัญลักษณ์ $inject ช่วยให้การฉีดโค้ดทำงานได้แม้หลังจากการย่อขนาดไฟล์
  • 📊 หมายเหตุเกี่ยวกับเวอร์ชัน: การสนับสนุน AngularJS สิ้นสุดลงในเดือนมกราคม 2022 ปัจจุบัน Angular ใช้การฉีดผ่าน inject() แทน

การฉีด Dependency ใน AngularJS โดยการส่ง Service เข้าไปใน Controller ผ่านทาง Injector

การฉีดพึ่งพาใน AngularJS คืออะไร?

การฉีดพึ่งพา ใน AngularJS เป็นรูปแบบการออกแบบซอฟต์แวร์ที่ใช้การกลับกันของการควบคุมเพื่อแก้ไขการขึ้นต่อกัน จะตัดสินใจว่าส่วนประกอบต่างๆ ยึดถือการพึ่งพาของตนอย่างไร สามารถใช้ในขณะที่กำหนดส่วนประกอบหรือจัดทำบล็อกการรันและกำหนดค่าของโมดูล ช่วยให้คุณสามารถทำให้ส่วนประกอบต่างๆ สามารถนำมาใช้ใหม่ ทดสอบได้ และบำรุงรักษาได้

การผกผันของการควบคุม: หมายความว่าวัตถุไม่ได้สร้างวัตถุอื่นที่พวกเขาต้องพึ่งพาในการทำงาน แต่พวกเขาได้รับวัตถุเหล่านี้จากแหล่งภายนอกแทน นี่เป็นพื้นฐานของ AngularJS Dependency Injection โดยที่หากวัตถุหนึ่งขึ้นอยู่กับอีกวัตถุหนึ่ง วัตถุหลักไม่รับผิดชอบในการสร้างวัตถุที่ขึ้นต่อกันแล้วใช้วิธีการของมัน แหล่งที่มาภายนอก (ซึ่งใน AngularJS คือเฟรมเวิร์ก AngularJS เอง) จะสร้างวัตถุที่ขึ้นต่อกันและมอบให้กับวัตถุต้นทางเพื่อการใช้งานต่อไป

⚠️ หมายเหตุเกี่ยวกับเวอร์ชัน: การสนับสนุน AngularJS สิ้นสุดลงในเดือนมกราคม 2022โดยไม่มีการแก้ไขช่องโหว่ด้านความปลอดภัย Angular รุ่นใหม่ใช้การฉีดผ่านผู้ให้บริการ @Injectable และ ฉีด()โค้ดด้านล่างนี้จะถูกเก็บไว้เป็นข้อมูลในอดีต

ก่อนอื่นเรามาทำความเข้าใจก่อนว่าการพึ่งพาคืออะไร

คลาสโมเดลที่ขึ้นอยู่กับฐานข้อมูล โดยมีการฉีดเซอร์วิสเข้าไปเพื่อดึงข้อมูล

แผนภาพด้านบนแสดงตัวอย่างการฉีดการพึ่งพา AngularJS แบบง่าย ๆ ของกิจวัตรประจำวันในการเขียนโปรแกรมฐานข้อมูล

  • กล่อง 'Model' แสดงถึง "คลาส Model" ซึ่งปกติจะสร้างขึ้นเพื่อโต้ตอบกับฐานข้อมูล ดังนั้นตอนนี้ฐานข้อมูลจึงกลายเป็นสิ่งที่ต้องมีเพื่อให้ "คลาส Model" ทำงานได้
  • ด้วยการฉีดขึ้นต่อกัน เราสร้างบริการเพื่อดึงข้อมูลทั้งหมดจากฐานข้อมูลและเข้าสู่คลาสโมเดล

ในส่วนที่เหลือของบทเรียนนี้ เราจะมาดูเรื่องการฉีดการพึ่งพา (dependency injection) และวิธีการดำเนินการดังกล่าวกัน AngularJS.

คอมโพเนนต์ใดบ้างที่สามารถฉีดเข้าไปเป็น Dependency ใน AngularJS ได้

ใน AngularJS การนำเข้า dependency จะทำโดยใช้ "injectable factory method" หรือ "constructor function"

ส่วนประกอบเหล่านี้สามารถแทรกด้วยส่วนประกอบ "บริการ" และ "คุณค่า" เป็นการพึ่งพาได้ เราได้เห็นสิ่งนี้ในหัวข้อก่อนหน้านี้กับบริการ $http

AngularJS โมดูล ลงทะเบียนวัตถุที่ฉีดได้ผ่านสูตรห้าสูตร

Recipe สิ่งที่มันบันทึกไว้
ความคุ้มค่า อ็อบเจ็กต์ที่พร้อมใช้งาน ซึ่งมองไม่เห็นในบล็อกการกำหนดค่า
โรงงาน ฟังก์ชันที่มีค่าส่งคืนเป็นแบบฉีด (injection)
บริการ คอนสตรัคเตอร์ที่ถูกสร้างขึ้นเพียงครั้งเดียวด้วยคำสั่ง new
ผู้จัดหา สูตรที่ปรับแต่งได้ซึ่งแสดงค่า $get
คงที่ ค่าคงที่ที่อ่านได้ในบล็อกการกำหนดค่า

เราได้เห็นแล้วว่าบริการ $http สามารถใช้ภายใน AngularJS เพื่อรับข้อมูลจาก MySQL หรือ MS SQL ฐานข้อมูลเซิร์ฟเวอร์ผ่าน PHP โปรแกรมประยุกต์บนเว็บ

โดยปกติบริการ $http จะถูกกำหนดจากภายในตัวควบคุมในลักษณะต่อไปนี้

sampleApp.controller ('AngularJSController', function ($scope, $http)

ตอนนี้เมื่อมีการกำหนดบริการ $http ในคอนโทรลเลอร์ดังที่แสดงด้านบน หมายความว่าตอนนี้คอนโทรลเลอร์ต้องพึ่งพาบริการ $http

ดังนั้นเมื่อมีการดำเนินการโค้ดข้างต้น AngularJS จะดำเนินการตามขั้นตอนต่อไปนี้

  1. ตรวจสอบว่ามีการสร้างอินสแตนซ์ “$http service” แล้วหรือยัง เนื่องจากตอนนี้ "ตัวควบคุม" ของเราขึ้นอยู่กับ "บริการ $http" วัตถุของบริการนี้จึงต้องเปิดให้ผู้ควบคุมของเราใช้งานได้
  2. หาก AngularJS พบว่าบริการ $http ไม่ได้สร้างอินสแตนซ์ AngularJS จะใช้ฟังก์ชัน 'factory' เพื่อสร้างวัตถุ $http
  3. จากนั้น ตัวฉีด (injector) ภายใน AngularJS จะส่งอินสแตนซ์ของบริการ $http ไปยังคอนโทรลเลอร์ของเราเพื่อประมวลผลต่อไป

แบบฟอร์มคำอธิบายประกอบ: คำอธิบายโดยนัย อ่านชื่อพารามิเตอร์ ดังนั้นการย่อขนาดโค้ดจึงทำให้ใช้งานไม่ได้ แต่การใช้สัญลักษณ์อาร์เรย์แบบอินไลน์และ $inject ยังคงใช้งานได้ ng-strict-di บน ng-app ปฏิเสธการใช้ annotation โดยปริยาย

เมื่อการพึ่งพาถูกแทรกเข้าไปในคอนโทรลเลอร์ของเราแล้ว ตอนนี้เราสามารถเรียกใช้ฟังก์ชันที่จำเป็นภายในบริการ $http เพื่อการประมวลผลต่อไปได้

ตัวอย่างของการพึ่งพาการฉีด

ในตัวอย่างนี้ เราจะเรียนรู้วิธีใช้ dependencyjection ใน AngularJS

การฉีดพึ่งพาสามารถทำได้ 2 วิธี

  1. ประการหนึ่งคือผ่าน “องค์ประกอบคุณค่า”
  2. อีกประการหนึ่งคือผ่าน "บริการ"

มาดูการใช้งานทั้งสองวิธีโดยละเอียด

1) องค์ประกอบคุณค่า

แนวคิดนี้ตั้งอยู่บนพื้นฐานของการสร้างสิ่งง่ายๆ Javaต้นฉบับ วัตถุและส่งต่อไปยังคอนโทรลเลอร์เพื่อประมวลผลต่อไป

ดำเนินการโดยใช้สองขั้นตอนด้านล่าง

ขั้นตอน 1) สร้าง Javaสร้างอ็อบเจ็กต์สคริปต์โดยใช้คอมโพเนนต์ค่า และแนบเข้ากับโมดูล AngularJS หลักของคุณ

ส่วนประกอบค่าจะรับพารามิเตอร์สองตัว ตัวหนึ่งคือคีย์ และอีกตัวคือค่าของคีย์นั้น Javaอ็อบเจ็กต์สคริปต์ที่ถูกสร้างขึ้น

ขั้นตอน 2) เข้า Javaวัตถุสคริปต์จาก ตัวควบคุม AngularJS

<! DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Event Registration</title>

</head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body ng-app="sampleApp">

<div ng-controller="AngularJSController">
    <h3> Guru99 Global Event</h3>
    {{ID}}
</div>
<script>

    var sampleApp = angular.module('sampleApp',[]);
    sampleApp.value("TutorialID", 5);
    sampleApp.controller('AngularJSController', function($scope,TutorialID) {
        $scope.ID =TutorialID;
    });

</script>
</body>
</html>

โค้ดด้านบนดำเนินการตามขั้นตอนด้านล่าง

  1. sampleApp.value("TutorialID", 5);

    ฟังก์ชัน value ของโมดูล AngularJS ถูกใช้เพื่อสร้างคู่คีย์-ค่าชื่อ “TutorialID” โดยมีค่าเป็น “5”

  2. sampleApp.controller('AngularJSController', function ($scope,TutorialID)

    ขณะนี้ตัวแปร TutorialID สามารถเข้าถึงได้โดยคอนโทรลเลอร์ในฐานะพารามิเตอร์ฟังก์ชัน

  3.  $scope.ID =TutorialID;

    ค่าของ TutorialID ซึ่งคือ 5 กำลังถูกกำหนดให้กับตัวแปรอีกตัวหนึ่งชื่อ ID ใน $ขอบเขต วัตถุนี้ทำขึ้นเพื่อให้สามารถส่งค่า 5 จากคอนโทรลเลอร์ไปยังวิวได้

  4. {{ID}}

    พารามิเตอร์ ID จะแสดงเป็นนิพจน์ในมุมมอง ดังนั้นผลลัพธ์ของ '5' จะแสดงบนเพจ

เมื่อรันโค้ดข้างต้นแล้ว จะได้ผลลัพธ์ดังนี้

การแสดงผลในเบราว์เซอร์ของตัวอย่างส่วนประกอบค่าจะแสดง TutorialID ที่ถูกแทรกเข้าไปเป็น 5

2) บริการ

บริการถูกกำหนดให้เป็นแบบซิงเกิลตัน Javaวัตถุสคริปต์ประกอบด้วยชุดฟังก์ชันที่คุณต้องการเปิดเผยและฉีดลงในตัวควบคุมของคุณ

ตัวอย่างเช่น “$http” เป็นบริการใน AngularJS ซึ่งเมื่อนำไปใช้ในคอนโทรลเลอร์ของคุณ จะให้ฟังก์ชันที่จำเป็นต่างๆ

( get() , query() , บันทึก() , ลบ(), ลบ() )

จากนั้นคุณสามารถเรียกใช้ฟังก์ชันเหล่านี้ได้จากคอนโทรลเลอร์ของคุณตามลำดับ

มาดูตัวอย่างง่ายๆ ว่าคุณสามารถสร้างบริการของคุณเองได้อย่างไร เราจะสร้างบริการการบวกแบบง่ายๆ ซึ่งจะบวกเลขสองตัว

<! DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Event Registration</title>

</head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<h3> Guru99 Global Event</h3>

<div ng-app = "mainApp" ng-controller = "DemoController">
    <p>Result: {{result}}</p>
</div>
<script>
    var mainApp = angular.module("mainApp", []);

    mainApp.service('AdditionService', function(){
        this.ADDITION = function(a,b) {
            return a+b;
        }
    });

    mainApp.controller('DemoController', function($scope, AdditionService) {

            $scope.result = AdditionService.ADDITION(5,6);
    });
</script>

</body>
</html>

ในตัวอย่างข้างต้น ดำเนินการตามขั้นตอนต่อไปนี้

  1.  mainApp.service('AdditionService', function()

    ในที่นี้เรากำลังสร้างบริการใหม่ชื่อ 'AdditionService' โดยใช้พารามิเตอร์บริการของโมดูล AngularJS หลักของเรา

  2.  this.ADDITION = function(a,b)

    ในที่นี้เรากำลังสร้างฟังก์ชันใหม่ชื่อ ADDITION ภายในเซอร์วิสของเรา ซึ่งหมายความว่าเมื่อ AngularJS สร้างอินสแตนซ์ของ AdditionService ภายในคอนโทรลเลอร์ของเรา เราจะสามารถเข้าถึงฟังก์ชัน 'ADDITION' ได้ ในคำจำกัดความของฟังก์ชันนี้ เราระบุว่าฟังก์ชันนี้รับพารามิเตอร์สองตัว คือ a และ b

  3.  return a+b;

    ในส่วนนี้ เรากำลังกำหนดส่วนเนื้อหาของฟังก์ชัน ADDITION ซึ่งมีหน้าที่บวกค่าพารามิเตอร์และส่งคืนค่าที่บวกแล้ว

  4.  mainApp.controller('DemoController', function($scope, AdditionService)

    นี่คือขั้นตอนหลักที่เกี่ยวข้องกับการฉีดการพึ่งพา (dependency injection) ในการกำหนดคอนโทรลเลอร์ของเรา ตอนนี้เราได้อ้างอิงถึงบริการ 'AdditionService' แล้ว เมื่อ AngularJS เห็นสิ่งนี้ มันจะสร้างอ็อบเจ็กต์ประเภท 'AdditionService' ขึ้นมา

  5.  $scope.result = AdditionService.ADDITION(5,6);

    ขณะนี้เรากำลังเข้าถึงฟังก์ชัน 'ADDITION' ซึ่งถูกกำหนดไว้ในบริการของเรา และกำหนดค่าให้กับอ็อบเจ็กต์ $scope ของคอนโทรลเลอร์

นี่คือตัวอย่างง่ายๆ ของวิธีที่เราสามารถกำหนดบริการของเราและแทรกฟังก์ชันการทำงานของบริการนั้นภายในตัวควบคุมของเรา

คำถามที่พบบ่อย

`service` จะสร้างอินสแตนซ์ของคอนสตรัคเตอร์ของคุณเพียงครั้งเดียวด้วย `new` ส่วน `factory` จะรันฟังก์ชันของคุณและฉีดค่าที่ฟังก์ชันนั้นส่งคืนเข้ามา ดังนั้นค่าพื้นฐานก็สามารถใช้งานได้เช่นกัน

ค่าคงที่เข้าถึงบล็อกการกำหนดค่าและไม่ตอบสนองต่อตัวตกแต่ง ค่าจะถูกลงทะเบียนหลังจากผู้ให้บริการ ดังนั้นบล็อกการกำหนดค่าจึงไม่สามารถมองเห็นได้

แอปพลิเคชันแต่ละตัวจะมีตัวฉีด (injector) หนึ่งตัว ทำหน้าที่แก้ไขชื่อ ส่งคืนอินสแตนซ์ผ่านฟังก์ชัน get และเรียกใช้ฟังก์ชันพร้อมกับส่วนประกอบที่เกี่ยวข้องผ่านฟังก์ชัน invoke

ตัวย่อชื่อพารามิเตอร์จะเปลี่ยนชื่อพารามิเตอร์ให้เหลือเพียงตัวอักษรเดียว ดังนั้นตัวฉีดพารามิเตอร์จึงค้นหาผู้ให้บริการที่มีชื่อว่า "a" การระบุชื่อพารามิเตอร์อย่างชัดเจนจะช่วยรักษาชื่อจริงเอาไว้

ลงทะเบียนผู้ให้บริการ ระบุรายชื่อผู้ให้บริการ โมดูล ในอาร์เรย์การพึ่งพา และตรวจสอบการสะกดคำ โค้ดที่ถูกย่อขนาดโดยไม่มีคำอธิบายประกอบก็ทำให้เกิดปัญหานี้เช่นกัน

@Injectable providers บวกกับพารามิเตอร์ของคอนสตรัคเตอร์ หรือ ฉีด() ฟังก์ชันภายในตัวเริ่มต้นฟิลด์ ตัวฉีดแบบลำดับชั้นจะประมวลผลโทเค็นทุกตัว

เครื่องมือการเรียนรู้ของเครื่องจักร tracทุกชื่อที่ถูกแทรกเข้าไป ตัวควบคุม และบริการต่างๆ จัดอันดับการเชื่อมโยง และระบุผู้ให้บริการที่มีความเสี่ยง วิศวกรตรวจสอบผลลัพธ์

นักบิน GitHub สร้างอาร์เรย์แบบอินไลน์และคำอธิบายประกอบ $inject ตามคำขอ และ agentic จะทำการสแกนทั้งโฟลเดอร์ Revคำอธิบายประกอบที่สร้างโดย iew

สรุปโพสต์นี้ด้วย: