1

angular newbie here.

Let's say I have an application that needs to monitor different things like "news submitted" "login attemps" and so on. My mainController which responsibility is to get information about those operations, fetch those data from a service and display these information in a simple dashboard.

<div ng-controller='mainController'>
      + ---------------------+
      | NEWS Submitted: 1233 |
      | Login attempts: 233  |
      + ---------------------+
</div>

<div ng-controller='newsController'></div>
<div ng-controller='loginAttemptsController'></div>

I would like to make the data numbers clickable and by clicking on them I'd like the app (without changing route) to display in the relative div the details of the data being clicked. So for example news submitted list or login attemps details. I'd like to have the handling of the details of news submitted and login attemps in their own controller.

The problem is: how can I make a ng-click event that tells angular to invoke a specific function of another controller?

S.Magnaschi
  • 787
  • 5
  • 12

2 Answers2

4

This is how it would work -

  1. from your mainController, emit an event upwards (through $emit). Call to $emit dispatches an event name upwards through the scope hierarchy notifying the registered $rootScope.Scope listeners.

  2. Inside newsController and loginAttemptsController add an event listener (using $rootScope.$on) to listen to the event emitted from mainController, get data from the target scope (in your case its mainController's scope) and set it to newsController and loginAttemptsController's scope model.

for details go through angular documentation - https://docs.angularjs.org/api/ng/type/$rootScope.Scope

I have set up a plunk here - http://plnkr.co/edit/1dhdPfmB1WwAkYhsz4Hv

Example code (html template) :

<div ng-controller="mainController">
    <button data-ng-click="OnNewButtonClick()">Show News</button>
    <button data-ng-click="OnLoginAttemptButtonClick()">Show Login Attempts</button>

</div>
<div ng-controller="newsController">
    {{newsControllerData.News}}
</div>
<div ng-controller="loginAttemptsController">
    {{loginAttemptsControllerData.loginAttempts}}
</div>

Example code (main controller) :

app.controller("mainController", ["$rootScope", "$scope", function ($rootScope, $scope) {

    $scope.newsControllerData = {};
    $scope.loginAttemptsControllerData = {};

    // from mainController emit HandleNews upwards on the scope
    $scope.OnNewButtonClick = function () {
        $scope.newsControllerData.info = "Hello World";
        $scope.$emit("HandleNews");
    }

    // from mainController emit HandleLoginAttempts upwards on the scope
    $scope.OnLoginAttemptButtonClick = function () {
        $scope.loginAttemptsControllerData.info = "login count = 4";
        $scope.$emit("HandleLoginAttempts");
    }

}]);

Example code (news Controller) :

app.controller("newsController", ["$rootScope", "$scope", function ($rootScope, $scope) {

    $scope.newsControllerData = {};

    // when any controller calls HandleNews, i would listen
    $rootScope.$on("HandleNews", function (evt, next, current) {
        $scope.newsControllerData.News = evt.targetScope.newsControllerData.info;
    });

}]);

Example code (loginAttempts Controller) :

app.controller("loginAttemptsController", ["$rootScope", "$scope", function ($rootScope, $scope) {

    $scope.loginAttemptsControllerData = {};

    // when any controller calls HandleLoginAttempts, i would listen
    $rootScope.$on("HandleLoginAttempts", function (evt, next, current) {
        $scope.loginAttemptsControllerData.loginAttempts = evt.targetScope.loginAttemptsControllerData.info;

    });


}]);
Rabi
  • 2,210
  • 17
  • 18
0

You can create a service, that will be storing the data between the controllers. Then you can use / change that piece of data in both of your controllers and associated views.

app.service('newsDataService', function() {

        this.newsData = [];

});

then in your controller,

app.controller('newsController', function($scope, 'newsDataService') {

    // access the data using newsDataService.newsData.

});


app.controller('loginAttemptsController', function($scope, 'newsDataService') {

    // access the data using newsDataService.newsData.

});

More information on AngularJs Services : https://docs.angularjs.org/guide/services

Manish Kr. Shukla
  • 4,447
  • 1
  • 20
  • 35
  • Thanks for the reply. If I understand correctly you say that I can use services to encapsulate a specific state and share it among my controllers as long as they have injected the service. I get it. – S.Magnaschi Aug 14 '14 at 10:25
  • But what if I just simply want to execute a controller function with a simple ng-click propery? So that if I click the news count, angular will activate a method say fetchNews from my newsController. I'm asking this because maybe my newsController needs to talk to a database service while my loginAttempts need to talk to a completely different service. From what you suggest I understand that newsDataService would be responsible for fetching the news and the loginAttempts? What am I missing? – S.Magnaschi Aug 14 '14 at 10:29