We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback

Building Directives for AngularJS

00:00

Formal Metadata

Title
Building Directives for AngularJS
Title of Series
Number of Parts
170
Author
License
CC Attribution - NonCommercial - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
Identifiers
Publisher
Release Date
Language

Content Metadata

Subject Area
Genre
Abstract
Directives are a powerful feature of Angular and allow you to bring future web standards into the browser today. Directives are also intimidating at first because you need to know some magical incantations to make them work correctly and efficiently. In this session we’ll build some custom directives and see how to work with scope objects, linking functions, transclusions, and other features of directives that can transform your front end development.
3
Thumbnail
59:06
71
112
127
130
Element (mathematics)World Wide Web ConsortiumDifferent (Kate Ryan album)Speech synthesisDirection (geometry)CodeTouchscreenUniverse (mathematics)Perspective (visual)Element (mathematics)EmailAreaBuildingSocial classWeb 2.0BitFile formatFormal grammarClassical physicsEntire functionBootstrap aggregatingMechanism designView (database)Rule of inferenceForm (programming)Dependent and independent variablesSource codeEndliche ModelltheorieSingle-precision floating-point formatData miningConnectivity (graph theory)Physical lawFamilyWeb browserLine (geometry)MereologyLatent heatGoodness of fitComputer simulationPoint (geometry)Multiplication signService (economics)WritingFood energySheaf (mathematics)Metropolitan area networkCartesian coordinate systemKeyboard shortcutPhysical systemDomain nameFormal languageCodeLevel (video gaming)TrailMessage passingSubject indexingStandard deviationSoftware developerDampingComplex (psychology)Content (media)Type theoryHydraulic jumpPrimitive (album)Division (mathematics)Visualization (computer graphics)Markup languageFocus (optics)DemosceneValidity (statistics)DecimalModule (mathematics)Row (database)Computer animation
Scripting languageGame controllerBitFunction (mathematics)Module (mathematics)EmpennageControl flowOnline chatTemplate (C++)Attribute grammarDisintegrationElement (mathematics)Cache (computing)Uniform resource locatorSimulationBootstrap aggregatingTemplate (C++)Right angleSocial classDirection (geometry)Markup languageCartesian coordinate systemProper mapUniform resource locatorContent (media)Computer fileBuildingSoftware developerMobile appAttribute grammarType theoryWordElement (mathematics)SoftwareSlide ruleBitFlagProjective planeWeb pageStructural loadDivision (mathematics)Plug-in (computing)Cache (computing)AdditionTask (computing)System callTerm (mathematics)Sign (mathematics)Default (computer science)Library (computing)Software frameworkFunctional (mathematics)Game controllerModule (mathematics)Factory (trading post)Dot productSound effectSubject indexingScripting languageArmPower (physics)2 (number)Annulus (mathematics)Physical lawView (database)VideoconferencingBit rateFilm editingGreatest elementGraph coloringNatural numberJava appletEndliche ModelltheorieLine (geometry)Computer animation
Module (mathematics)Function (mathematics)Template (C++)Scripting languageContent (media)Direction (geometry)Computer animation
EstimationScripting languageFunction (mathematics)View (database)Content (media)String (computer science)Graph coloringTemplate (C++)Functional (mathematics)Content (media)Direction (geometry)Link (knot theory)Markup languageFood energyElement (mathematics)Heat transferDifferent (Kate Ryan album)Computer animation
Function (mathematics)Link (knot theory)Game controllerModule (mathematics)Element (mathematics)Division (mathematics)Menu (computing)Convex hullAttribute grammarData typeScripting languageMessage passingType theoryInformationElement (mathematics)Attribute grammarFunctional (mathematics)Content (media)Template (C++)Set (mathematics)Graph coloringError messageObject (grammar)Default (computer science)Bootstrap aggregatingSocial classDirection (geometry)QuicksortImplementationCodeGeneralized linear modelMathematicsMultiplication signData structureMereologyBitMessage passingGame controllerSoftware developerOcean currentOperator (mathematics)Parameter (computer programming)Event horizonMetropolitan area networkWorkstation <Musikinstrument>Inclusion mapWave packetComputer animation
Message passingScripting languageData typeFunction (mathematics)Game controllerAttribute grammarElement (mathematics)InformationLink (knot theory)Template (C++)Menu (computing)HypertextAlgebraic closureGraph coloringForm (programming)Line (geometry)MathematicsQuicksortWeb pageObject (grammar)BitFunctional (mathematics)Direction (geometry)Element (mathematics)Type theoryCategory of beingGame controllerSocial classCodeInstance (computer science)Revision controlMessage passingRewritingMereologyKeyboard shortcutTouchscreen2 (number)Subject indexingInformationDefault (computer science)Multiplication signEndliche ModelltheoriePoint (geometry)Different (Kate Ryan album)Closed setInheritance (object-oriented programming)Observational studyRight angleReal numberData miningComputer animation
Module (mathematics)Function (mathematics)Link (knot theory)Element (mathematics)Attribute grammarDefault (computer science)Inheritance (object-oriented programming)Keyboard shortcutBridging (networking)Form (programming)Game controllerData modelString (computer science)Object (grammar)CASE <Informatik>Direction (geometry)RootExpressionAttribute grammarType theoryKeyboard shortcutGame controllerBridging (networking)Category of beingLevel (video gaming)Cartesian coordinate systemMarkup languageIntegrated development environmentInheritance (object-oriented programming)InformationRoutingComputer animation
Attribute grammarFunction (mathematics)Data typeElement (mathematics)Link (knot theory)Game controllerInformationMessage passingScripting languageCategory of beingType theorySocial classAttribute grammarMessage passingKeyboard shortcutInformation2 (number)CodeNP-hardComputer animation
Data typeScripting languageMathematicsMessage passingInformationFunction (mathematics)Link (knot theory)Element (mathematics)Attribute grammaroutputPoint (geometry)MathematicsExpressionContent (media)String (computer science)WritingGraph coloringEndliche ModelltheorieType theoryInformationAttribute grammarKeyboard shortcutWeightQuicksortComputer animation
Game controllerKeyboard shortcutData modelFunction (mathematics)Message passingScripting languageData typeElement (mathematics)Attribute grammarLink (knot theory)InformationExpressionWordAttribute grammarEqualiser (mathematics)MathematicsKeyboard shortcutGraph coloringRiflingGame controllerSubject indexingDefault (computer science)Order (biology)Direction (geometry)Web pageEndliche ModelltheorieInformationComputer animation
Function (mathematics)Data typeModule (mathematics)Link (knot theory)Attribute grammarElement (mathematics)InformationMessage passingScripting languageMathematicsHypertextGame controllerDefault (computer science)Color managementView (database)Software developerDirection (geometry)Web serviceKeyboard shortcutExistential quantificationLetterpress printingRight angleType theoryExpressionStructural loadCategory of beingInterior (topology)Object (grammar)Point (geometry)Gastropod shellEndliche ModelltheorieAttribute grammarClosed setView (database)String (computer science)Game controllerFunctional (mathematics)Multiplication signTemplate (C++)Markup languageSocial classOcean currentLoginSymbol tableSet (mathematics)WordTouchscreenParsingParsingPartial derivativeFood energyInclusion mapShared memoryWeb pageBit rateGraph coloringSingle-precision floating-point formatPower (physics)Theory of relativityMereologyComputer animation
Function (mathematics)Game controllerAttribute grammarElement (mathematics)Link (knot theory)Message passingScripting languageData typeDifferent (Kate Ryan album)Equaliser (mathematics)Software developerType theoryClosed setNatural numberDirection (geometry)Game controllerMereologyWordComputer animation
Game controllerFunction (mathematics)Attribute grammarLink (knot theory)Message passingElement (mathematics)InformationGame controllerComputer fileElement (mathematics)Functional (mathematics)Service (economics)Flow separationEqualiser (mathematics)Generalized linear modelDirection (geometry)Event horizonInheritance (object-oriented programming)LogicForm (programming)Endliche ModelltheorieOrder (biology)Connectivity (graph theory)CalculationMultiplication signObject (grammar)QuicksortLink (knot theory)Unit testingFormal grammarExecution unitFood energyComputer animation
EmailFunction (mathematics)Game controllerMessage passingLink (knot theory)Attribute grammarElement (mathematics)outputForm (programming)Template (C++)Scripting languageDefault (computer science)Computer configurationData typeDivision (mathematics)Module (mathematics)InfinityDirection (geometry)Mobile appElement (mathematics)Validity (statistics)Game controllerCASE <Informatik>Form (programming)Regular graphoutputType theoryTelecommunicationEndliche ModelltheorieEmailLine (geometry)Attribute grammarWordWindowRight angleProjective planeObject (grammar)Functional (mathematics)Inheritance (object-oriented programming)Event horizonCodeParameter (computer programming)Bound stateBit rateFood energy2 (number)Virtual machineComputer animation
TelecommunicationGame controllerSineLink (knot theory)Element (mathematics)Function (mathematics)Reading (process)Menu (computing)Pulse (signal processing)ExplosionDirection (geometry)Table (information)Line (geometry)Endliche ModelltheorieAttribute grammarContent (media)IdentifiabilityCellular automatonReal numberType theoryTraffic reportingBitDoubling the cubeComputer animation
Function (mathematics)Link (knot theory)Element (mathematics)VolumenvisualisierungReading (process)Cellular automatonDirection (geometry)Key (cryptography)Game controllerAttribute grammarType theoryMultiplication signTape driveEndliche ModelltheorieObject (grammar)Keyboard shortcutView (database)Process (computing)Food energySign (mathematics)Computer animation
ParsingVolumenvisualisierungElement (mathematics)Attribute grammarCompilerFunction (mathematics)Link (knot theory)NumberMathematicsResultantDirection (geometry)Endliche ModelltheorieWeb pageCodeCategory of beingPropagatorMultiplication signString (computer science)Event horizonForm (programming)DemoscenePoint (geometry)ChainBitRange (statistics)View (database)Interactive televisionSoftware developerMereologyPresentation of a groupParsingExpressionTouchscreenMobile WebDecimalPlug-in (computing)IntegerPhase transitionError messageElement (mathematics)Functional (mathematics)Computer animation
Scripting languageData typeMessage passingFunction (mathematics)Template (C++)Element (mathematics)Game controllerLink (knot theory)Functional (mathematics)Direction (geometry)Object (grammar)Generalized linear modelElement (mathematics)Multiplication signFood energyRule of inferenceComputer animation
Scripting languageEmailMessage passingData typePrice indexArmWeb browserProjective planeShift operatorGame controllerReal numberDivision (mathematics)DemosceneGeneralized linear modelMultiplication signTouchscreenElement (mathematics)Functional (mathematics)Computer animation
CompilerFunction (mathematics)Link (knot theory)Element (mathematics)Multiplication signBlogMultiplicationPresentation of a groupFunctional (mathematics)Web pageFunction (mathematics)Computer animation
Module (mathematics)Function (mathematics)Attribute grammarLink (knot theory)Element (mathematics)Direction (geometry)CodeComputer animation
Transcript: English(auto-generated)
Good afternoon, everybody. Good afternoon, I'd say. There we go. My name is Scott. I'd like to talk to you about directives for AngularJS. I'm kind of assuming that you might have worked with AngularJS already just a little bit so you know some of the basics, but I want to drill into a specific area of AngularJS, the area that I find
most difficult, found most difficult. Well, there's still mysteries in there. Writing directives for AngularJS because I found it very easy to create controllers, services, manipulate scope, do data binding, ng-model, all that stuff. When it came to directives, every time I looked at the source code to directives or looked at someone else who was writing a directive,
I found some new mysterious feature. So directives are beautiful, but they have some of the most terse shortcuts and syntax that you have to get used to and just magic behavior sometimes. So I actually want to give you two different perspectives on directives because I believe there's two different ways to look at them. One way is that you can use directives
to build this beautiful universe which is the idyllic Norwegian landscape you see on one half of the screen. That is, you can use directives to make your markup, the code that you write in HTML a little bit prettier, a little more orientated towards the way you think and the way your team thinks and the UX problems that you're trying to solve.
And then there's this other world of directives which I'll also talk about which you might never experience this but directives really are the machinery that is in the basement of the building where it's very hot and greasy and no one really wants to be there but it's what makes the whole thing work. So only the plumbers and the mechanics like being in that room with all the machinery
but there are pieces of directives that operate that way too. I mean, the entire form validation capabilities and the way ng-model works with a form in Angular is quite amazing but it's all this plumbing that is down there. We'll focus on the pretty scene first. The way
I view this is that if you've ever heard of the code smell primitive obsession, it's about when you're using a language like C sharp but you are representing your domain concepts using simple built-in primitives. So if I'm in a distributed messaging system, I'm modeling messages with a string. If I'm building something that needs to keep track of
monetary values, I'm storing those values in a decimal and that's all well and good until you reach a certain level of complexity and then you realize that, oh, I have to know whether that's in this currency or is it euros, is it US dollars, I don't know, it's just in this decimal. What is it? As HTML developers, we have a primitive
obsession when we're building the UI because all we have is primitives. We have things like divs, so everything becomes a div and even though HTML 5 introduced some new semantic markup and I can have a header and a footer and sections and articles, all those wonderful things, most of what I write still comes out to be divs. I put divs inside of divs to create, sometimes
using bootstrap classes to create rows and columns, but yeah, it's all divs. Directives allow you to escape from that and they're a very forward looking part of AngularJS because the Google people that started AngularJS, they knew what specifications were coming down the road and they wanted to orientate themselves towards those specifications.
So if you look at specifications surrounding custom elements, web components, Shadow DOM, these are things that Directives are trying to give us in our applications and inside the browser today until some point when all these newer specifications are finalized and they're in the browsers and our grandchildren
are building web applications, they'll be able to actually use those standards. But until then, that was supposed to be funny. Thank you. There's things like Polymer. If you've heard of it, they allow you to build web components. There's X-Tags which allow you to simulate web components and then there's Angular.
It's part of its pitch line. We're going to enhance your HTML. So how do they enhance your HTML? Well, let's take a look at this scenario where I have a div that I want to represent some alert that's going to be displayed to the user and I'm using Bootstrap.css so I say this is a div class equals alert, alert-warning, alert-dismissable
because I want it to be formatted a certain way and have a certain color and give the ability to the user to click on a button to make it go away. But when you look at that, it's all well and good that Bootstrap uses this they pretty much apply the single responsibility principle to CSS rules, right? So it's not just enough
to give it a class of alert because that only does some things. I have to be very specific and say class alert, alert-warning but what if I could write it like this? What if I could just say alert type equals warning and then include the content that I want? That can be nicer in many scenarios. If I wanted to do something like that today in an Angular application, that's when I would write a
custom directive. And just so you know, the exercise that we're about to go through is to build something that works like that. So I can just write alert in the HTML. But it's already been built you don't have to do this from scratch I just think it's a nice example. There are already a couple Angular modules out there like Angular UI
that already wrap a lot of Bootstrap so you can just write accordions or alerts in your HTML and directives pick it up and make things work. So, let's jump into Visual Studio and in my index.html here's the Bootstrap alert let me copy that and bring that here
inside of the markup, inside of something that's contained in an alerts controller and this is where I want to change this to just be an alert type equals warning get rid of all this class stuff yes, I still might want a button with a class of close so that it appears on the right but I don't want to use Bootstrap
dot js and jQuery dot js if you've ever used Bootstrap and you want things that are dismissable you have to include those additional files Bootstrap dot js and jQuery dot js I just want to make it all work with Angular so I want to build some sort of alert and I want this warning to appear inside of it and let's just see what it looks like now
so there's the Bootstrap alert on the top and then there's my alert which isn't colored correctly and doesn't close when I click on the button so the first thing we have to do is tell Angular that when you compile the markup in the DOM you should be looking for an element with the name of alert and the way we do that is by writing a directive
I already have an app dot js file that is the module that is in effect for my HTML page I have a controller on there, it doesn't do anything as yet, but now I need to write a directive called alert so that's what Angular will look for and I need to write a function so that when Angular is bootstrapping it will invoke that function
and get back what is known whoops as the directive definition object the DDO excuse me it is what describes the capabilities and the behavior of alert to Angular so it knows what to do when it sees that element in the HTML and one of the things you can put
inside of here is a template so I could say template is a div and let's just say for right now I'm going to write out simple text hello NDC or I guess this is a warning, warning from NDC don't trust the wi-fi Troy hunts around somewhere with one of those pineapple devices
but is this going to work yet? no because by default Angular directives it only looks for attributes in HTML it doesn't look for them as an element so in other words if I did a div alert that would work but I want it to be alert proper element type here
I do that with the restrict clause here so I can say restrict this to elements and attributes make it work either way it's just a short hand syntax so E for element, A for attribute there's also C for class which is quite interesting because if you say
I want to I want to make this directive wire up to wherever a class equals alert appears that can be quite effective with integrating with existing CSS that you might have or existing libraries or jQuery plugins that you're trying to replace there's also M for HTML comment but as far as I know no one really uses that so just pretend you didn't even see that
we're just going to stick with elements and attributes and now hopefully if everything is working correctly and I refresh this now my element is replaced with that template which is warning from NDC but most of us well there's many directives where you just can't inline the HTML
it's kind of messy right so I can also specify template URL cut this out of here and say no actually you need to go to alert.html which is a file I already have in this project I'll just come over to alert.html paste this in here without the double quotes and just so we know
things are working and it's updated so we pulled in that template alright so far I'm going to flip back to the slides for a second just so I don't get lost we've learned about restrict what type of things should Angular be looking for in the HTML to instantiate and use this directive
and this is how I could write it also HTML alert is an attribute now if I restrict to ena and we've learned about templates so I can specify a template URL and one thing that people commonly ask me about
is when I'm running my Angular application I see a dozen network requests go off on the first page load for all of these little directive templates is there a way to prevent that? well if you look at node tools specifically there's a grunt task and a gulp task that can actually pre-compile
all of your HTML templates together spit out a JavaScript file for you that you load into the web page and it will automatically deliver all of your templates at once from that JavaScript file it automatically puts them all into a cache factory that Angular calls dollar sign template cache so it doesn't have to do a lot of network requests for these small bits of HTML so
just a tip there if you're ever trying to optimize an application let's talk about transclusion transclusion is fun funny because it's one of those words that people used to pick on with Angular they're like transclusion it's not even in the dictionary what are you doing building this framework that's so weird but it isn't
Wikipedia by the way transclusion is just a term for saying I want to lift the content of one document let's say this content I'm going to lift it out of there and put it inside of something else and that's what I want to do here I want to be able to allow the user or the developer to write alert
and then include whatever content they want but I need to get whatever they want inside of there into my template somewhere right that's the goal and it's very easy with Angular because I can come into app.js and first of all I will set a flag transclusion is true that tells Angular that transclusion is going to happen
and then in my template I just need instead of making up my own stuff I'll use what the user said which is ng transclude and actually now that I think about it I don't think this is transclusion this is transclude
yes so now I have successfully transcluded the content out here into there and just so it looks different from the one above let's say this is the Angular directive which is spelled something close to that
so far so good so that's transclusion very simple oh yes thank you for letting me know this is not large enough is that better? thank you so transclusion
there's actually two ways to do this there's the easy way and there's the hard way if you just place an element inside of your template that uses the ng transclude directive that is where the content will be placed into Angular also has the concept of a transclusion function if you have to do something really fancy when you transclude
stuff you want to manipulate that markup you want to break it apart and put it in different places that's where in the linking function which we'll talk about later you can ask for the transclusion function that you invoke and it will give you back all those pieces inside an array of strings alright next topic
yeah let's talk about links so what do we not have working so far? well we don't have the colors we don't have the ability to click this to close it so one of the things that you can do with directives that you really shouldn't do anywhere else is manipulate the DOM directly
by walking up and touching an element so the link function that you provide is part of a directive definition object can include scope, element and attributes automatically that's not injectable like a lot of functions in Angular those are the set parameters that come
to you scope which is the current scope that you're operating with by default that scope is going to be the same scope as my controller that is outside that directive the element which is literally the HTML element that I'm operating with it's wrapped with the JQ light
API if you haven't worked with Angular before it offers an API around this element which is much very similar to jQuery's API when you wrap a DOM element with jQuery but not as nearly as many methods and not nearly as many features it's like the 20% of jQuery that you use 80%
of the time so yes I can do things with this element like add class so let's add a class of alert and I would probably also need to add alert dash plus warning but I want that to be parameterized for right now let's just hard code it see if this works because I think there's one more change
I might have to do but you understand where I'm going so far right I don't want the user to have to type class equals alert or anything I'm going to add it myself yeah so the one thing that's a little bit off here I believe is by default Angular throws my template
inside the original element which isn't quite what I want what I want to do actually is replace that element that looks better so I'm replacing that original alert element that was in there
and let's parameterize this how can I parameterize this well the nice thing about attributes is that I can walk up to attributes sorry and ask it do you have something for type and you might want to default it to something if it's not there so you either specify a type or I'll default it to a type
of info bootstrap has a warning info error something else too let's use that alert dash plus the type save everything very good let's just check this out index.html I say the type actually one is warning or info
yeah so it's a different color it's the calm blue color let people know they shouldn't be concerned um and now what about the button click event well before I write this I'm going to tell you that the reason I'm writing this link function is just to demonstrate that inside of here you have access to the element
and access to the attributes and you can do anything you want to the dom read any of these attributes but I have found that roughly 80% of the time I don't need to do this I'll show you a better way to do this in just a few minutes for right now I just want to show you that you can do things like yeah element.find
so now what I want to do is inside of my element somewhere I want to find the button and actually the button should just be standard everywhere I'm not going to force the developer to put a button in every place I'm going to include that in my template actually so I'll put the button there
and then transclude whatever other content they have that should still work I need to go and find that button so find again part of the JQ Lite API but unlike jQuery you cannot use just any selector inside of there it won't let you select by class or ID or anything like that you can only select by tag name
element name if you need fancier DOM manipulation what you might want to do is just include you can use jQuery and if jQuery is loaded before Angular Angular will use jQuery instead of its own JQ Lite implementation
let's find the button let's say when someone clicks on it I want to do the following function and by the way you don't have the usual dot click dot mouse over things you have to use on with the JQ Lite API let's just do something really devastating just remove the element from the DOM see if this works
refresh something went wrong my mouse didn't click correctly I guess if I click correctly it goes away so questions so far?
no, I can see everyone is fascinated or half asleep I'm not sure which hello with the element dot find and on there is a better way to do it I'm just demonstrating that you can do that inside of there
yep, yep, yep yeah, let's do it a different way I mean one problem here is that once the type is set it is always that type so I'm going to show you a better way to do this and along the way I'll also show you how this can be a little more dynamic let's say let's do this
inside the alerts controller I want to set up a scope dot alert some sort of data structure it says here's the message I want to display to the user this is a warning and the type of this is going to be a warning or maybe danger so this is dangerous
spelled something like that and let's just use this to build our alerts over here in the main template alert type equals let me interpolate in alert dot type and let's replace this with
message and then I guess to make it really fancy what I could do is add a button ng-click equals change alert because what I want to do is make sure that this alert can respond to changes in the model if someone changes the type or changes the message
I want that to make some visible difference in the page if that makes sense does it make sense ok so over in the controller let's add a scope dot change alert that is a function so when the user clicks on this we will say
scope dot alert dot type equals info scope dot alert dot message I could have just replaced the whole object I guess but we could say that was not a problem let's try this out refresh
I interpolated something wrong oh right right right now we have a couple of things going on so in my index dot html I alert dot message yes
I was hoping that part would work so if I change the alert notice the text change so the data binding just works even though it's in that transclusion I just changed the message, it changed what was on the screen but the color didn't change I also changed the info but because of the way our directive was written
it only read that type once and just stuck it in as a class so now what I need to do is I start needing to from inside of my directive be bound to something from the outside world in a more explicit manner message already takes care of that in one sense for me because that is using
ng bind it's data binding into the page but my alert type is not because I have it read out once here and just throwing it in as an add class so here's what I want to do I want to set up
sorry before I do that just one more thing I want to show you what happens if we have two of these whoops copy this and paste it and here instead of interpolating something I'm just going to say this is message two this should drive home a good point so now I have two instances of that directive on this page
and if I refresh and I click to close the first one the second one disappears this is mysterious behavior if I click the second one it goes away oh and what happens if I keep clicking around well
oh sorry sorry sorry that was not working the way I expected it I thought I was going to have a problem there well ignore that part for now right now let me do this sorry what if I want to give my users
the ability to respond to some type of alert and say alright I'm going to read what you type into here and I'll treat that as the reason that this alert happened maybe I can demonstrate that behavior this way so that's a little bit better what happens when I type into the first directive is that it appears in the second directive
because by default the scope object that I'm receiving is the same as the controller I'm inside of so it's this object and since both directives are writing into the reason property
into that same scope object this stuff shows up both places the other way I could have seen this I forgot is if I would have tried to do something like scope.close equals a function and what function will do is element.remove so I'm trying to get a little bit fancier and get rid of this fine stuff
I'm going to expose a close method on the scope object and tell it to remove an element and I go into my alert.html the other way I could have handled the close would be to say ng-click equals close and see what that does so I click on the first one
and the second one disappears that time it happened, right? no? yes? yes I click on the first one, the second one goes away again, that's because these things are sharing the same scope object so what is happening here is that when I write scope.close for the first directive on the screen
it grabs and forms a closure around the first directive element and so if I were to just have one on the page that would be fine but the second instance comes along rewrites that function forms a closure around the second element and that means it doesn't matter how many of these things I have here, I can only close
the last one on the page does that make any sense? maybe I know it took a while for it to sink in for me alright, so this is completely broken and I have all sorts of problems here if I try to change an alert, things aren't updating the color's not updating, if I try to close alerts things aren't happening what I really need to do is get away from using the same scope
as my parent controller what I want to do is create what's known as an isolated scope which means my directive will get its own scope object things I put into it won't conflict with anything else just by writing that one line of code well, three lines, but you could have put it on one line
just by isolating the directive like this if I refresh and type in here notice it doesn't appear in both anymore because it's going into a reason property on that scope for the first directive instance and this one is completely separate but now that fixes some problems I'm not overwriting things
I should be able to close both of them now so that part works but I still need the ability to get the things to the outside world I still need the ability to maybe my controller wants to find out what this reason is what does the user type inside of there
my controller might want to set messages independently might want to change the color still so what we're going to do is look at a piece of Angular that honestly baffles a lot of people we're going to look at how to set up binding between an isolated scope and the parent controller scope or some expression that could represent anything
these isolated scopes by the way usually if you have a controller inside of a controller in Angular the inner controller its scope object prototypically inherits from the outer controller it's not the case with directives it doesn't matter where that directive is it's isolated scope only prototypically
inherits from root scope which is the mother or the father of all scopes inside of an Angular application but once you have one which you do just by saying scope empty object now you can start adding certain declarations inside of that isolated scope so that Angular will
bind stuff to the outside world so the first one we'll look at well we're going to look at three we're going to look at at equals and ampersand they are a way to form a bridge between some outer scope a controller scope, root scope, somewhere and an isolated directive scope that's what these three things do
I want data from here to just automatically move into my isolated scope and if I change it here I'm going to automatically propagate it back to my controller scope that's the goal or I should say with an outside environment because the first thing we'll look at whoa, someone screwed up their animations there
is how to set the stage on fire how do I how can my scope reach out and grab an attribute value that is specified in the markup and keep things updated if that attribute value ever changes that is the purpose of the at
inside of an isolated scope so when I say scope type is an at that's telling Angular to automatically look for an attribute with the same name it has to have the same name if I do it this way type and to take that value that is inside of it info and just automatically
move it into that property of my scope object so if I do those I could say scope type attribute I no longer need to do I no longer need these attributes I can get rid of them whoops but not the lower curly brace there I don't need to read attributes
anymore because the attributes that I need I can just move them in here I could have as many of these as I want so there could be a type and there could be bind something called message as an attribute but what this means is my scope will now have a type property a type property will come from, sorry
here and for right now let me get rid of the two alerts so it's not too confusing that will come from here let me just hard code it for a second info so we can see this working and what I could do instead of that add class stuff inside of here is also use some data binding out here and just say my class
I want it to be alert alert dash type and interpolate it in see if that works sorry, yes it's an info so now let's try to wire it up dynamically
instead of hard coding it I want it to be alert dot info that's a problem typically when you write an expression in angular like if you write an ng model thing you just write ng model equals reason or ng model equals alert dot something but when you do attribute binding
sorry, when you do attribute binding like so angular is always going to read out the string content to the attribute directly it's not going to try to treat this as some sort of expression to evaluate therefore I always have to interpolate that with an explicit binding
so alert dot info and now if I come out here it should make sure I saved everything it should should, should, should oh sorry, what did I do? oh alert dot type
it wouldn't have worked this way either without those just to prove a point alert dot type and now if I change this alert color changes too so the attribute value changes that scope binding will automatically
pull in the new value that gets placed into here and put it in if that makes sense alright, next thing I want to do is perhaps actually use this reason and try to get it out of that directive and into my controller or do some two-way data binding with it
and that is done with an equal so if I say reason equals what angular is going to do is look for a reason attribute here and take this expression so I don't need to interpolate it in anymore with the binding expressions, take that expression
and essentially set up a two-way data binding between that expression and my isolated scope so if I change reason in the scope it should automatically be pushed into whatever is specified here and if anything is specified here or changes here in that expression it should be pushed into my scope in other words
let's come into our alert and let's start off with an initial reason just say default reason or please fill out anything like that and then what I want to do in my HTML
is I want to tell my directive that the reason it should be looking at is alert dot reason so I want to set up that binding there and in order for that to work in the directive itself I will need to say
reason equals so two-way binding there and now just check my template real quick I do have this set up to be ng model equals reason yeah so refresh the page and you can see default reason appears there
because it's pulling it out of that expression and if I change it we're not showing it but it would be pushed back into the controller, let's show it real quick over in index HTML outside of the directive let me bind the reason and what we could also do when someone clicks to change
the alert I could say scope dot alert dot reason blank it out or something so that's data moving from the controller scope into my directive that's information being changed in my isolated scope but being pushed out to the controller scope and again
change it in controller scope it gets pushed back into my isolated scope really interesting stuff isn't it? I think, simple anyway once you understand the crazy little shortcut syntax which is ampersand and equals so we're just saying
look for an attribute and take that expression bind it to my scope and finally there's ampersand which is basically a way of saying I expect this to bind to something that I can invoke by applying parenthesis and that's going to stimulate some
behavior in the outside world I don't know what it's going to do, it could close something it could navigate somewhere, make a web service call all I know is that in my isolated scope I'm going to have a member called close and if I invoke it something's going to happen so as a directive developer I might want to say
I'm not going to close things myself what I'm going to do is expose this close member to you so that if you set up that expression I promise to invoke it at the right point of time and then you decide what to do you're out there in the controller somewhere but it has to be called close so in the markup
when I'm using this directive I can say oh, you gave me a close well, for close what I will do is say let's invoke something on my scope called close alert and let me just set up one additional thing here, I could say that this should only show
show show when alert is truthy so the template does an ng-click equals close where that's going to map to now when someone clicks on that close button is it's going to come into my directive
and because of this binding say yeah, we're going to invoke a function that was given to us, an expression that was given to us the expression that was given to us was close alert so now let me go off and look for close alert on this outer controller scope so inside the controller it is now responsible for the closing
stuff, so scope dot close alert, notice the name is different what it could do is just something like scope dot alert equals null, that would be falsey and I think I did everything correctly so if I click on the close button because of ng-show then it just gets rid of
everything, right questions? I see concerned looks for this one yeah, this
I was confused by this for a long long time and I think it's kind of unfortunate with angular some directives when you use them as an attribute like this you specify an expression that is, if I type something in here like alert dot type or alert dot whatever angular is always
always going to treat that as an expression and something that has to be evaluated against scope so that is telling angular because of the way ng-show is built please go up to the current scope object and look for a property called alert and if it's truthy we show things if it's falsey we hide things so
inside of ng-show I imagine they have something set up well I won't pseudocode it they could have an equals symbol there, they're doing model binding but this one has to be interpolated unfortunately because my directive was written in such a way
where'd it go? up the screen to use this attribute binding instead of the model binding and so that's saying just pull something out of the attribute for me and quite often you might want to do that because a lot of times people are building these things and they don't want to put something in the model to get a value there, they really do
just want to say type equals info and be done with it but if they do that that's fine the way I had things set up with at, but it's never going to be treated it's never going to be treated as an expression like this one yeah I need to say alert.type
to make it dynamic and actually interpolate that into there it's confusing and I used to get frustrated with it actually so I didn't know when to use double curlies and when to use an expression
so to go, yeah, that's a good point just to go the other way there are some directives like ng-include this used to happen to me a lot, you would think oh, ng-include, I just want to hardcode a path here that says go to slash views, slash
partial slash shell login.html right maybe a relative path but ng-include treats this as an expression so it walks up to your scope object and says where's the views property, there is none so this thing doesn't load
the way you treat this as a constant expression is to delicately place those single quotes around it so that that angular parser says, oh, that's a string so yeah, we go to views paratallies or whatever french word that is you can get the login view
and I could do that here if I said type equals and used a single quote around this if I refresh the page and look at the DOM I imagine we'd see class equals squigglies alert dash type there that's not what I want though
good so far? more questions? because this if we just go back and review the directive briefly wasn't a whole lot of work and in fact I added some additional strange features in there to demonstrate different things but it might have made for a slightly nicer
user experience developer experience to be able to say, hey, I want to write things like this alert type equals and just have things automatically close and everything else for me so yeah, some people call directives some people say that the directives give you the ability to write
a DSL in HTML that's one way to think of it let's talk about some plumbing now some of the mysterious parts of directives so you can, inside of a directive also specify a controller in other words
in my directive I could say controller is a function that takes scope and element also services if it wants services or I could say controller equals ng-alert controller something like that specified in a separate file
angular will find it and attach it to this question is why would I want a controller what would I do in a controller that I couldn't do in the link function because we already saw the link function you can attach events, you can manipulate the DOM controllers inside of a directive to me are good for two reasons
one is if I have a lot of complicated logic or doing calculations or manipulating scope hopefully I won't do too much of that inside of a directive but if I do if I can pull that logic out of the linking function and into the controller well the controller is a separate nice component that I can just instantiate in a unit test and fire some things off against the scope and write a search
so it can often be easier to test a controller because it's just a function that modifies the scope easier to test that than link which requires me to dig around with directives and do all sorts of other things but the second reason to create a controller which is quite often used inside of angular itself is to actually
create an API for other directives to talk to each other so if you create a controller for a directive and you create an API not by adding things to scope but by adding things to the controller object itself so this dot and some function
inside of some other directive you have the ability to tell angular hey I have this alert directive in order for me to work I require some other directive as a sibling or as a parent and I need to talk to the other controller so that I can tell it that certain things have happened inside of my alert
this happens all the time with ng model and ng form I don't know how much angular you've done or if you've done any form validation with angular but if I say form name equals edit form form in case you didn't know it is an angular directive
so literally someone has written in angular app dot directive form because you can take control of just regular HTML elements they don't have to be special well and then inside of that form I have an input type equals whatever but it has an ng model
equals username something like that ng model asks for the ng form controller so that it has an object it can walk up to and say someone just entered text into me so consider yourself dirty or someone just wiped out all of the text inside of this input and
there's a required attribute here so dear form please consider ourselves invalid and ng model and ng form have this communication back and forth because they look kind of like this let me show you an example using a slightly different project so I don't have to type I'll type out all the code
but let me start from here here's a slightly different alert this one has an alert header directive nested inside of it so if I look at the definition for this alert header what I will find is
that alert header says hey I require two controllers this is a way to say that I require other other directives to be in place and again it's a weird goofy syntax and it's an array so it actually requires two things first of all this is saying I need a parent alert
that means I am so sorry about random jumping around let me close some windows so that I am always opening up the right window here start this again real quick I require a parent alert in other words
if alert header was not inside of an alert there would be a problem because that one line of code says alert header I need an alert to be a parent somewhere please give me a reference to that controller and then I need my own controller to be passed into me that will always pass because if you are
an alert header and you need an alert header controller it will just happen so the way this works is when you require other directives to be present they will be passed in to this controller parameter which is really controllers because it can be an array if you require multiple things and the first thing in here
will be the first thing you require and the second thing in here will be the second thing that you require so now inside of my linking function I have access to two controllers that have an API and when things happen like a click event I can walk up and invoke methods on those other controllers this is not something we do
in regular Angular outside of directives you don't get references to other controllers and invoke things on them but it happens with directives quite frequently because they are so bound to the DOM and they are the plumbing that makes things work what is modify reason or look at modify reason on the alert controller
there is alert it specified a controller of alert controller so that is way up here it provided an API for other things to call into it and modify something tell it to do something let me show you another example
this is a little directive that I had to sorry about that this is a little directive I had to write because I wanted to be able to create an inline editable table I wanted to be able to write TD with the content editable attribute which is an HTML attribute and then use
an ng-model so that I can actually push values between a table and something in my scope and actually to make this a little more concrete I will flip around a little bit more and just show you something real quick which is
when I am editing this report I want to be able to come into this name thing and I want to create a table for the user where they can type in identifiers that is interesting
let's try it over here here we go so identifiers are over there I just want them to be able to click on that and type so what are these TD cells these are TD cells with this content editable directive that you see right here
unfortunately if you put content editable and ng-model on a TD cell it just does not magically work with angular ng-model does not exactly how to understand how to work with a TD cell so I had to write a custom directive that basically says sorry whenever you see this attribute and you see and you can get a hold of an ng-model controller
then what I want you to do is this I want you to watch for any time the user basically types a key and when that happens I want you to read what is inside of the HTML and then maybe do some processing but then this is the API that ng-model exposes through its controller
I am telling ng-model here is what is in the view you call $setViewValue on ng-model and it says oh that is what is in the view maybe I will push that through onto the scope object and that way I can get two way data binding with this hopefully that makes some sense
here is the API provided by ng-form controller and ng-model how does ng-model tell the form that things are suddenly not clean or dirty anymore it does that by calling methods when the user interacts with the page and these are the properties that you can actually check to see if a form is valid or invalid or so forth
ng-model actually quite advanced behind the scenes you can do things like setup formatters and parsers so when I tell ng-model here is a new thing from the view it can have a collection of parsers that parse that value and turn strings into integers and things like that and on the way back out you can provide formatters to turn integers into
or well JavaScript doesn't have integers to turn numbers into something with two points after the decimal or something like that hopefully that is making sense and yes I am zipping through this part of the presentation because this is the stuff that you might
only need to know 10% of the time you can get really far with directives just using the stuff that I showed you earlier remember to use apply so one of the common problems I see with directives is that you are using a directive because you want to integrate with some third party jQuery plugin that you like or because there is an event that you need to capture that Angular doesn't already provide you a
directive for it, so you write something that uses element.one hooks up to a native event and when it happens you start doing things that will change the scope Angular doesn't know that that code is executing so it doesn't do a digest phase and propagate changes unless you wrap things
inside of a scope.apply scope.apply is the magic bit of telling Angular hey I am about to do something that is going to change some scope values so once I am done once you execute this function the very next thing you probably want to do is look for anything that has changed so you can push new data into the view
without scope.apply you can modify things and not see the result appear on the screen which is very mysterious so just remember Scott Allen told you if you modify something and it doesn't appear and there is no errors in the developer tools make sure you don't need a scope.apply because you are doing something with native events like this.
is something that people will do from directives also you want to set up a watch on some expression so I want to watch something on my scope called text perhaps there is the same thing for observe this allows you from inside of a directive to do something to the dom element when a scope value changes
it is very useful and yes now we are not on the summary just yet compile what I will tell you about compile is this compile is only useful if you are really trying to optimize a directive so you are writing a directive that is going to be used
by lots of people and lots of other developers on mobile devices and it does a lot of DOM manipulation that is when you want to use compile because here is what compile will do when you have a directive like this
what Angular actually does first is look in your directive definition object to see if there is a compile because the first thing it would call on your directive definition object before anything else is that compile function and it will pass you the element in that compile function so that you can do any DOM modifications that you want
if I were doing a lot of DOM modifications inside of my directive which I am not then I do not need to worry about compile I can just write a link function and that is fine the big difference between compile and link is this if you are inside of an ng-repeat
and that ng-repeat executes 10 times so just to make this a little more concrete div ng-repeat equals i in sorry I already am in a repeat
thank you this is the other project I will show you how this works real quick run in browser control shift w it was setting up a repeat and I will make this demo code available to you so you can add new alerts dynamically but when you are inside of a repeat
if you have a link function that does DOM modifications for this element that you need to do before you place it into the screen if you write those DOM modifications inside of a linking function they will get applied that will have to run 10 times
and modify the DOM 10 times each time this alert appears if there is 10 items in alert the reason to use compile is because what compile can do is if you can get away with doing your DOM modifications right here they will happen only once and then that element
that you have modified and dressed up and massaged to look just the way you want it will be cloned and stamped out 10 times to fulfill that ng-repeat that is really one of the only reasons to write compile I want to do one DOM modification and then clone my element multiple times to get it into the page
and then when you write a compile you return basically your linking function that is the linking function that we wrote so that is a bizarre piece of Angular if you want to see some more details about that I'm not pushing my blog or anything but I did a recent post and you can actually see I have debugging output
that shows you exactly when they execute exactly what the element is at each step of compile and link but if you remember anything from this presentation remember that I flipped around a lot and remember that directives can be somewhat simple
but give you some nice benefits and with that I will say that I think that's all I have to tell you today I hope you enjoy the rest of the conference any questions? I'll get this code available somewhere and if you want to email me to get a copy of it just let me know
very quiet crowd everyone just went to coffee well thank you for coming