Common functionality among Multiple Controllers

02 / May / 2014 by Amit Kumar 0 comments

Many a times, we see a requirement, where we have to write same functions in multiple controllers just to share a common functionality among them, which is a bad approach, because in future, if any changes are required to that function, we’ll have to make the changes manually in all the copies of that function where it is defined or if we want to add that particular functionality in another controller, again we’ll have to copy-paste the whole function scope in that controller too. And doing so is completely against the DRY (Don’t Repeat Yourself) principle.

So to solve this problem, we write directives. Let’s play more with the directives ;-)

NOTE: If you are not aware with the basics of directives, then I will advice you to please read the links below to get to know an idea of Directives:
1. Directive Introduction
2. Components in AngularJS

In my AngularJS Routes blog, we made a single page application (With user CRUD functionality) demo. We were having remove user functionality only in LIST page, but now we want to add remove functionality to SHOW and EDIT Page. So instead of doing copy-paste in SHOW and EDIT page, we are going to write directive for that as below:

/*
 * Defining RemoveUserFunctionality Directive, to share it among
 * multiple controllers. This directive injects remove function to scope where it is marked.
 * */
routeTestModule.directive('removeUserFunctionality', ['$location', function ($location) {
    return {
        scope: true,
        link: function ($scope) {
            /*
             * We remove function from ListUserController and place it here (in directive),
             * And inject remove function everywhere with the help of this directive.
             * */
            $scope.remove = function (id) {
                $scope.users = _.filter(users, function (user) {
                    return user.id != id;
                });
                users = $scope.users;
                $location.path("/user/list");
            };
        }
    }
}]);

Let’s use removeUserFunctionality directive and add Remove function to EDIT and SHOW Pages as below:

partials/edit.html:

<!-- We are using remove-user-functionality directive to inject Remove function into scope -->
<table remove-user-functionality>
    <tr>
        <td>Name</td>
        <td>{{user.name}}</td>
    </tr>
    <tr>
        <td>Age</td>
        <td>{{user.age}}</td>
    </tr>
    <tr>
        <td><a ng-href="#/user/edit/{{user.id}}">Edit</a></td>
        <td><input type="button" value="Remove" ng-click="remove(user.id)" /></td>
        <!--
        Here Remove function is not defined into EditUserController, its injected by
        remove-user-functionality directive.
        -->
    </tr>
</table>

partials/show.html:

<!-- We are using remove-user-functionality directive to inject Remove function into scope -->
<table remove-user-functionality>
    <tr>
        <td>Name</td>
        <td><input type="text" ng-model="user.name" /></td>
    </tr>
    <tr>
        <td>Age</td>
        <td><input type="text" ng-model="user.age" /></td>
    </tr>
    <tr>
        <td><input type="button" value="Cancel" ng-click="cancel()"/></td>
        <td><input type="button" value="Update" ng-click="update()"/></td>
        <td><input type="button" value="Remove" ng-click="remove(user.id)" /></td>
        <!--
        Here also Remove function is not defined in ShowUserController, rather injected by
        remove-user-functionality directive.
        -->
    </tr>
</table>

partials/list.html:

<!-- We are using remove-user-functionality directive to inject remove function into scope -->
<table remove-user-functionality>
    <tr>
        <td>Id</td>
        <td>Name</td>
        <td>Age</td>
        <td></td>
        <td></td>
    </tr>
    <tr ng-repeat="user in users">
        <td><a ng-href="#/user/show/{{user.id}}">{{user.id}}</a></td>
        <td>{{user.name}}</td>
        <td>{{user.age}}</td>
        <td><a ng-href="#/user/edit/{{user.id}}">Edit</a></td>
        <td><input type="button" value="Remove" ng-click="remove(user.id)" /></td>
        <!--
        Again Remove function is not defined in UserListController, it is injected by
        remove-user-functionality directive.
        -->
    </tr>
</table>

After this, if any change is required, we have to make it only in removeUserFunctionality Directive, and we can use it everywhere. :-)

NOTE: You can checkout full working source code from this link.

Amit Kumar
amit.kumar@intelligrape.com
in.linkedin.com/in/amitkumar0110
twitter.com/amit_kumar0110
More Blogs by Me

FOUND THIS USEFUL? SHARE IT

Leave a comment -