Όλα όσα πρέπει να ξέρετε για ng-template, ng-content, ng-container και * ngTemplateOutlet in Angular

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

Κατά την επιθεώρηση του DOM είδα την ngcontentεφαρμογή σε στοιχεία από το Angular. Χμμ… αν περιέχουν τα στοιχεία στο τελικό DOM, τότε τι χρησιμεύει ; Εκείνη τη στιγμή μπερδεύτηκα μεταξύ και .

Στην αναζήτηση για να γνωρίζετε τις απαντήσεις στις ερωτήσεις μου, ανακάλυψα την έννοια της . Προς έκπληξή μου, υπήρχε επίσης *ngTemplateOutlet. Ξεκίνησα το ταξίδι μου αναζητώντας σαφήνεια για δύο έννοιες, αλλά τώρα είχα τέσσερις από αυτές, ακούγοντας σχεδόν το ίδιο!

Έχετε πάει ποτέ σε αυτήν την κατάσταση; Εάν ναι, τότε είστε στο σωστό μέρος. Έτσι, χωρίς άλλη παραλλαγή ας τα πάρουμε ένα προς ένα.

1.

Όπως υποδηλώνει το όνομά του είναι ένα στοιχείο πρότυπο που γωνιακή χρήσεις με τις διαρθρωτικές οδηγίες ( *ngIf, *ngFor, [ngSwitch]και προσαρμοσμένες οδηγίες).

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

Εξετάστε ένα απλό παράδειγμα *ngIf:

Εμφανίζεται παραπάνω η γωνιακή ερμηνεία του *ngIf. Το Angular τοποθετεί το στοιχείο κεντρικού υπολογιστή στο οποίο εφαρμόζεται η οδηγία και διατηρεί τον κεντρικό υπολογιστή ως έχει. Το τελικό DOM είναι παρόμοιο με αυτό που έχουμε δει στην αρχή αυτού του άρθρου:

Χρήση:

Έχουμε δει πώς χρησιμοποιεί το Angular αλλά τι γίνεται αν θέλουμε να το χρησιμοποιήσουμε; Καθώς αυτά τα στοιχεία λειτουργούν μόνο με μια διαρθρωτική οδηγία, μπορούμε να γράψουμε ως:

Εδώ homeείναι μια booleanιδιότητα του στοιχείου που έχει οριστεί σε trueτιμή. Η έξοδος του παραπάνω κώδικα στο DOM:

