Anup
Anup

Reputation: 9738

Call another Controller's Method

I have a NavBarCtrl which is in partial page. In this page i have a Search box with a button Search.

On this btn click, i want to call DashBoardCtrl method listRecords().

I am getting all the searched values by setting them to $rootScope in DashBoardCtrl.

How to call another controller's method?

Here is my relevant code :-

<div class="navbar navbar-fixed-top" ng-controller="NavbarCtrl">
    <ul>
        <li class="dropdown"><a href="javascript:void(0)" class="dropdown-toggle" data-toggle="dropdown" ng-click="isCollapsed = !isCollapsed">
                <img src="/images/menu-search.png" alt="Search" title="Search" ng-click="openSearch()" />
            </a>
                <div class="dropdown-menu">
                    <div ng-form="searchPatient" class="searchPatient" id="searchPatient">                            
                        <table>
                            <tr>
                                <td>Last Name</td>
                                <td><input name="lastname" id="lastname" type="text" ng-model="search.lastname"></td>
                            </tr>
                            <tr>
                                <td>First Name</td>
                                <td><input name="firstname" id="firstname" type="text"></td>
                            </tr>
                            <tr>
                                <td>Date of Birth</td>
                                <td><input name="dateofbirth" id="dateofbirth" type="text"></td>
                            </tr>                              
                        </table>                            
                        <button type="button" class="btn" ng-click="listRecords(1)">Search</button>
                    </div>
                </div>
            </li>   
    </ul>
</div>

Upvotes: 0

Views: 499

Answers (3)

Marc Kline
Marc Kline

Reputation: 9409

By using a service such as a factory, you would ensure both better testability and readability of your code. $rootScope is like the global namespace of Angular - you should use it very sparingly, if ever at all.

I made a Plunker Demo to demonstrate a simplified version of a search service whose query originates from one controller and results appear in another.

This type of code can be both simple and clean:

.controller('NavController', function($scope, Search) {
  $scope.change = function(query){
    Search.query(query);
  }
})
.controller('DashController', function($scope, Search) {
  $scope.search = Search;
})
.factory('Search', function(Data){
  var search = {results: []};

  search.query = function(query){
    search.results = [];
    Data.forEach(function(item){
      if (item.color == query) { search.results.push(item) }
    });
    return search;
  }

  return search;
})

It sounds as if you've decided to go with a solution using $rootScope, but I urge you to reconsider. Investing some time now to establish good practices will pay off later, perhaps many times over.

Upvotes: 2

Nidhish Krishnan
Nidhish Krishnan

Reputation: 20741

You can use Angular JS $watch , factory or you can declare that method as $rootScope.listRecords to achieve this tasks

Using Factory - (Recommended)

Working Demo

var app = angular.module('myApp', []);

app.factory('testFactory', function(){
    return {
        listRecords: function(){
            console.log('listRecords');
        }
    }               
});


app.controller('NavBarCtrl', function ($scope, testFactory) {

    $scope.clickAction = function () {
        console.log('clickAction');
        $scope.fromService = testFactory.listRecords();
    }
});

app.controller('DashBoardCtrl', function ($scope, testFactory) {

    $scope.fromService = testFactory.listRecords();
});

Declaring the method with $rootScope

Working Demo

var app = angular.module('myApp', []);
app.controller('NavBarCtrl', function ($scope, $rootScope) {

   $scope.clickAction = function()
    {
        $scope.listRecords();
        console.log('clickAction');
    }
});

app.controller('DashBoardCtrl', function ($scope, $rootScope) {

    $rootScope.listRecords = function()
    {
        console.log('listRecords');
    }
});

Without declaring the method with $rootScope

The below code shows how you can trigger another controller method without making the method as rootScope

Working Demo

var app = angular.module('myApp', []);
app.controller('NavBarCtrl', function ($scope, $rootScope) {

   $scope.clickAction = function()
    {
        $rootScope.trigger = 1;
        console.log('clickAction');
    }
});

app.controller('DashBoardCtrl', function ($scope) {
    $scope.$watch('trigger', function()
    {
      $scope.listRecords();
    }, true);

    $scope.listRecords = function()
    {
        console.log('listRecords');
    }
});

Upvotes: 2

ivarni
ivarni

Reputation: 17878

A controller that is the child of another can access a function from it's parent via $scope if the parent controller puts it on its own $scope. Alternatively anything that is put on $rootScope is accessible from any controller, but that is a very brittle solution. It sounds like your function really should be in a service.

Upvotes: 2

Related Questions