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:
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.
2 Answers 2
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)"
5 Comments
$emit to the function like this: ng-change="checkDate(); $emit("activate")" to call this: $scope.$on("activate", function (event, args) {pullSocialData();});?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?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>
3 Comments
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?