Enter Your Email Address to Watch This Lesson

Your link to unlock this lesson will be sent to this email address.

Unlock this lesson and all 986 of the free egghead.io lessons, plus get Angular 1.x content delivered directly to your inbox!



Existing egghead members will not see this. Sign in.

Directives Talking to Controllers

4:43 Angular 1.x lesson by

Often in AngularJS we want to share information between controllers and directives. One way to do this is by passing the scope, but this makes the directive reliant on the scope having the methods you want to run. This lesson shows you a cleaner way that you can pass methods to the directive using an attribute and decouple controllers from directives. This in turn makes your directives more generic/reusable.

Get the Code Now
click to level up

egghead.io comment guidelines

Avatar
egghead.io

Often in AngularJS we want to share information between controllers and directives. One way to do this is by passing the scope, but this makes the directive reliant on the scope having the methods you want to run. This lesson shows you a cleaner way that you can pass methods to the directive using an attribute and decouple controllers from directives. This in turn makes your directives more generic/reusable.

Avatar
marcek

What if you want to keep the directive isolated from the controller's scope ? Wouldn't be better to pass the controller's method reference to the directive by "&" ?

app.directive("enter", function() {

    var linkFn = function(scope, element, attrs) {
        element.bind("mouseenter", function() {
                scope.enter()
        })
    }

    return {
        scope: {
            enter: '&'
        },
        link: linkFn
    }
})
In reply to egghead.io

John Lindquist: Let's talk about how you can communicate with controllers from your directives. If we create an app, we'll just do a simple twitter app. Twitter apps are like the hello world apps of today. We'll do a ng-controller, call it "app controller." A lot of apps have those. Then we'll have that same sort of functionality where if you roll over something, we'll say "load more tweets." We'll say "roll over to load more tweets" in the content of this.

Then we'll have our directive here be that enter directive that we created before in another video. We'll just set up our app. It'll be a twitter app, no dependencies. The controller will be "app controller." This will actually take a scope right here. So we'll say "scope load more tweets." So function and an alert to say "loading tweets." We'll get into actually loading data in later videos.

Then we'll create a directive, which is just an enter directive to return a function, which basically says we did this before as well. Scope element attributes and element, bind, mouse enter. Let's make sure this is working. Enter. Roll over and it looks like it's working just fine. What you could do here is just say because we have access to this scope you could say "scope load more tweets." And roll over and it'll give you the alert to say "loading tweets."

That's probably not the best way to do it. You're not sure that this scope is actually working with this scope. You're also not sure that this really binds the enter directive to this app controller. You want to keep them separated by passing in what you want to call into the enter directive. Let's say enter "load more tweets."

Before we even do that, let's look at what we could do here which would call it pretty much the same way. If you say "scope.apply" with a dollar sign, don't forget the dollar sign. That's the accessible things Angular JS provides, the services they provide. I say "load more tweets from here" and pass in a string. This will kind of parse this string and find it on this scope and then invoke it. So you can see I get the same result here, "loading tweets" as if I invoked it directly.

What this allows us to do is to take that attribute instead of passing a string to load more tweets. We can take the attribute that we pass in here and just say "load more tweets" and pass that into the enter directive. This will work the same. Say for example you wanted to create another method here. We'll say "delete tweets" and alert, "deleting tweets." Now instead of loading more tweets, we want to delete tweets. When you do this it will say "deleting tweets" and that keeps a nice separation between our enter directive and the controller itself.

See how we can reuse this directive and not have to worry about what the controller's doing. All we know is that whatever we pass into the enter attribute is what's going to get invoked. We'll get into more detail on some of these scope issues and things in future videos.

HEY, QUICK QUESTION!
Joel's Head
Why are we asking?