Για αρχάριους, μπορεί κάποιος να εξηγήσει με σαφήνεια τη διαφορά μεταξύ Υπηρεσίας, Εργοστασίου και Παροχέα στο AngularJS;


Απάντηση 1:

AngularJS: Διαφορά μεταξύ υπηρεσίας έναντι προμηθευτή έναντι εργοστασίου

Αν ψάχνετε για αυτό, πιθανώς επειδή προσπαθείτε να καταλάβετε ποια είναι η σωστή για να χρησιμοποιήσετε. Ή γιατί έχετε συναντήσει τους τρεις από αυτούς και προσπαθείτε να προσδιορίσετε τη διαφορά επειδή μοιάζουν παρόμοια.

Αν νομίζετε ότι είναι παρόμοια - έχετε δίκιο. Είναι πολύ παρόμοια. Στην πραγματικότητα, είναι όλα τα ίδια.

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

Ο Παροχέας

Πρόκειται να δημιουργήσουμε έναν παροχέα που επιστρέφει μια τιμή και απλά να εμφανίσει αυτήν την τιμή, θα κάνατε αυτό:

var mod = angular.module ("MyModule", []); mod.provider ("myProvider", λειτουργία () {this. $ get = function () {επιστροφή "Η τιμή μου";};}); mod.controller ("MyController", λειτουργία (myProvider) {console.log ("MyController - myProvider:" + myProvider);}); ΕΞΟΔΟΣ ΚΑΤΑΣΚΕΥΗΣ MyController - myProvider: Η αξία μου

Ένα ενεργό διαδραστικό παράδειγμα μπορεί να βρεθεί στο: JS Fiddle.

Εκεί, έτσι ένας "πάροχος" στον πυρήνα ας σας "παράσχει" μια αξία. Αυτή η αξία θα μπορούσε να είναι οτιδήποτε. Σε αυτή την περίπτωση είναι μια συμβολοσειρά με τιμή "My Value", αλλά θα μπορούσε εύκολα να ήταν μια συνάρτηση ή ένα αντικείμενο.

Σημείωση σε άλλα δείγματα κώδικα Πάω να αποκλείσω το την ετικέτα και τον ορισμό του mod για το σκοπό της διατήρησης των αποσπασμάτων κώδικα σύντομα και προς το σημείο.

Το γωνιακό μόνο παίρνει την αξία μία φορά - ποτέ

Σημειώστε ότι το γωνιακό μόνο "παίρνει" τη τιμή μία φορά, ανεξάρτητα από το πόσες φορές χορηγείται ο παροχέας. Αυτό σημαίνει ότι ονομάζεται $ get () μόνο μία φορά, αποθηκεύει την τιμή που παρέχεται από το $ get (), και σας δίνει την ίδια αποθηκευμένη αξία κάθε φορά.

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

