Lesson Tuesday

Let's start adding some interactivity to our to do application. In the past, we used jQuery to add interactivity to our user interface logic. For instance, we might use jQuery to do the following:

$(".clickme").click(function(){
   alert("I've been clicked!")
});

We can do something very similar in Angular with an event binding. We can attach an event binding to any DOM event (such as a form submission or button click). We can then trigger specific code to run whenever that event occurs.

We'll add an edit button to our To Do List application to test this new concept. For now the button will trigger an alert message. In the next lesson, we'll complete the edit functionality.

Anatomy of an Angular Event Binding

A basic event binding goes inside the HTML template and looks like this:

<button (click)="someMethod()">Click me!</button>

It's composed of three primary parts:

  • The HTML element it's attached to. In the example above, the event binding is attached to a <button>. You can add event bindings to almost any HTML tag.

  • The target event. This is the event that must occur to trigger our code. In the example above, it is click. The target event is always represented by the name of the specific DOM event between parentheses. As you might have guessed, we could use other events in place of click such as keydown or focus.

  • A template statement. In the example above, someMethod() is our template statement. The template statement is a method call or property assignment that runs when the target event occurs.

Adding an Event Binding

Now that we understand the structure and purpose of event bindings, let's add one to our application. Eventually we'll want to edit and update our Tasks. Let's add functionality that allows us to click on a Task. For now, it will just create an alert. In the next lesson we'll add editing functionality.

First, let's add an event binding to our template:

app/app.component.html
...
<ul>
  <li *ngFor="let currentTask of tasks">{{currentTask.description}} <button (click)="editTask()">Edit!</button></li>
</ul>
...

In the code above we add an event binding inside our repeater directive (the <li> with *ngFor). This is because we want to add an edit button for each Task. Refresh the page and we'll add a button next to each task.

However, if we click the button we'll get a console error. That's because we haven't defined editTask() yet. We need to define the method in the corresponding component's class declaration. We still only have one component (the root component) but we'll soon have more. If we tried to define the method in another component's class declaration, Angular wouldn't be able to find it.

Let's add an editTask() method to our component's class declaration now:

app/app.component.ts
...
export class AppComponent {
  ...
  editTask() {
    alert("Time to edit a task!");
  }
}

If we refresh our application, we'll see the alert pop up when we click on a task's edit button. Let's review what we've covered so far:

  1. We attached an event binding to an HTML element: <button (click)="editTask()">Edit!</button>. It includes a target event of click and the template statement editTask().

  2. When the target event occurs (the button registers a click), Angular takes the method from the template statement and looks for an editTask() method in this component's class declaration (the AppComponent class).

  3. The logic in the editTask() method is executed, triggering an alert.

In our example, all of the data is flowing in one direction from our HTML template into our component's class declaration. That is why event binding is also known as a type of one-way data binding.

One-Way Data Binding

One-way data binding may sound complex at first but, we can break it down further. In one-way data binding, data flows in one direction. For instance, in the event binding we just created, the data flows from our HTML template to our class declaration. However, nothing is going in the other direction; the method in our class declaration isn't telling our HTML template to change!

We can visualize the one-way flow of data like this when we use an event binding:

one-way-data-binding-diagram

  • When data flows in the opposite direction, it's known as a property binding. We'll be covering property bindings in the next lesson.

  • When data flows in both directions, it's known as two-way binding. We'll be covering two-way binding after we've finished covering property bindings.

The concept of data flow can be confusing at first but we'll discuss further in upcoming lessons. Once we understand data movement in Angular, it will become much easier to visualize and work with Angular applications in general!

Additional Resources

For more information on event bindings, check out the Event Binding entry of the Angular documentation.

In the next lesson, we'll explore property binding.