Beheersing van AngularJS-richtlijnen

Richtlijnen zijn een van de krachtigste componenten van AngularJS, waarmee u eenvoudige HTML-elementen / -kenmerken kunt uitbreiden en maken herbruikbare en toetsbare code. In deze zelfstudie laat ik u zien hoe u AngularJS-richtlijnen gebruikt met praktische tips uit de praktijk. 

Wat ik hier bedoel richtlijnenzijn meestal aangepaste richtlijnen tijdens de zelfstudie. Ik zal niet proberen je te leren hoe je ingebouwde richtlijnen moet gebruiken zoals ng-repeat, ng-voorstelling, enz. Ik zal u laten zien hoe u aangepaste richtlijnen kunt gebruiken om uw eigen componenten te maken. 

schets

  1. Eenvoudige richtlijnen
  2. Richtlijn Beperkingen
  3. Geïsoleerde reikwijdte
  4. Richtlijn Scopes
  5. Richtlijn overerving
  6. Richtlijn Debugging
  7. Richtlijn Eenheidstesten
  8. Richtlijn Scope Testing
  9. Conclusie

1. Eenvoudige richtlijnen

Stel dat u een eCommerce-app over boeken heeft en dat u specifieke boekdetails op verschillende gebieden weergeeft, zoals de opmerkingen, gebruikersprofielpagina's, artikelen, enzovoort. Uw widget voor boekdetails kan er ongeveer als volgt uitzien:

In deze widget is er een boekafbeelding, titel, beschrijving, opmerkingen en beoordeling. Het verzamelen van die informatie en het plaatsen van een specifiek dom element kan moeilijk zijn om te doen op elke plaats waar je het wilt gebruiken. Laten we deze weergave widgetiseren met behulp van een AngularJS-richtlijn. 

angular.module ('masteringAngularJsDirectives', []) .directive ('book', function () return beperken: 'E', scope: data: '=', templateUrl: 'templates / book-widget.html ')

In het bovenstaande voorbeeld is een richtlijnfunctie gebruikt om eerst een richtlijn te maken. De naam van de richtlijn is boekDeze richtlijn retourneert een object en laten we het een beetje over dit object hebben. beperkenis voor het definiëren van het richtlijntype, en dat kan het ook zijn EEN(EENttribute),C(Cdeerntje), E (Element), enM(coMment). U kunt het gebruik van elk hieronder zien.

Type Gebruik
EEN
boek>
C
E <boek data = "book_data">boek>
M

strekkingis voor het beheer van de scope van de richtlijn. In het bovenstaande geval worden boekgegevens overgedragen naar de richtlijnenjabloon met behulp van de "="scooptype. Ik zal uitgebreid ingaan op de reikwijdte in de volgende paragrafen. templateUrlwordt gebruikt voor het aanroepen van een weergave om specifieke inhoud weer te geven met behulp van gegevens die zijn overgedragen aan de scope van de richtlijn. Je kan ook gebruiken sjabloonen geef direct HTML-code op, zoals deze:

... sjabloon: '
Boek info
'...

In ons geval hebben we een gecompliceerde HTML-structuur en daarom koos ik voor de templateUrlkeuze.

2. Richtlijnbeperkingen

Richtlijnen worden gedefinieerd in het JavaScript-bestand van uw AngularJS-project en gebruikt op de HTML-pagina. Het is mogelijk om AngularJS-richtlijnen als volgt in HTML-pagina's te gebruiken:

A (kenmerk)

In dit gebruik wordt de naam van de richtlijn gebruikt in standaard HTML-elementen. Stel dat u een op rollen gebaseerd menu gebruikt in uw eCommerce-applicatie. Dit menu wordt gevormd volgens uw huidige rol. U kunt een richtlijn definiëren om te beslissen of het huidige menu moet worden weergegeven of niet. Uw HTML-menu kan er als volgt uitzien:

  • Huis
  • Laatste nieuws
  • Gebruikersadministratie
  • Campagne beheer

en de richtlijn als volgt:

