Επεξήγηση γωνιακών υπηρεσιών και έγχυσης εξάρτησης

Υπηρεσίες και εγχυτήρες

Τα στοιχεία είναι υπεύθυνα για τα δεδομένα που αποδίδονται στο πρότυπο. Η χρήση εξωτερικών υπηρεσιών μπορεί να απλοποιήσει αυτήν την ευθύνη. Επιπλέον, η ενθυλάκωση του εξωτερικού είναι πολύ πιο εύκολο να διατηρηθεί.

Η ανάθεση πάρα πολλών αρμοδιοτήτων σε ένα στοιχείο μπορεί να περιπλέξει την κατηγορία συστατικών. Και τι γίνεται αν αυτές οι ευθύνες εφαρμόζονται σε διάφορα στοιχεία; Η αντιγραφή και επικόλληση μιας τέτοιας λογικής είναι εξαιρετικά κακή πρακτική. Τυχόν μελλοντικές αλλαγές στη λογική θα ήταν πιο δύσκολο να εφαρμοστούν και να δοκιμαστούν.

Γωνιακό σκοπό να περιορίσει αυτό το ζήτημα με υπηρεσίες και εξάρτηση εξάρτηση. Και οι δύο έννοιες συνεργάζονται για να παρέχουν λειτουργική αρθρωτή .

Τα στοιχεία δεν χρειάζεται να παρέχουν καμία ξένη πληροφορία. Μια υπηρεσία εισάγει ό, τι χρειάζεται για να λειτουργήσει για λογαριασμό των στοιχείων που παρέχει . Τα στοιχεία πρέπει μόνο να δημιουργήσουν την υπηρεσία. Από εκεί εξυπηρετούν τις δικές τους ανάγκες με την παρουσία της υπηρεσίας.

Όσον αφορά τις δοκιμές και τη μελλοντική τροποποίηση, όλη η λογική είναι σε ένα μέρος. Η υπηρεσία δημιουργείται από την πηγή της. Οι δοκιμές και οι τροποποιήσεις στην πηγή ισχύουν οπουδήποτε γίνεται η ένεση της υπηρεσίας.

Εισαγωγή στις υπηρεσίες

Η υπηρεσία είναι ένας τύπος σχήματος που διατίθεται στο Angular. Είναι να παράγεται από τη διασύνδεση γραμμής εντολών (CLI): ng generate service [name-of-service]. Αντικαταστήστε [name-of-service]με ένα προτιμώμενο όνομα. Η εντολή CLI αποδίδει τα ακόλουθα.

import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class LoggerService { constructor() { } }

Η λογική μιας υπηρεσίας είναι ξεχωριστή στην κατηγορία της. Η γωνιακή ερμηνεία μιας κατηγορίας ως ενέσιμης υπηρεσίας που βασίζεται στον @Injectableδιακοσμητή. Οι ενέσιμες υπηρεσίες πρέπει να εγγραφούν σε έναν εγχυτήρα.

Το στοιχείο δημιουργεί μια υπηρεσία ενώ ο εγχυτής παρέχει αυτήν την παρουσία. Συνεχίστε να διαβάζετε στην επόμενη ενότητα για περισσότερα σχετικά με τους εγχυτήρες.

Το @Injectableπεδίο μεταδεδομένων providedIn: ‘root’στοχεύει τη ριζική ενότητα της τρέχουσας εφαρμογής ( app.module.ts). Καταχωρίζει την υπηρεσία με τον εγχυτήρα της μονάδας έτσι ώστε να μπορεί να κάνει την υπηρεσία σε οποιοδήποτε από τα παιδιά της.

Οι εγχυτήρες είναι τα δομικά στοιχεία του συστήματος έγχυσης εξάρτησης της Angular. Οι εγχυτήρες είναι ένα καλό μέρος για να εστιάσετε την προσοχή σας προτού συνεχίσετε με τις υπηρεσίες.

Εγχυτήρες

Μια εφαρμογή, αρχίζει με app.module.ts, περιέχει μια ιεραρχία εγχυτήρων. Υπάρχουν δίπλα σε κάθε ενότητα και στοιχείο στο δέντρο εφαρμογών.

Ιεραρχία εφαρμογών

Οι πράσινοι κύκλοι υποδεικνύουν εγχυτήρες. Παρέχουν υπηρεσίες παρουσίας σε στοιχεία συστατικών. Ανάλογα με το ποιος εγχυτής έχει καταχωρηθεί μια υπηρεσία, ενδέχεται να είναι ή να μην είναι διαθέσιμη σε ένα στοιχείο.

