Ngclick Assignments

Getting used to the concept of in Angular is among the more difficult concepts to fully grok when first being introduced to the magical land of Angular.

Like anything else though, "once you understand it, it's really not that bad"...

$rootScope

This is the mother of all scopes. Quite literally. All other scopes in Angular descend from it. The is created on the DOM element where you set up .

You can prove this to yourself by simply adding to the tag of a page, and running this in the console...

That will log out the in the console.

If you go run any of the hello world examples for angular out there now, such as one like from the Angular home page...

There is a directive here on the input called . The job of a directive is to link and element to a scope, and allow you to work with that DOM element by adding behavior, or transforming it.

The directive will bind , , and elements to a scope.

In this case, this directive is linking an element to the by adding a new property to it.

Angular attaches to the change event of that element. Any time the change event fires, angular updates the value of on the scope with the value of the element. This in turn tells anybody interested in the value of that its value has changed. This is all done through angular's crazy dirty checking stuff.

In this case, there's no property defined on yet, so angular will just create it for you.

That concept is all known as 2 way data binding; the concept of changing a model value which gets reflected in the UI and changing a UI that gets reflected in the model.

$scope in controllers

The first step to understanding in an Angular controller is to truly understand what a controller's job is in the first place.

The job of a controller is to pass data from the model, to the view.

That's it. Plain and simple. The view (aka user) asks for something from the controller, and the controller turns to the model and says, "hey, I need this thing". Then the controller takes that thing, and hands it back to the view.

Controller are meant to be thin, and testable by keeping as much of your problem solving and state manipulation code inside of a "model".

I generally think of the "model" in angular as a combination of angular services, and simple objects that you attach to scopes. So in essesnce your model can be whatever you want it to be which can be a little confusing at first.

The general idea though is that whatever your "model" is, you use to tell your view about it. This is why some people will call a "viewModel".

A controller's job with respect to Angular is to set up functions and properties that the view can use. The primary way you set these functions and properties up is by injecting into the controller.

When you use the to bind an element to the view, a new is created which prototypically inherts from the .

You can then attach these values to the view with directives and expressions.

Nested Controllers

This is where things get weird...

Controllers can be nested so you have to be careful about a few things. Because of the fact that the scopes do inherit from other scopes, if you create a primitive value (string, number, boolean) on a parent scope, the child scope will have an be able to manipulate the value.

What will happen though is if a child is changing primitive values on a parent, it will end up creating a copy of the value in the child, and break the inheritance chain.

This can be avoided...

should always have a "." in the name

As a rule of thumb this can help avoid the problem of overwriting a parent's scope values.

When you add a object onto a controller's scope, you can edit that user object's properties in the child and not break the inheritance chain from the parent.

Another thing you can do when nesting controllers is use the newer controllerAs syntax.

Using the controllerAs syntax is a small syntax change that can just add some clarity to where different values come from.

Notice how in the controller rather than assigning the values to , they are actually assigned to .

Don't let this fool you too much. When you use this syntax, that simply means it will take the values you put on , and under the covers, assign them to .

Using is effectively the same thing as this...

It's just a little cleaner to not have to use when you don't need to do anything but assign values and functions.

scope in directives

Another sticky place when working with scopes in Angular is when writing custom directives. Part of the confusion comes from the fact that when you create a directive, one of the properties you pass on the directive definition is ...

There are a few options when setting up scope for a directive. First of all, the default value for this option is .

This default can lead to some dangerous issues especially when trying to create re-usable directives...

When you have , the a new scope will NOT be created for this directive. That means it will use the parent scope by default. So, if you think you're creating a property on a scope local to your directive, you are in fact actually creating a property on the parent scope. Not a very re-usable solution.

Another option you have is to pass .

Passing this option will tell angular to create you a new child scope for this directive. This child scope will be similar to how the scope in the works. It will prototypically inherit from it's parent in the exact same way.

This means you'll have access to the parent scope, but also be able to add new properties to a scope local to the directive...

In this example you can see that because of prototypical inheritance, this directive's scope will have access to a parent property. The difference now though is that when a NEW property is added to the scope, it will be created locally within the directive's scope and not directly on the parent scope.

The Isolate Scope is the most complicated form of scope for directives.

When an object literal is passed as the parameter value for on a directive, a new scope is created for the directive. It still inherits from the parent scope, however only the named properties from the parameter will be passed into this new isolated scope.

You can almost think of the option as a filter with three different ways of filtering. You can see each of the three in the previous example: "@", "=", and "&".