app.directive ("restricted", function () return beperken: 'A', link: function (scope, element, attrs) // Enige authenticatiefunctie var isAuthorized = checkAuthorization (); if (! isAhororized)  element.css ('display', 'none');)

Als u de beperktin het menu-element als attribuut, kunt u een controle op toegangsniveau voor elk menu uitvoeren. Als de huidige gebruiker niet geautoriseerd is, wordt dat specifieke menu niet getoond. 

Dus, wat is het linkfunctie daar? Gewoon, de link-functie is de functie die u kunt gebruiken om richtlijn-specifieke operaties uit te voeren. De richtlijn geeft niet alleen een aantal HTML-codes weer door sommige ingangen te leveren. U kunt ook functies aan het richtlijnelement binden, een service aanroepen en de richtlijnwaarde bijwerken, richtlijnattributen krijgen als dit een is Etype richtlijn, enz.

C (klasse)

U kunt de richtlijnnaam binnen HTML-elementklassen gebruiken. Ervan uitgaande dat u de bovenstaande richtlijn als volgt zult gebruiken Cu kunt de richtlijn bijwerken beperken zoals Cen gebruik het als volgt:

  • Huis
  • Laatste nieuws
  • Gebruikersadministratie
  • Campagne beheer

Elk element heeft al een klasse voor styling, en als de beperkt klasse is toegevoegd, het is eigenlijk een richtlijn.

E (Element)

U hoeft geen richtlijn in een HTML-element te gebruiken. U kunt uw eigen element maken met behulp van een AngularJS-richtlijn met een E beperking. Stel dat u een gebruikerswidget in uw toepassing wilt laten weergeven gebruikersnaam, avatar, en reputatieop verschillende plaatsen in uw applicatie. Misschien wilt u een richtlijn als deze gebruiken:

app.directive ("user", function () return restrict: 'E', link: function (scope, element, attrs) scope.username = attrs.username; scope.avatar = attrs.avatar; scope.reputation = attrs.reputation;, sjabloon: '
Gebruikersnaam: username, Avatar: avatar, Reputatie: reputation
')

De HTML-code is:

In het bovenstaande voorbeeld wordt een aangepast element gemaakt en een aantal kenmerken zoals gebruikersnaam, avatar, en reputatie. Ik wil de aandacht vestigen op de body van de link-functie. Elementattributen worden toegewezen aan een richtwaarde. De eerste parameter van de koppelingsfunctie is de reikwijdte van de huidige richtlijn. De derde parameter van de richtlijn is het attribuutobject van de richtlijn, wat betekent dat u elk kenmerk uit de aangepaste richtlijn kunt lezen door attrs.attr_name. Attribuutwaarden worden aan het bereik toegewezen, zodat ze binnen de sjabloon worden gebruikt. 

Eigenlijk kun je deze operatie op een kortere manier doen, en daar zal ik later over praten. Dit voorbeeld is bedoeld om het hoofdidee achter gebruik te begrijpen.

M (coMment)

Dit gebruik is niet erg gebruikelijk, maar ik zal laten zien hoe het te gebruiken. Stel dat u op veel plaatsen een reactieformulier nodig heeft voor uw toepassing. U kunt dat doen door de volgende richtlijn te gebruiken:

app.directive ("comment", function () return beperken: 'M', sjabloon: '')

En in het HTML-element:

3. Geïsoleerde reikwijdte

Elke richtlijn heeft zijn eigen toepassingsgebied, maar u moet voorzichtig zijn met betrekking tot de gegevens die binden aan de richtlijnverklaring. Laten we zeggen dat u de mandonderdeel van uw eCommerce-applicatie. Op de winkelwagenpagina heb je items die hier al eerder zijn toegevoegd. Elk item heeft zijn bedragveld om te selecteren hoeveel items u wilt kopen, zoals hieronder:

Dit is de richtlijnverklaring:

app.directive ("item", functie () return beperken: 'E', koppeling: functie (bereik, element, attrs) scope.name = attrs.name;, sjabloon: '
Naam: naam Selecteer bedrag: Geselecteerde bedrag: Count
')

En om drie items in HTML weer te geven:

  

Het probleem hierbij is dat wanneer u de hoeveelheid van het gewenste item kiest, alle secties van de items worden bijgewerkt. Waarom? Omdat er een bidirectionele gegevensverbinding is met een naam tellen, maar de reikwijdte is niet geïsoleerd. Om het bereik te isoleren, voegt u gewoon toe bereik: naar het kenmerk directive in de sectie return:

app.directive ("item", functie () return beperken: 'E', bereik: , koppeling: functie (bereik, element, attrs) scope.name = attrs.name;, sjabloon: '
Naam: naam Selecteer bedrag: Geselecteerde bedrag: Count
')

Dit leidt ertoe dat uw richtlijn een eigen geïsoleerde scope heeft, zodat tweewegsbinding binnen deze richtlijn afzonderlijk kan plaatsvinden. Ik zal ook over de strekkingattribute later.

4. Richtlijnen

Het belangrijkste voordeel van de richtlijn is dat het een herbruikbaar onderdeel is dat gemakkelijk kan worden gebruikt - u kunt het zelfs geef wat extra attributen op die richtlijn. Maar hoe is het mogelijk om extra waarde, binding of uitdrukking aan een richtlijn door te geven om gegevens binnen de richtlijn te kunnen gebruiken?

"@" Scope: Dit type bereik wordt gebruikt voor het doorgeven van waarde aan de scope van de richtlijn. Stel dat u een widget voor een meldingsbericht wilt maken:

app.controller ("MessageCtrl", function () $ scope.message = "Product created!";) app.directive ("notification", function () return limit: 'E', scope: message: '@', sjabloon: '
bericht
');

en je kunt gebruiken:

In dit voorbeeld wordt de berichtwaarde eenvoudig toegewezen aan de richtwaarde. De weergegeven HTML-inhoud zal zijn:

Product gemaakt!

"=" Bereik: In dit bereiktype worden bereikvariabelen doorgegeven in plaats van de waarden, wat betekent dat we niet doorgeven bericht, we gaan voorbij bericht in plaats daarvan. De reden achter deze functie is het construeren van bidirectionele gegevensbinding tussen de richtlijn en de pagina-elementen of controllers. Laten we het in actie zien.

.directive ("bookComment", function () return beperken: 'E', scope: text: '=', sjabloon: '')

In deze richtlijn proberen we een widget te maken voor het weergeven van commentaartekstinvoer om een ​​opmerking voor een specifiek boek te maken. Zoals u kunt zien, heeft deze richtlijn één kenmerk nodig tekst om bidirectionele gegevensbinding tussen andere elementen op de pagina's te construeren. U kunt dit op de pagina gebruiken:

Dit is het tekstvak op de richtlijn 

Dit toont gewoon een tekstvak op de pagina, dus laten we nog iets toevoegen om te communiceren met deze richtlijn:

Dit is het tekstvak op de pagina  
Dit is het tekstvak op de richtlijn

Telkens wanneer u iets in het eerste tekstvak typt, wordt dit ook in het tweede tekstvak getypt. Je kunt dat andersom doen. In de richtlijn hebben we de bereikvariabele doorgegeven CommentText in plaats van de waarde, en deze variabele is de gegevensbindingreferentie naar het eerste tekstvak. 

"&" Scope: We kunnen de waarde doorgeven en verwijzen naar richtlijnen. In dit bereiktype zullen we kijken hoe expressies in de richtlijn kunnen worden uitgedrukt. In de praktijk kan het nodig zijn om een ​​specifieke functie (expressie) door te geven aan de richtlijnen om koppeling te voorkomen. Soms hoeven richtlijnen niet veel te weten over het idee achter de uitdrukkingen. Een richtlijn zal bijvoorbeeld het boek leuk vinden, maar weet niet hoe dat moet. Om dat te doen, kun je een structuur als deze volgen:

.directive ("likeBook", function () return limit: 'E', scope: like: '&', sjabloon: '')

In deze richtlijn wordt een uitdrukking doorgegeven via de net zoals attribuut. Laten we een functie definiëren in de controller en doorgeven aan de richtlijn in de HTML.

$ scope.likeFunction = function () alert ("Ik vind het boek leuk!")

Dit bevindt zich in de controller en de sjabloon zal zijn:

likeFunction () komt van de controller en wordt doorgegeven aan de richtlijn. Wat als u een parameter wilt doorgeven aan likeFunction ()? U moet bijvoorbeeld een beoordelingswaarde doorgeven aan de likeFunction (). Het is heel eenvoudig: voeg gewoon een argument toe aan de functie in de controller en voeg een invoerelement toe aan de richtlijn om het aantal starts van de gebruiker te vereisen. U kunt dat doen zoals hieronder getoond:

.directive ("likeBook", function () return limit: 'E', scope: like: '&', sjabloon: '
'+'')
$ scope.likeFunction = function (star) alert ("Ik vind het boek leuk !, en gaf" + star + "star.")

Zoals u kunt zien, komt het tekstvak uit de richtlijn. De tekstvakwaarde is gebonden aan het functieargument zoals like (star: starCount). ster is voor de controllerfunctie, en starCount voor de binding van de tekstvakwaarde. 

5. Overname van richtlijnen

Soms hebt u mogelijk een functie die in verschillende richtlijnen bestaat. Ze kunnen in een ouderrichtlijn worden opgenomen, zodat ze worden overgenomen door de kinderrichtlijnen. 

Ik zal u een realistisch voorbeeld geven. U wilt statistische gegevens verzenden wanneer klanten hun muiscursor naar de bovenkant van een specifiek boek verplaatsen. U kunt een muisklikevenement implementeren voor de boekrichtlijn, maar wat als het door een andere richtlijn wordt gebruikt? In dit geval kunt u overerving van de richtlijnen gebruiken, zoals hieronder:

app.directive ('mouseClicked', function () return limit: 'E', scope: , controller: "MouseClickedCtrl as mouseClicked")

Dit is een ouderrichtlijn die moet worden overgenomen door kinderrichtlijnen. Zoals je kunt zien is er een controllerattribuut van de richtlijn die de "as" -richtlijn gebruikt. Laten we deze controller ook definiëren:

app.controller ('MouseClickedCtrl', functie ($ element) var mouseClicked = this; mouseClicked.bookType = null; mouseClicked.setBookType = function (type) mouseClicked.bookType = type; $ element.bind ("klik", function () alert ("Type of book:" + mouseClicked.bookType + "verzonden voor statistische analyse!");))

In deze controller stellen we eenvoudig een controllerinstantie van de variabele in booktype door gebruik te maken van kinderrichtlijnen. Telkens wanneer u op een boek of tijdschrift klikt, wordt het type element naar de back-endservice verzonden (ik heb een waarschuwingsfunctie gebruikt om de gegevens weer te geven). Hoe kunnen kinderrichtlijnen deze richtlijn gebruiken??

app.directive ('ebook', function () return require: "mouseClicked", link: function (scope, element, attrs, mouseClickedCtrl) mouseClickedCtrl.setBookType ("EBOOK");) .directive (' magazine ', function () return require: "mouseClicked", link: function (scope, element, attrs, mouseClickedCtrl) mouseClickedCtrl.setBookType ("MAGAZINE");)

Zoals je ziet, gebruiken kinderrichtlijnen de vereisen sleutelwoord om de ouderrichtlijn te gebruiken. En nog een belangrijker punt is het vierde argument van de linkfunctie in de kinderrichtlijnen. Dit argument verwijst naar het controllerattribuut van de bovenliggende instructie, wat betekent dat de onderliggende richtlijn de regelfunctie kan gebruiken setBookType in de controller. Als het huidige element een eBoek is, kunt u de eerste richtlijn gebruiken. Als het een tijdschrift betreft, kunt u de tweede gebruiken:

Game of thrones (klik op mij)
PC World (klik op mij)

Kinderrichtlijnen zijn een eigenschap van de ouderrichtlijn. We hebben het gebruik van de muisklikgebeurtenis voor elke onderliggende richtlijn uitgeschakeld door dat gedeelte in de bovenliggende richtlijn te plaatsen.

6. Richtlijnen voor foutopsporing

Wanneer u richtlijnen in de sjabloon gebruikt, is wat u op de pagina ziet de gecompileerde versie van de richtlijn. Soms wilt u het daadwerkelijke gebruik van de richtlijn zien voor het opsporen van fouten. Om de niet-gecompileerde versie van de huidige sectie te zien, kunt u gebruiken ng-niet-te binden. Stel dat u een widget heeft die de populairste boeken afdrukt, en hier is de code voor:

De scoopvariabele van het boek is afkomstig van de controller en de uitvoer hiervan is als volgt:

Als u het gebruik van de richtlijn achter deze gecompileerde uitvoer wilt weten, kunt u deze versie van de code gebruiken:

  • boek

Deze keer ziet de uitvoer er als volgt uit:

Het is cool tot nu toe, maar wat als we zowel de ongecompileerde als gecompileerde versies van de widget willen zien? Het is tijd om een ​​aangepaste richtlijn te schrijven die een geavanceerde foutopsporingsbewerking zal uitvoeren. 

app.directive ('customDebug', functie ($ compile) return terminal: true, link: function (scope, element) var currentElement = element.clone (); currentElement.removeAttr ("custom-debug"); var newElement = $ compile (currentElement) (scope); element.attr ("style", "border: 1px solid red"); element.after (newElement);)

In deze richtlijn klonen we het element dat zich in de foutopsporingsmodus bevindt, zodat het niet wordt gewijzigd na een aantal bewerkingen. Na het klonen, verwijder de custom-debugom niet als foutopsporingsmodus te werken en deze vervolgens te compileren $ complile, die al in de richtlijn is geïnjecteerd. We hebben een stijl gegeven aan het debug-moduselement om de foutopsporingselementen te benadrukken. Het eindresultaat is als volgt:

U kunt uw ontwikkeltijd besparen door dit soort foutopsporingsrichtlijnen te gebruiken om de oorzaak van fouten in uw project te achterhalen.

7. Testen van richtlijnstelsels

Zoals u al weet, is unit testing een zeer belangrijk onderdeel van de ontwikkeling om de code die u hebt geschreven volledig te beheersen en mogelijke bugs te voorkomen. Ik ga niet diep in het testen van eenheden duiken, maar zal je een idee geven over het testen van richtlijnen op een aantal manieren.

Ik zal Jasmine gebruiken voor unit testing en Karma voor de unit test runner. Om Karma te gebruiken, installeer het eenvoudigweg wereldwijd door te draaien npm install -g karma karma-cli (u moet Node.js en npm op uw computer geïnstalleerd hebben). Na de installatie opent u de opdrachtregel, gaat u naar de hoofdmap van uw project en typt u karma init. Het zal u een aantal vragen stellen, zoals hieronder, om uw testvereisten in te stellen.

Ik gebruik Webstorm voor ontwikkeling en als u Webstorm ook gebruikt, klikt u gewoon met de rechtermuisknop op karma.conf.js en selecteer Rennen karma.conf.js. Hiermee worden alle tests uitgevoerd die zijn geconfigureerd in het karma conf. U kunt ook testen uitvoeren met de karma start opdrachtregel in de hoofdmap van het project. Dat draait allemaal om de omgeving, dus laten we overschakelen naar het testgedeelte.

Laten we zeggen dat we de boekrichtlijn willen testen. Wanneer we een titel aan de richtlijn doorgeven, moet deze worden gecompileerd tot een detailweergave van een boek. Dus laten we beginnen.

beschrijf ("Boek Tests", functie () var element; var scope; beforeEach (module ("masteringAngularJsDirectives")) beforeEach (inject (functie ($ compile, $ rootScope) scope = $ rootScope; element = angular.element ( ""); $ compileer (element) ($ rootScope) bereik. $ digest ())); it (" richtlijn moet met succes worden gecompileerd ", function () expect (element.html ()). toBe (" test ") )));

In de bovenstaande test testen we een nieuwe richtlijn genaamd booktestDeze richtlijn neemt het argument titelen maakt een div aan door deze titel te gebruiken. In de test, voor elke testsectie, bellen we onze module masteringAngularJsDirectiveseerste. Vervolgens genereren we een geroepen instructie booktest. In elke teststap wordt de uitvoer van de richtlijn getest. Deze test is alleen voor een waardecontrole.

8. Richtlijn Scope Testing

In deze sectie zullen we de reikwijdte van de richtlijn testen booktestDeze richtlijn genereert een boekdetailweergave op de pagina en wanneer u op dit detailgedeelte klikt, wordt een bereikvariabele genoemd bekekenwordt ingesteld als waar. In onze test zullen we controleren of bekekenis ingesteld op true wanneer de klikgebeurtenis wordt geactiveerd. De richtlijn is:

.directive ('booktest', function () return restrict: 'E', scope: title: '@', replace: true, template: '
titel
', link: function (scope, element, attrs) element.bind ("klik", functie () console.log ("book viewed!"); scope.viewed = true;); )

Om een ​​gebeurtenis in een element in AngularJS in de richtlijn in te stellen, kunt u de link attribuut. Binnen dit kenmerk heb je het huidige element dat rechtstreeks is gekoppeld aan een klikgebeurtenis. Om deze richtlijn te testen, kunt u het volgende gebruiken:

beschrijf ("Boek Tests", functie () var element; var scope; beforeEach (module ("masteringAngularJsDirectives")) beforeEach (inject (functie ($ compile, $ rootScope) scope = $ rootScope; element = angular.element ( ""); $ compileer (element) ($ rootScope) scope. $ digest ())); it (" scope liked moet waar zijn als book liked ", function () element.triggerHandler (" click "); expect ( element.isolateScope (). bekeken) .toBe (true);););

In de testsectie wordt een klikgebeurtenis geactiveerd door gebruik van element.triggerHandler ( "klik"). Wanneer een klikgebeurtenis wordt geactiveerd, moet de bekeken variabele worden ingesteld zoals waar. Die waarde wordt bevestigd door te gebruiken verwachten (element.isolateScope (). bekeken) .toBe (true).

9. Conclusie

Om modulaire en testbare webprojecten te ontwikkelen, is AngularJS de beste die we gemeen hebben. Richtlijnen zijn een van de beste componenten van AngularJS, en dit betekent dat hoe meer je weet over AngularJS-richtlijnen, hoe meer modulaire en testbare projecten je kunt ontwikkelen. 

In deze zelfstudie heb ik geprobeerd je de beste praktijkvoorbeelden over richtlijnen te laten zien, en onthoud dat je veel moet oefenen om de logica achter de richtlijnen te begrijpen. Ik hoop dat dit artikel je helpt de AngularJS-richtlijnen goed te begrijpen.