Build Lightweight Controllers by Binding to Models in Angular

Lukas Ruebbelke
InstructorLukas Ruebbelke
Share this video with your friends

Social Share Links

Send Tweet
Published 8 years ago
Updated 5 years ago

In Angular, our controllers should be small and focused on the view that it is controlling. We accomplish this by moving as much logic and state as we can into models. Angular 2 introduced observables and async pipes which make it easy to manage state and communicate that directly to our templates.

We can start to point our Angular 1 applications in that direction by binding to our models directly from within our controllers. In this lesson, we will see a simple example of this technique and a slightly more advanced case where we lose the lexical reference to the this keyword.

[00:00] In Angular we want to keep our controllers small and focused on the view that it is controlling. We accomplish this by moving as much logic and state as we can into models.

[00:09] Angular 2 introduced observables and async pipes which makes it really easy to manage state and communicate that directly to our template.

[00:17] We can start to point our Angular 1 applications in that direction by binding to our models directly from within our controllers. In this lesson we will see a simple example of this technique and a slightly more advanced case where we lose the lexical reference to the this keyword.

[00:32] We're also going to do a bit of review as we build out the bookmarks component for this example. I have created a bookmarks model, which you can see here, and I have added it to the common module.

[00:46] I've also started creating a bookmarks component and have added the styles and the HTML, which you can see here. In the HTML we're just doing an ng-repeat over the bookmarks collection and here are the styles with the active style being the most important one.

[01:04] We'll get started by jumping into the bookmarks controller. We're going to define our bookmarks controller class, and then we will define our constructor, and we're going to pass in the bookmarks model.

[01:19] We'll add in ng-inject, and then from there we will assign a local reference to the bookmarks model. Then in our $onInit event hook we're going to fetch the bookmarks from the bookmarks model. Then we will assign the results of that to this.bookmarks.

[01:49] From there let's export this, and then we'll jump into our component, and we'll hook this up so import template. Then we'll import the controller. Then let's import the styles. From there let's define our component configuration object so bookmarks component.

[02:31] Then we'll set the template, the controller, and controllerAs we'll give it a property of or value of bookmarks list controller. From there let's export this. Then we will hop into our bookmarks module, and we'll build this out, import angular from angular.

[02:57] Then we will import the bookmarks component. Then we'll define our module, so bookmarksModule = angular.module.

[03:12] We'll give it a name of Bookmarks, no dependencies, and then we'll add our component to it using .component, bookmarks as the selector, and we'll attach the bookmarks component object to that.

[03:28] We'll export the bookmarks module, and then from there we'll hop into our components module and we'll add this as a dependency so it is available for the rest of the application.

[03:50] Now that we've imported it let's add it in as a dependency, and then from there let's hop into app.html. We're going to replace this H1 tag with a bookmarks component. Now if we hop into the browser we'll see not only categories, but we can see bookmarks on the right-hand side.

[04:13] The next step is when we click a category we want to show only the bookmarks for that category. How we're going to do that is we're going to first jump into the categories model, and we're going to create a mechanism to store the current category.

[04:32] So this.currentCategory = null, and then from we're going to add a getter and a setter method so that we can get the current category which will return this.currentCategory, and then we'll create a setter method called setCurrentCategory that will accept a category parameter and then assign that to this.currentCategory.

[04:58] Then from there let's hop into the categories controller, and we're going to update onCategorySelected to when a category item is selected. We're going to capture that category item and pass that into the categories model to store that value.

[05:19] Now we're also going to create another method called isCurrentCategory. We'll pass in a category item, and then we're just going to first check if there is a current category by calling this category's model, getCurrentCategory.

[05:41] If there is then we're going to compare the ID of the item returned by getCurrentCategory to the category item that we passed in.

[05:52] This is the first simple example of binding to a model as we'll see when we hook in ng-class. We're going to toggle on an active property, which we saw in the style sheet that we looked at earlier.

[06:14] From here active is going to be applied when categoriesListController.isCurrentCategory, and the category we pass in evaluates to true. We're also going to update the logo to capture an ng-click, and from there we're going to call categoriesListController.onCategoriesCelected to...then we'll pass in the value of null.

[06:40] In this case when you click to logo we want to just clear that out. We'll hop into the browser. You can see that when we click a category that it is maintaining its state. Now what we want to do is set it up so that when we click on a category we filter the bookmarks.

[07:00] The first thing we need to do is go into the bookmarks controller, and we're going to inject the categories model. From there we'll store a local reference, and then we're going to create a local reference called getCurrentCategory to the reference or to the getCurrentCategory method on the categories model.

[07:31] This is simply a pass through property, but now what we're going to do is then add in a filter, and we're going to filter on the category property. We're going to compare that against the current category name.

[07:54] The idea is that when this filter runs it's going to call bookmarksListController.getCurrentCategory, which is really going to call getCurrentCategory on the model. We're going to click this, and you'll notice that nothing is happening. Let's see what is going on here.

[08:08] We'll hop into the current category, or rather the category model, and let's just trace out what this is within this particular method.

[08:26] Refresh, and you can see here that we have categories model, so we have four of these on the left-hand side, but then we have this = bookmarksController, which is obviously not what we want to happen. The reason why that's happening is because we're overriding the lexical reference to this.

[08:46] What we need to do is bind the getCurrentCategory method back to the categories model. Just by adding .bind this category's model now we're saying call this method but call it within the context of categories model.

[09:02] You can see here when we click this that the filter is now working, and if we look in the console it's categories model all the way down.

[09:13] Let's just review what we've done up to this point. In categories model we've created a mechanism to set the current category and then retrieve the current category.

[09:29] Then from there within the categories controller we are setting the current category, but we are also testing for the current category as well so that we can apply an active filter.

[09:40] Then in the bookmarks controller we're setting this current category to the get current category on the categories model which gets called by the filter.

[09:50] But then we had to add in the .bind to keep the reference to categories model correct. This is how you bind to a model in an Angular 1 application.

Thom
Thom
~ 8 years ago

Great course ! I want to use this approach to re-factor an existing NG1 app. What other references are good to use for making an angular 1 app angular 2 ish ?

Lukas Ruebbelke
Lukas Ruebbelkeinstructor
~ 8 years ago

Hey Thom, You are in luck! I have actually created an Egghead course and companion guide on this very topic. See https://www.angular2patterns.com/ and https://egghead.io/courses/using-angular-2-patterns-in-angular-1-x-apps. Thanks!

Markdown supported.
Become a member to join the discussionEnroll Today