Οι υπηρεσίες που έχουν εγγραφεί στη ρίζα της εφαρμογής ( app.module.ts) είναι διαθέσιμες σε όλα τα στοιχεία. Ένας εγχυτήρας για ένα εξάρτημα ενδέχεται να μην έχει καταχωρηθεί συγκεκριμένη υπηρεσία. Εάν συμβαίνει αυτό και το εξάρτημα ζητήσει την παρουσία του, ο εγχυτής θα αναβάλει τον γονέα του. Αυτή η τάση συνεχίζεται έως ότου βρεθεί είτε στον εγχυτήρα ρίζας είτε στην υπηρεσία.

Κοιτάζοντας το διάγραμμα, ας πούμε ότι μια υπηρεσία εγγράφεται στον εγχυτήρα του σημείου Β. Όλα τα εξαρτήματα στο σημείο Γ και κάτω δεν θα μπορούν να έχουν πρόσβαση στην υπηρεσία που είναι καταχωρημένη στον εγχυτήρα Β. Οι εγχυτήρες δεν θα αναβάλουν ποτέ τα παιδιά τους για μια παρουσία υπηρεσίας.

Ενεση εξάρτησης

Υπάρχουν πολλοί τρόποι για να καταχωρήσετε μια υπηρεσία με τους εγχυτήρες μιας εφαρμογής.

Το providedIn: ‘root’πεδίο μεταδεδομένων @Injectableπαρέχει την πιο συνιστώμενη προσέγγιση. Αυτό το πεδίο μεταδεδομένων κυκλοφόρησε με το Angular 6.

Όπως αναφέρθηκε προηγουμένως, providedIn: ‘root’καταχωρεί μια υπηρεσία στον εγχυτήρα της μονάδας ρίζας. Αυτό είναι άμεσα εφαρμόσιμο σε ολόκληρη την εφαρμογή.

Η καινοτομία providedIn: ‘root’είναι ανατριχιαστική . Εάν η υπηρεσία δεν χρησιμοποιείται παρά την εγγραφή της, διαγράφεται από την εφαρμογή στο χρόνο εκτέλεσης. Με αυτόν τον τρόπο δεν καταναλώνει πόρους.

Οι άλλοι δύο τρόποι είναι πιο άμεσοι και παραδοσιακοί. Δυστυχώς, δεν προσφέρουν ανακίνηση.

Μια υπηρεσία μπορεί να εγγραφεί με οποιονδήποτε εγχυτήρα κατά μήκος του συστατικού δέντρου. Εισάγετε την υπηρεσία ως πάροχος στον @Componentτομέα των μεταδεδομένων: providers: []. Η υπηρεσία είναι διαθέσιμη στο συστατικό και στα παιδιά του

Στην τρίτη στρατηγική εγγραφής, τα providers: []μεταδεδομένα υπάρχουν ως δικό τους πεδίο στον @NgModuleδιακοσμητή. Η υπηρεσία είναι άμεση από το module έως το υποκείμενο δέντρο στοιχείων.

Θυμηθείτε ότι σε αντίθεση με το providedIn: ‘root’, η @NgModuleεγγραφή δεν προσφέρει αναταραχή. Και οι δύο στρατηγικές είναι κατά τα άλλα ταυτόσημες. Μόλις εγγραφεί μια υπηρεσία @NgModule, καταναλώνει πόρους ακόμη και αν δεν χρησιμοποιηθεί από την εφαρμογή.

Οι υπηρεσίες συνεχίστηκαν

Το γράψιμο μιας πραγματικής υπηρεσίας έρχεται στη συνέχεια. Για να ανακεφαλαιώσετε, οι υπηρεσίες χειρίζονται ορισμένες λειτουργίες για λογαριασμό των στοιχείων της εφαρμογής.

Οι υπηρεσίες υπερέχουν στο χειρισμό κοινών λειτουργιών. Διαθέτουν εξαρτήματα την ευθύνη κάνοντας αυτό. Εξοικονομεί χρόνο χωρίς να χρειάζεται να ξαναγράψετε κοινές λειτουργίες σε πολλά στοιχεία. Είναι επίσης πιο δοκιμή, επειδή ο κωδικός είναι σε ένα μέρος. Οι αλλαγές πρέπει να γίνουν μόνο σε ένα μέρος χωρίς να χρειάζεται να κάνετε αναζήτηση αλλού.

Χρησιμοποιήστε Θήκες

Μερικά παραδείγματα προχωρούν σε μεγάλο βαθμό στην πλήρη κατανόηση των υπηρεσιών.

  • αρχεία καταγραφής κονσόλας
  • Αιτήματα API

