Στο Angular, ένα στοιχείο είναι μια ειδική οδηγία και το ιδιαίτερο χαρακτηριστικό του είναι ότι έχει το δικό του πρότυπο (html) και στυλ (css). Επομένως, η χρήση στοιχείων μπορεί να κάνει τον κώδικά μας εξαιρετικά αποσυνδεδεμένο, επαναχρησιμοποιήσιμο και εύκολα επεκτάσιμο. Τα συνήθη συστατικά ορίζονται ως εξής:
demo.component.ts:
demo.component.html:
demo.component.scss:
Όταν αναφερόμαστε στο στοιχείο, αποδίδεται το αναλυμένο περιεχόμενο του στοιχείου:
Ας υποθέσουμε ότι υπάρχει ανάγκη για το στοιχείο να δέχεται περιεχόμενο που προβάλλεται εξωτερικά, πράγμα που σημαίνει ότι το στοιχείο καταλήγει να παρουσιάζει περισσότερα από αυτά που ορίζει. Αυτή τη στιγμή, ο πρωταγωνιστής αυτού του άρθρου είναι καλεσμένοςng-περιεχόμενο。
Απλή προβολή
Ας ξεκινήσουμε με το πιο απλό, προσθέστε το τροποποιημένο demo.component.html και το demo.component.scss στο demo.component.html, ως εξής:
demo.component.html:
demo.component.scss:
Για λόγους εφέ, το χρώμα φόντου του δοχείου ορίζεται σκόπιμα ως πορτοκαλί.
Σε αυτό το σημείο μπορούμε να μεταδώσουμε περιεχόμενο από το εξωτερικό κατά την αναφορά στο στοιχείο και το εξωτερικό περιεχόμενο θα εμφανίζεται στην πορτοκαλί περιοχή:
Στοχευμένη προβολή
Εάν υπάρχουν πολλά ταυτόχρονα, πώς θα προβάλλεται το εξωτερικό περιεχόμενο;
Ας ρίξουμε μια ματιά σε ένα παράδειγμα πρώτα, για λόγους διάκρισης, πρόσθεσα μια μπλε περιοχή, το τροποποιημένο demo.component.html και το demo.component.scss ως εξής:
demo.component.html:
demo.component.scss:
Για να αναφέρετε το στοιχείο:
Σε αυτό το σημείο, θα δούμε ότι το εξωτερικό περιεχόμενο προβάλλεται στην μπλε περιοχή:
Φυσικά, εάν βάλετε τον πορτοκαλί κωδικό περιοχής μετά τον μπλε κωδικό περιοχής, τότε το εξωτερικό περιεχόμενο θα προβάλλεται στην πορτοκαλί περιοχή:
Έτσι, από το παραπάνω παράδειγμα, μπορούμε να δούμε ότι εάν υπάρχει επίσης ένα απλό , τότε το εξωτερικό περιεχόμενο θα προβάλλεται στο τελευταίο του προτύπου στοιχείου.
Γνωρίζοντας λοιπόν αυτό το πρόβλημα, μπορεί να αναρωτηθούμε, μπορούμε να προβάλλουμε εξωτερικό περιεχόμενο με στοχευμένο τρόπο; Η απάντηση είναι προφανώς ναι.
Για να το αντιμετωπίσετε αυτό, υποστηρίξτε έναδιαλέγωΧαρακτηριστικά που σας επιτρέπουν να προβάλλετε συγκεκριμένο περιεχόμενο σε ένα συγκεκριμένο μέρος. Αυτή η ιδιότητα υποστηρίζει επιλογείς CSS (επιλογέας ετικέτας, επιλογέας κλάσης, επιλογέας χαρακτηριστικού、... ) για να ταιριάζει με αυτό που θέλετε. Εάν δεν έχει οριστεί χαρακτηριστικό επιλογής στο ng-content, θα λάβει το πλήρες περιεχόμενο ή το περιεχόμενο που δεν ταιριάζει με κανένα άλλο στοιχείο ng-content.
Κοιτάζοντας απευθείας το παράδειγμα, τα τροποποιημένα demo.component.html και demo.component.scss είναι τα εξής:
demo.component.html:
demo.component.scss:
Όπως μπορείτε να δείτε από τον παραπάνω κώδικα, η μπλε περιοχή θα λάβει το τμήμα της κεφαλίδας της ετικέτας, η κόκκινη περιοχή θα λάβει το τμήμα του div με την κλάση "demo2", η πράσινη περιοχή θα λάβει το τμήμα του div με το όνομα ιδιότητας "demo3" και η πορτοκαλί περιοχή θα λάβει το υπόλοιπο εξωτερικό περιεχόμενο (έναρξη, είμαι το περιεχόμενο της εξωτερικής ενσωμάτωσης, τέλος).
Για να αναφέρετε το στοιχείο:
Σε αυτό το σημείο, θα δούμε το εξωτερικό περιεχόμενο να προβάλλεται στο καθορισμένο αρχείο .
Επεκτείνετε τη γνώση
ngProjectAs
Τώρα γνωρίζουμε ότι η ιδιότητα επιλογής του ng-content σάς επιτρέπει να καθορίσετε ότι το εξωτερικό περιεχόμενο προβάλλεται σε ένα δεδομένο .
Για να προβάλλετε σωστά το περιεχόμενο με βάση το χαρακτηριστικό επιλογής, υπάρχει ένας περιορισμός - είτε πρόκειται για κεφαλίδα ετικέτας, div με κλάση "demo2" ή div με όνομα ιδιότητας "demo3", αυτές οι ετικέτες είναι όλες άμεσοι υποκόμβοι της ετικέτας στοιχείου.
Τι θα συνέβαινε αν δεν ήταν ένας άμεσος υποκόμβος; Ας τροποποιήσουμε απλώς τον κώδικα που αναφέρεται στο στοιχείο επίδειξης, ας βάλουμε την κεφαλίδα της ετικέτας σε ένα div και ας την τροποποιήσουμε ως εξής:
Σε αυτό το σημείο, βλέπουμε ότι το τμήμα της κεφαλίδας καρτέλας του περιεχομένου δεν προβάλλεται πλέον στην μπλε περιοχή, αλλά στην πορτοκαλί περιοχή. Ο λόγος είναι ότι το <ng-content select="header"></ng-content> δεν μπορεί να ταιριάξει με την προηγούμενη κεφαλίδα ετικέτας, επομένως αυτό το μέρος του περιεχομένου προβάλλεται στην <ng-content></ng-content> πορτοκαλί περιοχή.
Για να λύσουμε αυτό το πρόβλημα, πρέπει να χρησιμοποιήσουμε την ιδιότητα ngProjectAs, η οποία μπορεί να εφαρμοστεί σε οποιοδήποτε στοιχείο. Οι λεπτομέρειες έχουν ως εξής:
Ορίζοντας την ιδιότητα ngProjectAs, το div όπου βρίσκεται η κεφαλίδα της ετικέτας δείχνει select="header" και το τμήμα της κεφαλίδας της ετικέτας προβάλλεται στην μπλε περιοχή:
<ng-content>Μην "δημιουργείτε" περιεχόμενο Κάντε ένα πείραμα Για να κάνετε ένα πείραμα, ορίστε πρώτα ένα στοιχείο demo-child-component:
demo-component σε:
Στη συνέχεια, στο demo-component cast demo-child-component:
Σε αυτό το σημείο, στην κονσόλα βλέπουμε ότι η αρχικοποίηση του demo-child-component έχει ολοκληρωθεί! Αυτά τα λόγια. Αλλά όταν κάνουμε κλικ στο κουμπί για εναλλαγή λειτουργιών, η προετοιμασία του demo-child-component έχει ολοκληρωθεί! Δεν εκτυπώνεται πλέον, πράγμα που σημαίνει ότι το στοιχείο επίδειξης-παιδιού-συστατικού δημιουργείται μόνο μία φορά - ποτέ δεν καταστρέφεται και δεν αναδημιουργείται.
Γιατί συμβαίνει αυτό?
Αιτίες εμφάνισης
<ng-content> Δεν «παράγει» περιεχόμενο, απλώς προβάλλει υπάρχον περιεχόμενο. Μπορείτε να το σκεφτείτε ως ισοδύναμο με τη μέθοδο node.appendChild(el) ή τη μέθοδο $(node).append(el) στο jQuery: με αυτές τις μεθόδους, ο κόμβος δεν κλωνοποιείται, απλώς μετακινείται στη νέα του θέση. Επομένως, ο κύκλος ζωής του προβαλλόμενου περιεχομένου θα συνδέεται με το σημείο όπου δηλώνεται και δεν θα εμφανίζεται στη θέση του.
Αυτό εξηγεί επίσης την προηγούμενη ερώτηση από την αρχή:Εάν υπάρχουν πολλά ταυτόχρονα, πώς θα προβάλλεται το εξωτερικό περιεχόμενο;
Αυτή η συμπεριφορά γίνεται για δύο λόγους: συνέπεια και απόδοση. Τι "επιθυμητή συνέπεια" σημαίνει ότι ως προγραμματιστής, μπορείτε να μαντέψετε τη συμπεριφορά της εφαρμογής σας με βάση τον κώδικά της. Ας υποθέσουμε ότι έγραψα τον ακόλουθο κώδικα:
Προφανώς το στοιχείο demo-child-component θα δημιουργηθεί μία φορά, αλλά τώρα αν χρησιμοποιήσουμε ένα στοιχείο από μια βιβλιοθήκη τρίτου μέρους:
Εάν μια βιβλιοθήκη τρίτου μέρους έχει τον έλεγχο του κύκλου ζωής ενός στοιχείου επίδειξης-θυγατρικού στοιχείου, δεν θα έχω τρόπο να γνωρίζω πόσες φορές έχει δημιουργηθεί. Ο μόνος τρόπος για να γίνει αυτό είναι να κοιτάξετε τον κώδικα των βιβλιοθηκών τρίτων για να κατανοήσετε την εσωτερική λογική επεξεργασίας τους. Το νόημα της σύνδεσης του κύκλου ζωής ενός στοιχείου με τα στοιχεία της εφαρμογής μας αντί για τα περιτυλίγματα είναι ότι οι προγραμματιστές μπορούν να ελέγξουν ότι οι μετρητές δημιουργούνται μόνο μία φορά, χωρίς να γνωρίζουν τον εσωτερικό κώδικα των βιβλιοθηκών τρίτων.
Λόγοι απόδοσηςείναι πιο σημαντικό. Επειδή το ng-content είναι απλώς ένα κινούμενο στοιχείο, μπορεί να γίνει κατά το χρόνο μεταγλώττισης, όχι κατά το χρόνο εκτέλεσης, γεγονός που μειώνει σημαντικά τον φόρτο εργασίας της πραγματικής εφαρμογής.
Λύση
Προκειμένου το συστατικό να ελέγχει την υλοποίηση των προβαλλόμενων υποσυστατικών, μπορούμε να το κάνουμε αυτό με δύο τρόπους: χρησιμοποιώντας <ng-template> στοιχεία και ngTemplateOutlets γύρω από το περιεχόμενό μας ή χρησιμοποιώντας οδηγίες δομής με σύνταξη "*". Για απλότητα, θα χρησιμοποιήσουμε τη Σύνταξη στο παράδειγμα <ng-template> .
demo-component σε:
Στη συνέχεια, συμπεριλαμβάνουμε το demo-child-component στο ng-template:
Σε αυτό το σημείο, όταν κάνουμε κλικ στο κουμπί για εναλλαγή, η κονσόλα θα εκτυπωθείΗ προετοιμασία του demo-child-component ολοκληρώθηκε!Αυτά τα λόγια.
|