Anders Lindén
Anders Lindén

Reputation: 7303

How do I call method in child controller?

I am using angular pager by using

<script type="text/javascript" src="Scripts/angular-pager.js"></script>

In MainController, I have a PagerController like

<body>
    <div ng-app="myapp" ng-controller="mainController">
      <div ng-controller="PagerController as vm" data-entities="Bookings"
        data-pagesize="10">
    </div>
</body>

That pager controller uses http to populate itself using information in data-entities like

var app = angular.module("myapp", ["ng"])
  .controller("mainController", function ($scope, $http, $filter)
{
  /* a lot of code */
})
.factory('PagerService', PagerService)
.controller('PagerController', function (PagerService, $http, $scope, $attrs)
{
    var vm = this;
    var pageSize = $attrs["pagesize"];
    var entities = $attrs["entities"];

    vm.update = function ()
    {
        setPage(vm.pager.currentPage);
    };

    vm.setPage = setPage;

    initController();

    function initController()
    {
        setPage(1);
    }

    function setPage(page)
    {
        $http.get(entities + "/" + page + "/" + pageSize).success(function (result)
        {
            var numPages = Math.ceil(result.totalNumItems / pageSize);

            vm.pager = PagerService.GetPager(result.totalNumItems, numPages, page);
            vm.items = result.items;
        });
    }
});

When I have done actions in the main controller, I need to update the pager, because the data has changed as a result of those actions. How do I have the pagers' update function called from code inside mainController?

Upvotes: 2

Views: 106

Answers (2)

Robin-Hoodie
Robin-Hoodie

Reputation: 4974

While @Sravan's answer will work, it's better to $broadcast from the current $scope so only this controllers children will receive the event. With $rootScope you will actually $broadcast the event to ALL scopes/controllers.

Also, don't forget to unregister your listener(s) to prevent possible leaks.

mainController

  $scope.$broadcast('pageChange', $scope.page);

PagerController

var unregisterPageChangeListener = $scope.$on('pageChange', function(event, updatedPage){
   vm.pager.currentPage = updatedPage;
   vm.update();
});

$scope.$on('$destroy', function() { unregisterPageChangeListener(); }

Though it was not your question, even better still is to communicate between controllers through services/factories.

Upvotes: 1

Sravan
Sravan

Reputation: 18647

You can use the rootscope broadcast to achieve your solution.

$rootScope.$broadcast is sending an event through the application scope. Any children scope of that app can catch it using a simple: $scope.$on().

In your mainController, after your changes are done, you can call the $rootScope.$broadcast() method with a parameter.

var app = angular.module("myapp", ["ng"])
  .controller("mainController", function ($scope, $http, $filter,$rootScope)
{
  /* a lot of code */
  $rootScope.$broadcast('page_changed', {page : $scope.page});
})

In your PagerController, you can subscribe to that event using, $rootScope.$on()

$rootScope.$on('page_changed', function(event, obj){
    console.log(obj.page);
    vm.update(obj.page);
})

PagerController:

.controller('PagerController', function (PagerService, $http, $scope, $attrs,$rootScope)
{
    var vm = this;
    var pageSize = $attrs["pagesize"];
    var entities = $attrs["entities"];

    $rootScope.$on('page_changed', function(event, obj){
        console.log(obj.page);
        vm.update(obj.page)
    })

    vm.update = function ()
    {
        setPage(vm.pager.currentPage);
    };

    vm.setPage = setPage;

    initController();

    function initController()
    {
        setPage(1);
    }

    function setPage(page)
    {
        $http.get(entities + "/" + page + "/" + pageSize).success(function (result)
        {
            var numPages = Math.ceil(result.totalNumItems / pageSize);

            vm.pager = PagerService.GetPager(result.totalNumItems, numPages, page);
            vm.items = result.items;
        });
    }
});

So, whenever something is changed in the main controller, just broadcast that change, and it will update the pager controller.

Upvotes: 1

Related Questions