mod.provider ("myProvider", λειτουργία () {this. $ get = function () {console.log ("MyProviderFunction. $ get ()"); }); mod.controller ("MyController", λειτουργία (myProvider) {console.log ("MyController - myProvider:" + myProvider);}); mod.controller ("MyController2", λειτουργία (myProvider) {// ADDED αυτόν τον ελεγκτή console.log ("MyController2 - myProvider:" + myProvider);}); ΕΙΣΟΔΟΣ ΕΞΟΔΟΥ ΜΟΥΣΕΡΑΣ MyProviderFunction. Ονομάζεται $ get (). MyController - myProvider: Η αξία μου MyController2 - myProvider: Η αξία μου

Άνοιγμα στο JS Fiddle

Όπως βλέπετε, η λειτουργία $ get () κλήθηκε μόνο μία φορά.

Σημειώστε ότι γράψαμε μια δέσμη κώδικα για τον πάροχο μόνο για το σκοπό της δημιουργίας μιας μεθόδου που ονομάζεται $ get (). Γιατί όχι αντί να δίνουμε μια γωνιακή συνάρτηση που ορίζει μια άλλη συνάρτηση, γιατί όχι μόνο να της δώσουμε τη λειτουργία που θέλουμε να τρέξουμε απευθείας; Λοιπόν μπορείτε, αυτό είναι που το Angular καλεί ένα εργοστάσιο.

Ενα εργοστάσιο

Με ένα εργοστάσιο απλά δίνετε το σώμα λειτουργίας για τη μέθοδο $ get και το Angular κάνει τα υπόλοιπα. Παρακάτω είναι αυτό που φαίνεται ο νέος κώδικας, όπως θα δείτε ότι συμπεριφέρεται ακριβώς το ίδιο.

mod.factory ("myProvider", λειτουργία () {// CHANGED "provider" σε "εργοστασιακό" console.log ("Εργοστασιακή λειτουργία που ονομάζεται"), επιστροφή "My Value"; mod.controller ("MyController", λειτουργία (myProvider) {console.log ("MyController - myProvider:" + myProvider);}); mod.controller ("MyController2", λειτουργία (myProvider) {console.log ("MyController2 - myProvider:" + myProvider);}); ΕΞΟΔΟΣ ΚΑΤΑΣΚΕΥΗΣ Εργοστασιακή λειτουργία που καλείται. MyController - myProvider: Η αξία μου MyController2 - myProvider: Η αξία μου

Άνοιγμα στο JS Fiddle

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

Μέχρι τώρα έχουμε επιστρέψει μια απλή τιμή συμβολοσειράς, αλλά στην πράξη αυτό που θέλουμε πιθανώς να επιστρέψουμε τον περισσότερο χρόνο είναι ένα αντικείμενο. Λοιπόν αυτό δεν θα αλλάξει το παράδειγμά μας πάρα πολύ, μπορούμε πολύ εύκολα να ανταλλάξουμε το string που επιστρέφουμε με ένα αντικείμενο αντ 'αυτού.

Για παράδειγμα, ας το κάνουμε αυτό επιστρέφοντας ένα αντικείμενο που περιέχει μια συνάρτηση που ονομάζεται getValue (). Τώρα υπάρχουν αρκετοί τρόποι με τους οποίους μπορείτε να δημιουργήσετε ένα αντικείμενο στο JavaScript, πρόκειται να χρησιμοποιήσουμε την προσέγγιση "Constructor αντικειμένων" όπου δημιουργούμε μια συνάρτηση που καλύπτει ένα αντικείμενο με ιδιότητες και λειτουργίες και χρησιμοποιεί τη νέα λέξη-κλειδί για να το δημιουργήσει.

λειτουργία MyObject () {// ADDED κατασκευαστής αντικειμένων this.getValue = function () {επιστροφή "Η τιμή μου"; }, } mod.factory ("myProvider", συνάρτηση () {console.log ("Εργοστασιακή λειτουργία που ονομάζεται"), επιστροφή νέου MyObject (); // CREATE μια εμφάνιση του αντικειμένου μας))? mod.controller ("MyController", λειτουργία (myProvider) {console.log ("MyController - myProvider:" + myProvider.getValue ()); // CHANGED για κλήση getValue ()}); mod.controller ("MyController2", συνάρτηση (myProvider) {console.log ("MyController2 - myProvider:" + myProvider.getValue ()); // CHANGED για να καλέσετε getValue ()}); ΕΞΟΔΟΣ ΚΑΤΑΣΚΕΥΗΣ Εργοστασιακή λειτουργία που καλείται. MyController - myProvider: Η αξία μου MyController2 - myProvider: Η αξία μου

Άνοιγμα στο JS Fiddle

Τώρα θέλω να κάνω ένα μικρό τσίμπημα σε αυτό επειδή θα οδηγήσει ωραία στην επόμενη έννοια. Στο παράδειγμά μας δημιουργούμε τη συνάρτηση "Object Constructor" MyObject (), αλλά από τη στιγμή που το δημιουργούμε μόνο σε ένα σημείο μπορούμε να χρησιμοποιήσουμε αντ 'αυτού ανώνυμη λειτουργία.

Αυτό είναι ένα πολύ μικρό τσίμπημα. Αντί αυτού:

λειτουργία MyObject () {this.getValue = function () {επιστροφή "Η τιμή μου"; }, } mod.factory ("myProvider", λειτουργία () {console.log ("Εργοστασιακή λειτουργία που ονομάζεται."), επιστροφή νέου MyObject ();});

Κάνουμε αυτό:

mod.factory ("myProvider", συνάρτηση () {console.log ("Εργοστασιακή λειτουργία που ονομάζεται."), επιστροφή νέας συνάρτησης () {// INLINED ο κατασκευαστής αντικειμένου μας this.getValue = function () {return "My Value"; }}}}}).

Έτσι το όλο θέμα τώρα μοιάζει με αυτό:

mod.factory ("myProvider", συνάρτηση () {console.log ("Εργοστασιακή λειτουργία που ονομάζεται."), επιστροφή νέας συνάρτησης () {// INLINED ο κατασκευαστής αντικειμένου μας this.getValue = function () {return "My Value"; }}}}}). mod.controller ("MyController", λειτουργία (myProvider) {console.log ("MyController - myProvider:" + myProvider.getValue ());}); mod.controller ("MyController2", λειτουργία (myProvider) {console.log ("MyController2 - myProvider:" + myProvider.getValue ());});

Άνοιγμα στο JS Fiddle

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

Στη διάθεσή σας

Εδώ είναι ο ίδιος κώδικας εκτός από τη χρήση μιας υπηρεσίας αντί ενός εργοστασίου.

mod.service ("myProvider", function () {// CHANGED "factory" σε "service" // ΣΗΜΕΙΩΣΗ ότι η μοναδική λειτουργία που περάσαμε είναι ο κατασκευαστής αντικειμένων πριν από αυτό.getValue = ·} ·}); mod.controller ("MyController", λειτουργία (myProvider) {console.log ("MyController - myProvider:" + myProvider.getValue ());}); mod.controller ("MyController2", λειτουργία (myProvider) {console.log ("MyController2 - myProvider:" + myProvider.getValue ());}); ΕΞΟΔΟΣ ΚΑΤΑΣΚΕΥΗΣ MyController - myProvider: Η αξία μου MyController2 - myProvider: Η αξία μου

Άνοιγμα στο JS Fiddle

Παροχέας vs Factory vs Service

Έτσι, συνοπτικά, ο πάροχος, το εργοστάσιο και η υπηρεσία είναι όλοι οι πάροχοι υπηρεσιών. Ένα εργοστάσιο είναι μια ειδική περίπτωση ενός παρόχου όταν το μόνο που χρειάζεστε στον παροχέα σας είναι μια συνάρτηση $ get (). Σας επιτρέπει να γράφετε με λιγότερο κώδικα. Μια υπηρεσία είναι μια ειδική περίπτωση ενός εργοστασίου όταν θέλετε να επιστρέψετε μια παρουσία ενός νέου αντικειμένου, με το ίδιο πλεονέκτημα να γράφετε λιγότερο κώδικα.

Πότε να χρησιμοποιείτε το ένα έναντι του άλλου;

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

mod.factory ("myProvider", λειτουργία () {console.log ("Εργοστασιακή λειτουργία που ονομάζεται."), επιστροφή νέου SomeMessageBoxClass ("προσαρμοσμένο όρισμα")?

Ένας από τους κύριους παράγοντες αποφασιστικότητας μεταξύ παρόχου και εργοστασίου είναι αν θέλετε να μπορείτε να διαμορφώσετε το αντικείμενο που δημιουργείται πριν να δημιουργηθεί. Κάνετε αυτό καλώντας module.config () και να πάρετε μια παρουσία στον ίδιο τον πάροχο (αντί του αντικειμένου που επέστρεψε ο πάροχος). Κάνετε αυτό προσθέτοντας τον "Παροχέα" στο τέλος του ονόματος του παροχέα σας όταν το εισάγετε.

Ακολουθεί ένα παράδειγμα για το πώς θα το κάνετε αυτό:

mod.provider ("myProvider", λειτουργία () {this.value = "Η τιμή μου", this.setValue = function (newValue) {this.value = newValue;}; αξία; }; }); mod.controller ("MyController", λειτουργία (myProvider) {console.log ("MyController - myProvider:" + myProvider);}); mod.config (λειτουργία (myProviderProvider) {// ADDED config section // Σημειώστε το επιπλέον επίθεμα "Provider" myProviderProvider.setValue ("Νέα τιμή")}}).

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

Αν θυμάστε πότε παρουσιάσαμε για πρώτη φορά τον προμηθευτή του εργοστασίου παραπάνω, δώσαμε το απλό παράδειγμα επιστροφής μιας τιμής συμβολοσειράς. Αυτό έμοιαζε έτσι:

mod.factory ("myProvider", λειτουργία () {επιστροφή "Η τιμή μου";});

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

mod.value ("myProvider", "Η τιμή μου").

Έτσι πότε θα χρησιμοποιούσατε το ένα έναντι του άλλου; Προφανώς θα χρησιμοποιούσατε τον εργοστασιακό παροχέα όταν θέλετε να υπολογίσετε την τιμή βάσει κάποιων άλλων δεδομένων, για παράδειγμα δεδομένα από έναν άλλο παροχέα τιμών ή από μια εξωτερική πηγή. Και / ή όταν θέλετε να υπολογίσετε την τιμή εάν και μόνο όταν το ζητήσετε για πρώτη φορά. Ορίστε μερικά παραδείγματα:

// Παράδειγμα όπου το εργοστάσιο εξαρτάται από έναν παροχέα "value" mod.value ("πολλαπλάσιο", 3). mod.factory ("τιμή", συνάρτηση (πολλαπλάσιο) {επιστροφή 10 * πολλαπλά;})? // Παράδειγμα όπου το εργοστάσιο εξαρτάται από τα εξωτερικά δεδομένα mod.factory ("τιμή", συνάρτηση (πολλαπλάσια) {var multiple = getDateFromExternalPage (), επιστροφή 10 * πολλαπλά,})?

Υποστήριξα ότι η αξία ήταν ο μόνος άλλος πάροχος; Λοιπόν, είπα ψέματα, υπάρχει ένα άλλο που είναι πολύ παρόμοιο με αξία με δύο μικρές διαφορές. Αυτός ο παροχέας ονομάζεται σταθερός.

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

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

Ακολουθεί ένα παράδειγμα:

mod.value ("myValue", "Πρώτη ανάθεση"). mod.value ("myValue", "Δεύτερη ανάθεση"). mod.constant ("myConstant", "Πρώτη ανάθεση"); mod.constant ("myConstant", "Δεύτερη εκχώρηση"); mod.controller ("MyController", λειτουργία (myValue, myConstant) {console.log ("myValue:" + myValue), console.log ("myConstant:" + myConstant)? ΕΞΟΔΟΣ ΚΑΤΑΣΚΕΥΗΣ myValue: Δεύτερη εκχώρηση myconstant: Πρώτη ανάθεση

Ακολουθεί μια περίληψη του πότε να χρησιμοποιείτε το καθένα:

αξία

Παρέχετε μια απλή γραμματική αξία.

mod.value ("myValue", 10).
    

συνεχής

Πρέπει να έχετε πρόσβαση σε αυτήν την τιμή κατά τη διάρκεια της φάσης διαμόρφωσης. (χρησιμοποιώντας το .config ())

mod.constant ("myValue", 10). mod.config (λειτουργία (myValue) {console.log (myValue);});

εργοστάσιο

Η αξία που παρέχετε πρέπει να υπολογιστεί βάσει άλλων δεδομένων.

mod.factory ("myFactory", λειτουργία () {επιστροφή 10;});
        

υπηρεσία

Επιστρέφετε ένα αντικείμενο με μεθόδους.

mod.service ("myService", συνάρτηση () {var name = "Bob"; this.setName = συνάρτηση (newName) {this.name = newName;}; });
        

προμηθευτής

Θέλετε να μπορείτε να διαμορφώσετε, κατά τη διάρκεια της φάσης διαμόρφωσης, το αντικείμενο που πρόκειται να δημιουργηθεί πριν δημιουργηθεί.

($) = () () () () () () Αυτή η συνάρτηση () () () {console.log ("Hi" + όνομα;};}}}}) · mod.config (λειτουργία (greeterProvider) {greeterProvider.setName ("John")?
        

Για να οδηγήσετε το σημείο στο σπίτι εδώ και τελευταία φορά, εδώ είναι μια εικόνα ενός παρόχου με τα εργοστάσια, την αξία και τα τμήματα υπηρεσιών που επισημαίνονται:


Απάντηση 2:

Εσωτερικά το AngularJS χρησιμοποιεί το εργοστάσιο για τη δημιουργία αντικειμένου υπηρεσίας και τη χρήση του παροχέα για τη δημιουργία εργοστασιακού αντικειμένου.

Ένα εργοστάσιο κάνει,

  1. Δημιουργήστε ένα Object / instanceConstruct / Initialize το δημιουργημένο αντικείμενο / instancereturn το δημιουργημένο αντικείμενο / instance

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

Κάτω από το παράδειγμα, μπορείτε να επιλέξετε ανάμεσα σε δύο πύλες πληρωμών, κάποιον που χρησιμοποιεί τον κωδικό / βιβλιοθήκη σας, η μέθοδος του εργοστασίου σας μπορεί να κάνει επιλογή αν θα δημιουργήσει το αντικείμενο Paypal ή Stripe. Αυτό είναι πολύ παρόμοιο με το Abstract Factory, οι χρήστες της υπηρεσίας πληρωμών δεν γνωρίζουν ποια υπηρεσία χρησιμοποιήθηκε για την πύλη πληρωμής.

var myModule = angular.module ('myModule', []); myModule.constant ("PaymentGatewayName", "Stripe"). // ή Paypal myModule.factory ('payService', λειτουργία (PaymentGatewayName) {var paymentService; // αποφασίζετε ποιο αντικείμενο να δημιουργήσετε με βάση τις επιχειρησιακές ανάγκες // StripeGateway και PaypalGateway είναι κλάσεις JavaScript // περιέχει συγκεκριμένη υλοποίηση της πύλης αν ( (Πληκτρολογίου PaymentGatewayName == "Stripe") {payService = new StripeGateway (); // προσαρμοσμένος κωδικός για την προετοιμασία της πύλης λωρίδας} άλλο (PaymentGatewayName == "Paypal") {payService = new PaypalGateway / προσαρμοσμένος κώδικας για την προετοιμασία της πληρωμής επιστροφής χρημάτωνService;});

Ένας κώδικας υπηρεσίας μοιάζει με αυτόν, παρατηρείτε μια λέξη-κλειδί "αυτή", δηλαδή, το αντικείμενο έχει ήδη δημιουργηθεί για εσάς από το Angular Core, δεν δημιουργείτε πλέον έλεγχο αντικειμένων.

var myModule = angular.module ('myModule', []); myModule.service ('Cache', λειτουργία () {var localVariable = ""; // δεν είναι δυνατή η πρόσβαση εκτός αυτής.cacheSize = 5; // 5 MB this.objectsSize = 1000; // max 1000 αντικείμενα this.put = function (κλειδί, τιμή) {...} this.get = λειτουργία (get) {επιστροφή ...}});

Απάντηση 3:

Η μεγάλη ερώτηση στο AngularJS: Service vs Factory v / s Provider. Τι πρέπει να χρησιμοποιήσω;

Υπάρχουν τόνοι πόρων στο διαδίκτυο που συζητούν το θέμα. Αποδεικνύεται ότι αυτή η ερώτηση εμφανίζεται κάθε εβδομάδα περίπου σε διαφορετικά κανάλια και ακόμα και μετά την ανάγνωση των δέκα κορυφαίων απαντήσεων στο StackOverflow, δεν είναι ακόμα ξεκάθαρο.

Αν νομίζετε ότι είναι παρόμοια - έχετε δίκιο. Είναι πολύ παρόμοια. Στην πραγματικότητα, είναι όλοι το ίδιο πράγμα. Είναι όλοι πάροχοι.

Διαβάστε το πλήρες άρθρο -> AngularJS: Service v / s Εργοστάσιο v / s Provider - Get Interview έτοιμο σε 15 λεπτά