Here's examples on how to use each of the three methods.

=

You would then use this directive like...

By adding to the property of your directive, you've basically setup a way to pass an object from the parent scope down to the directive scope by using as an attribute on the directive.

It's also worth noting that if you wanted to, with any of the three scope properties you can pass an optional alias name along with '=, @, or &', there will be an example of this later.

When using the sign as an option you have basically set up a two way binding between the directive and the parent scope. If you then change in the directive, the change will be reflected in the parent's property.

The option will always be a single string value (no {{}}'s are needed here) representing some property on the parent scope of the directive. So, here in the previous case, is a property on the 's scope.

When you type in the input box generated by the directive, you'll see . Changing the value of this text box will actually end up changing the from !

@

The option of scope is a way to pass in a string value, or a value containing 's that will get interpolated.

This is effectively a one way binding. You cannot change the value on the directive scope and have it be reflected in the parent scope, unlike with the option. If you want to reference properties from the parent scope, you must use the curly braces around them. Whatever you pass in as the value of a property that uses the option will be interpolated.

Here's an example...

And this is how you would use that directive...

Notice that in the the , is a value on the parent of the directive in the .

On the directive scope, because of , you'll see that you can pass values via the attribute and the will be added to the scope. String interpolation will kick in, and is going to equal "Austin Danger Powers". That's also what the template will render.

&

The last option for in a directive is . This allows you to fully invoke an expression within the context of the parent scope. You basically get a wrapper function that wraps whatever you pass in so you can invoke it in the directive.

The following example is a bit trivial, but in order to fully understand this concept, it's a good place to start.

So, you can see here the . This means that in your , you'll have a available. You can then use that function in the scope of the directive and pass in values via a hash map that will execute in the parent's context.

The way this works is by passing in an object that has keys which match the arguments you pass in via the HTML when you invoke the directive...

See how here in the HTML you have...

Here's one more practical example of how you can use this option in a directive scope...

In this example, there's 2 inputs in the template. One bound to , and one bound to . Since neither of these are previously defined in any scopes, they'll be added to the directives isolated scope.

Then the button has an directive. Every time that this button is clicked, it will evaluate the expression. Since the function is defined in the parent directive, and passed in through the , you can then pass in the map of values to execute the add function.

Since simply retuns a value, you can then assign which will then be another value in the directive scope and can also be used in the template with .

Conclusion

Hopefully this helps groking all the scopes in Angular! There's a lot of things to fully wrap your head around with Angular and this is just one of the pieces. Like learning any framework though, it just takes a bit of time and practice to get things really going and fully comprehended.

In an angular directive you can use a function in the parent scope by using the ‘&’ function binding. Why would this be needed?

In this example a teacher is creating an online assignment to witch he wants to add some students from a bigger list. To add students a popup is opened to get and show all the students to choose from. This popup is an element that will be used at more places in the application and is therefor an angular component. This is where the function binding is coming in handy. The teachers assignment needs to know about the added students, but the students in the popup and the teachers assignment live in a different angular scope. The function binding allows you to call a function on the parents scope. So from the directive containing the students you can call a function on the controller of the teachers assignment. Lets get out the code to show how this is done.

Code example

Parent JavaScript

On the controller handling the create-assignment.html is the function onAddStudentsParentScope that needs the students from the popup. At this moment this function does not have access to students. To fix that we connect this function to the add-students component.

Parent HTML

On the parents HTML, where the teacher is creating the assignment there is a button to open the add students popup. For the popup itself you see the components add-students tag. The onAddStudentsParentScope function is bound to the on-add atribute in the component tag. This makes it accessible on the scope of the component

Popup JavaScript

On the component definition you see the bindings. There the onAddStudentsParentScope function is bound to onAdd with the “&” function binding.

Popup HTML

So the idea is to call the onAddStudentsParentScope function from the popup. For the HTML that is quite straightforward. You can use the onAdd binding and call it as the parent function.

Call from Javascript

Calling it from HTML is nice and all, but what if you need to do some stuff before or after you send the students, like formatting the students array. It is also possible to call the parent function from JavaScript. Lets look at how that is done.

First thing is making a function on the controller of the addStudentsComponent. In that function you can call the parent scope function.

In the HTML you only have to change the on-click to the new function in the controller.

Good luck coding with Angular function bindings.

 

 

0 thoughts on “Ngclick Assignments”

    -->

Leave a Comment

Your email address will not be published. Required fields are marked *