Τίποτα δεν αποδόθηκε! :(

Γιατί όμως δεν μπορούμε να δούμε το μήνυμά μας ακόμα και μετά τη σωστή χρήση με μια διαρθρωτική οδηγία;

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

Ας συγκρίνουμε τα παραπάνω δύο DOM που αποδόθηκαν από το Angular:

Εάν παρακολουθείτε προσεκτικά, υπάρχει μια επιπλέον ετικέτα σχολίων στο τελικό DOM του Παραδείγματος 2 . Ο κώδικας που ερμήνευσε η Angular ήταν:

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

Για να το ξεφορτωθείτε υπάρχουν δύο τρόποι για να επιτύχετε το επιθυμητό αποτέλεσμα:

Μέθοδος 1:

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

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

Μέθοδος 2:

Αυτή είναι μια αρκετά αόρατη μορφή και σπάνια χρησιμοποιείται (χρησιμοποιώντας δύο αδέλφια ). Εδώ δίνουμε μια αναφορά στο *ngIfin thenγια να της πούμε ποιο πρότυπο θα πρέπει να χρησιμοποιηθεί εάν η συνθήκη είναι αληθής.

Δεν συνιστάται η χρήση πολλαπλών παρόμοιων (θα μπορούσατε να χρησιμοποιήσετε αντ 'αυτού) γιατί δεν είναι αυτό που προορίζονται. Χρησιμοποιούνται ως κοντέινερ για πρότυπα που μπορούν να επαναχρησιμοποιηθούν σε πολλά σημεία. Θα το καλύψουμε περισσότερα σε μια μεταγενέστερη ενότητα αυτού του άρθρου.

2.

Έχετε γράψει ή δει ποτέ κώδικα που μοιάζει με αυτό:

Ο λόγος για τον οποίο πολλοί από εμάς γράφουν αυτόν τον κώδικα είναι η αδυναμία χρήσης πολλαπλών δομικών οδηγιών σε ένα στοιχείο κεντρικού υπολογιστή στο Angular. Τώρα αυτός ο κώδικας λειτουργεί καλά, αλλά εισάγει πολλά επιπλέον κενά στο DOM εάν item.idείναι μια ψευδής τιμή που ενδέχεται να μην απαιτείται.

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

Αυτό που είναι ακόμη χειρότερο είναι το επίπεδο ένθεσης που πρέπει να κάνετε για να εφαρμόσετε το στυλ σας (CSS)!

Μην ανησυχείτε, πρέπει να σώσουμε!

Το Angular είναι ένα στοιχείο ομαδοποίησης που δεν επηρεάζει τα στυλ ή τη διάταξη, επειδή το Angular δεν το τοποθετεί στο DOM .

Αν λοιπόν γράψουμε το Παράδειγμα 1 με :

Παίρνουμε το τελικό DOM ως:

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

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

3.

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

Εξετάστε ένα απλό συστατικό:

Το περιεχόμενο HTML που περνά στις ετικέτες ανοίγματος και κλεισίματος του στοιχείου είναι το περιεχόμενο που θα προβάλλεται. Αυτό ονομάζουμε προβολή περιεχομένου . Το περιεχόμενο θα αποδοθεί στο εσωτερικό του στοιχείου. Αυτό επιτρέπει στον καταναλωτή του στοιχείου να περάσει οποιοδήποτε προσαρμοσμένο υποσέλιδο μέσα στο στοιχείο και να ελέγξει ακριβώς πώς θέλει να αποδίδεται.

Πολλαπλές προβολές:

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

Δείτε πώς:

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

Η κλήση του στοιχείου θα μοιάζει με:

4. * ngTemplateOutlet

… Χρησιμοποιούνται ως κοντέινερ για πρότυπα που μπορούν να επαναχρησιμοποιηθούν σε πολλά σημεία. Θα το καλύψουμε περισσότερα σε μια μεταγενέστερη ενότητα αυτού του άρθρου.

… Υπάρχει μια άλλη περίπτωση χρήσης όπου χρησιμοποιείται για την έγχυση ενός προτύπου δυναμικά σε μια σελίδα. Θα καλύψω αυτήν την περίπτωση χρήσης στην τελευταία ενότητα αυτού του άρθρου.

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

Επαναχρησιμοποίηση προτύπου:

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

Ακολουθεί το απόσπασμα κώδικα:

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

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

Προσαρμόσιμα στοιχεία:

Η δεύτερη θήκη χρήσης για *ngTemplateOutletείναι ιδιαίτερα προσαρμοσμένα εξαρτήματα. Εξετάστε το προηγούμενο παράδειγμα συστατικού μας με ορισμένες τροποποιήσεις:

Πάνω απ 'είναι η τροποποιημένη έκδοση του στοιχείου που δέχεται τρεις ιδιότητες των εισροών -  headerTemplate, bodyTemplate, footerTemplate. Ακολουθεί το απόσπασμα για project-content.ts:

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

Για να χρησιμοποιήσετε το πρόσφατα τροποποιημένο συστατικό μας:

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

ng-content εναντίον * ngTemplateOutlet

Και οι δύο μας βοηθούν να επιτύχουμε εξαιρετικά προσαρμοσμένα στοιχεία, αλλά ποια να επιλέξουμε και πότε;

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

Αυτό δεν συμβαίνει με ng-content. Αποδίδει το περιεχόμενο ως έχει. Στο μέγιστο μπορείτε να διαχωρίσετε το περιεχόμενο και να το αποδώσετε σε διαφορετικές τοποθεσίες της προβολής σας με τη βοήθεια του selectχαρακτηριστικού. Δεν μπορείτε να αποδώσετε υπό όρους το περιεχόμενο ng-content. Πρέπει να δείξετε το περιεχόμενο που λαμβάνεται από τον γονέα χωρίς να λαμβάνετε αποφάσεις βάσει του περιεχομένου.

Ωστόσο, η επιλογή μεταξύ των δύο εξαρτάται πλήρως από την περίπτωση χρήσης σας. Τουλάχιστον τώρα έχουμε ένα νέο όπλο *ngTemplateOutletστο οπλοστάσιό μας που παρέχει περισσότερο έλεγχο στο περιεχόμενο εκτός από τα χαρακτηριστικά του ng-content!