Forward Advance Learning

Writing Components

Components were introduced in Angular 1.5. They let us define directives with sensible defaults for creating a component based architecture.

A component oriented architecture is an app built from multiple isolated directives. Data is explicitly passed in using '<', and events are used to send data back out using '&'. Apps built in this way can be much more scalable because each component can be thought about in isolation from its surroundings.

Here's a simple footer component:

angular.module('app', [])
.component('appFooter', {
template: `
<footer>Thanks for using the app.</footer>
`
});

This gives us:

  • A default empty controller.
  • An isolated, empty $scope.
  • bindTocController, so we have a $ctrl attribute of $scope that contains the controller.

Here's a more complex example that defines an isolated $scope. We pass in the cheese using one way binding, then fire an event when the cheese is eaten.

angular.module('app', [])
.component('cheeseView', {
scope: {
cheese: '<',
onEat: '&'
},
template: `
<input ng-model='$ctrl.cheese' />{{cheese}}
<button ng-click="$ctrl.onEat()">Eat Me!</button>
`
});

We would use this component like this:

<cheese-view cheese="Gouda" on-eat="eaten=true"></cheese-view>

One way binding

This component is using one way binding. The cheese is passed down into the component. Data goes down the tree using attributes. If we want to pass data back up we use events.

Exercise - TODO

We ae going to ceate a little TODO app using components.

Download the start point, you will find an app component and a skeleton todoList component. Verify this works.

Create header and footer components. Hooray, easy win.

Use one way binding to pass the todo list from the app component down into the todo-list component.

Use and ng-repeat to loop over the list and output the results

For bonus points create a todo component that renders a single todo. Pass this todo in with one way binding.

Extension Add more TODOs

Create a todo-entry-form component. This will let you type in a new todo. This component should emit an on-new-todo event using the & binding. When it does so, append the new todo to the list in the app component.

Double Extension - delete TODOs

Add a button to the todo component that emits an on-delete event. This should send a message up via the todo-list to the app (you will need to emit two events, one from the todo, and one from the todo list. The app should then delete the todo from its list.

The finished app structure will look like this:

app
header
todo-list
todo
todo
todo
footer

Harder Exercise - Flickr

Modify your Flickr search to use components.

Create header and footer components for the app that look suitably swish.

Make a search box component. It should receive a term parameter, and emit an on-search event, which you will deal with at the app level.

Create a flickr search results component

It should receive a term and do a search whenever the term changes. You may need to $watch term to make this happen.

Have the flickr search results pane emit start and complete events when the search starts and completes

Create a spinner component

Have it receive a visible parameter. When it is visible, it spins. When it is not visible, it doesn't spin.

Your app structure should look like this:

app
search-field
flickr-results
spinner