Και τα δύο είναι κοινά στις περισσότερες εφαρμογές. Η παροχή υπηρεσιών για τη διαχείριση αυτών των λειτουργιών θα μειώσει την πολυπλοκότητα των στοιχείων.

Αρχεία καταγραφής κονσόλας

Αυτό το παράδειγμα συσσωρεύεται από τον βασικό @Injectableσκελετό. Ο σκελετός είναι διαθέσιμος μέσω της εκτέλεσης του CLI ( ng generate service [name-of-service]]).

// services/logger.service.ts import { Injectable } from '@angular/core'; interface LogMessage { message:string; timestamp:Date; } @Injectable({ providedIn: 'root' }) export class LoggerService { callStack:LogMessage[] = []; constructor() { } addLog(message:string):void { // prepend new log to bottom of stack this.callStack = [{ message, timestamp: new Date() }].concat(this.callStack); } clear():void { // clear stack this.callStack = []; } printHead():void  printLog():void { // print bottom to top of stack on screen this.callStack.reverse().forEach((logMessage) => console.log(logMessage)); } getLog():LogMessage[] { // return the entire log as an array return this.callStack.reverse(); } }

Το LoggerService εγγράφεται στο root module μέσω των @Injectableμεταδεδομένων. Έτσι, μπορεί να δημιουργηθεί στο app.component.html.

// app.component.ts import { Component, OnInit } from '@angular/core'; import { LoggerService } from './services/logger.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html' }) export class AppComponent implements OnInit { logs:object[] = []; constructor(private logger:LoggerService) { } updateLog():void { this.logger.printHead(); this.logs = this.logger.getLog(); } logMessage(event:any, message:string):void { event.preventDefault(); this.logger.addLog(`Message: ${message}`); this.updateLog(); } clearLog():void { this.logger.clear(); this.logs = []; } ngOnInit():void { this.logger.addLog(“View Initialized”); this.updateLog(); } }

Το πρότυπο HTML παρέχει περαιτέρω πληροφορίες σχετικά με τη χρήση του LoggerService από το στοιχείο.

Log Example

SUBMIT

Complete Log

CLEAR
  • {{ logs.length - i }} > {{ log.message }} @ {{ log.timestamp }}

Αυτό έχει την αίσθηση μιας εφαρμογής ToDo. Μπορείτε να καταγράψετε μηνύματα και να διαγράψετε το αρχείο καταγραφής μηνυμάτων. Φανταστείτε εάν όλη η λογική από την υπηρεσία μεταφέρθηκε στο AppComponent! Θα περιπλέξει τον κώδικα. Το LoggerService διατηρεί τον κωδικό που σχετίζεται με το αρχείο καταγραφής ενθυλακωμένο από την βασική κατηγορία AppComponent

Λήψη αιτημάτων

Here is one more example worth playing around with. This example is possible thanks to typicode’s JSONPlaceholder1. The API is public and free to use.

import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; // //jsonplaceholder.typicode.com // public API created by typicode @ //github.com/typicode interface Post { userId:number; id:number; title:string; body:string; } @Injectable({ providedIn: 'root' }) export class PlaceholderService { constructor(private http:HttpClient) { } getPosts():Observable { return this.http.get('//jsonplaceholder.typicode.com/posts'); } getPost(id:number):Observable { return this.http.get(`//jsonplaceholder.typicode.com/posts/${id}`); } }

This is more of a stand-alone piece than a fully fleshed out example. Fetch requests tend to work better as an injectable service. The alternative is an over-complicated component. The injected class subscribes to what the PlaceholderService pre-configures.

Conclusion

Services and dependency injection are very useful together. They allow developers to encapsulate common logic and inject across multiple different components. This alone is a massive convenience for any future maintenance.

Injectors work as intermediaries. They mediate between instantiating components and a reservoir of registered services. Injectors offer these instantiable services to their branch children.

Δείτε τους επόμενους συνδέσμους για περισσότερες πληροφορίες σχετικά με τις υπηρεσίες και την εξάρτηση.

Πόροι για γωνιακό

  • Γωνιακή τεκμηρίωση
  • Εισαγωγή στην ένεση γωνιακής εξάρτησης
  • Τι είναι η ένεση εξάρτησης και πότε να τη χρησιμοποιήσετε
  • Καλύτερα παραδείγματα γωνιακού κώδικα
  • Γωνιακό αποθετήριο GitHub
  • Ενεση εξάρτησης
  • Εισαγωγή στις υπηρεσίες και DI