0

I know similar questions has been asked in the past, but I hope to get a better understanding to my specific issue.

I have multiple controllers managing the view of a single page. The main reason for this is that the functionality of each controller is vastly different, and I also combined some functionality that used to be on separate views. This is also not an issue that will be resolved by creating a service. I only need to "kick-start" both controllers.

This is my question: I want to implement a single date filter/method on the view, that will call the same method in both controllers to do its functionality, and update the view accordingly.

EDIT: How can I use $scope.on and $scope.emit, or $rootScope to call the function in both controllers?

As per these previously posted questions:

Question 1

Question 2

Here are the two controllers:

angular.module('portalDashboardApp')
 .controller('SocialMentionsAnalysisController', SocialMentionsAnalysisController);
angular.module('portalDashboardApp')
 .controller('SocialMentionsListController', SocialMentionsListController);

This is the method call in my single view:

ng-change="checkDate()

This is the filter method that gets called:

NOTE: Each of the controllers has this method, and I would like to call both these methods via my single method call.

$scope.checkDate = function () {
 var dateValues = DatePickerService.checkDate($scope.dateFrom, $scope.dateTo);
 $scope.dateFrom = dateValues[0];
 $scope.dateTo = dateValues[1];
 $sessionStorage.dateFrom = dateValues[0];
 $sessionStorage.dateTo = dateValues[1];
 pullSocialData();
}; 

I have done research, and this question is perhaps what I need, but I don't know how to implement it.

asked Nov 17, 2016 at 10:45

2 Answers 2

1

The the $on functions with same name will get called with its corresponding single $emit call. I mean, you have multiple $on functions in multiple controllers,

$scope.$on('funtionToTrigger', function(event, args) {
//in first controller
});
$scope.$on('funtionToTrigger', function(event, args) {
//in second controller
});
$scope.$on('funtionToTrigger', function(event, args) {
//in third controller
});

Note: all $on functions' name are same 'funtionToTrigger'. Once you call $scope.$emit('funtionToTrigger', args); then all three $on functions will run in all three controllers.

So here, you have write a $on function in each controller.

function SocialMentionsAnalysisController () {
 $scope.$on('funtionToTrigger', function(event, dateFrom, dateTo) {
 //your code for this controller.
 });
}
function SocialMentionsListController() {
 $scope.$on('funtionToTrigger', function(event, dateFrom, dateTo) {
 //your code for this controller.
 });
}

Then call $emit on onChange.

ng-change="$emit('funtionToTrigger', dateFrom, dateTo)"
Michael Laffargue
10.3k6 gold badges46 silver badges76 bronze badges
answered Nov 17, 2016 at 13:33
Sign up to request clarification or add additional context in comments.

5 Comments

Hi Amir, thank you fior the great answer. I have a question; can I add the $emit to the function like this: ng-change="checkDate(); $emit("activate")" to call this: $scope.$on("activate", function (event, args) {pullSocialData();});?
I have set it up as follow: in my date directive:ng-model="dateFrom" ng-change="$emit('dateChanged', dateFrom, dateTo); checkDate()", and like this in my controller: $scope.$on("dateChanged", function checkdate(event, dateFrom, dateTo) {var dateValues = DatePickerService.checkDate(dateFrom, dateTo); pullSocialData(); }) This almost works. My $scope.$on method gets called in the 1st controller, but not in my second controller. Any thoughts?
There is no parent relation between scope's controllers. You need to emit event from $rootScope
Would I simply inject $rootScope, and change the $scope.on to $rootScope.on?
I changed it to $rootScope, and it works! Thank you :)
1

I hope i understand correctly the question but you can use directive for this. Instead of use ng-change, you can create your own directive that bin on change of input and check the date here.

For example, your javascript :

app.controller('Ctrl1', function($scope) { })
 .controller('Ctrl2', function($scope) { })
 .directive('checkDate', function(checkDateService) {
 return {
 restrict: 'A',
 scope: true,
 link: function(scope, element, attrs ){
 element.on('change', function() {
 scope.$apply(function() {
 checkDateService.checkDate(scope.from, scope.to);
 })
 });
 }
 }
 }).service('checkDateService', function() {
 return {
 checkDate: function(from, to) {
 console.log(from, to);
 }
 }

});

And the HTML :

<body>
 <div ng-controller="Ctrl1">
 <input type="date" ng-model="from" check-date />
 <input type="date" ng-model="to" check-date />
 </div>
 <div ng-controller="Ctrl2">
 <input type="date" ng-model="from" check-date />
 <input type="date" ng-model="to" check-date />
 </div>
</body>

Here the same sample as plunker :https://plnkr.co/edit/Jqz7Zd4HF0WVBvkJHBbZ?p=preview

To use event in inline js on HTML, I think you can define a methode on $rootScope (at run configuration) that broadcast your event. This event will be triggered by all controller depends on $rootScope.

In Javascript :

app.run(function($rootScope) {
 $rootScope.brodcastDateChanged = function(dateFrom, dateTo) {
 $rootScope.$broadcast('dateChanged', {
 from: dateFrom,
 to: dateTo
 });
 };
})
.controller('Ctrl1', function($scope) { 
 $scope.$on('dateChanged', function(event, args) {
 console.log('event triggered from Ctrl1', args)
 });
 })
 .controller('Ctrl2', function($scope) { 
 $scope.$on('dateChanged', function(event, args) {
 console.log('event triggered from Ctrl2', args)
 });
 })
 .controller('Ctrl3', function($scope) { 
 $scope.$on('dateChanged', function(event, args) {
 console.log('event triggered from Ctrl3', args)
 });
 })

In HTML

<div ng-controller="Ctrl1">
 <input type="date" ng-model="from" ng-change="brodcastDateChanged(from, to)" />
 <input type="date" ng-model="to" ng-change="brodcastDateChanged(from, to)" />
</div>
<div ng-controller="Ctrl2">
 <input type="date" ng-model="from" ng-change="brodcastDateChanged(from, to)" />
 <input type="date" ng-model="to" ng-change="brodcastDateChanged(from, to)" />
</div>
<div ng-controller="Ctrl3">
 <input type="date" ng-model="from" ng-change="brodcastDateChanged(from, to)" />
 <input type="date" ng-model="to" ng-change="brodcastDateChanged(from, to)" />
</div>
answered Nov 17, 2016 at 13:27

3 Comments

Hi Silvinus. Thank you for the response and great input. I am in fact already making use of a directive for the dates. The issue with this is that both the dates (one in each controller HTML) doesn't get changed automatically or at the same time. One will still have to change each date for each part of the view controlled by each controller. Any thoughts?
If I transpose your comment in my sample, You want change the date from of Ctrl2 when date from of Ctrl1 change and vice versa?
I am actually trying to call a function in each controller when the data in ctrl 1 changes. I am trying $emit and $scope.$on, but only 2 of the 3 controllers are effected. I think the $emit gets destroyed or something.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.