Reputation:
I understand that using $rootScope to share values between controllers is a bad idea and everybody recommends using Services and as an answer links to the the angular docs. However I am at loss there, because the official documentation does not show any simple example, and when I tried to implement some examples from here, StackOverflow – they did not work for me (maybe because I am using ng-repeat?). I have been trying to solve it for several days, as to not to bother you here, but now I am at totally at loss.
Could you please show me how to solve the example below, and I will then use it in my application (where I have about 50 different scopes used in 5 different controllers). The example below is the simple outline of my problem. I have also created a plunker for it http://plnkr.co/edit/J4fZ51koueyUX9mXqzDk?p=preview
I have three controllers in my JS:
app.controller('TotalCalc', function($scope) {
});
app.controller('color', function($scope) {
$scope.colors = [
{name1: "Red",price1: 300},
{name1: "Green",price1: 660},
{name1: "Black",price1: 920}
];});
app.controller('coating', function($scope) {
$scope.coatings = [
{name2: "Single coating",price2: 2},
{name2: "Double coatings",price2: 4},
{name2: "Triple coating",price2: 7}
];});
And in my HTML I have:
<div class="container" ng-controller="TotalCalc">
Here I want to calculate a value: (color selected price) * (coating multiplier)<br>
Using the "selected.price1" * "selected.price2", from the "color" and "coating" controllers below.
<div class="col-xs-6" ng-controller="color">
<strong>Color selected price: {{selected.price1 ||0}}</strong>
<div class="list-group small">
<a ng-repeat="color in colors" ng-click="$parent.selected = color" class="list-group-item" ng-class="{active:selected==color}"><span class="badge pull-right">$ {{color.price1}}</span>{{color.name1}}</a>
</div>
</div>
<div class="col-xs-6" ng-controller="coating">
<strong>Coating multiplier: {{selected.price2 ||0}}</strong>
<div class="list-group small">
<a ng-repeat="coating in coatings" ng-click="$parent.selected = coating" class="list-group-item" ng-class="{active:selected==coating}"><span class="badge pull-right">{{coating.price2}}</span>{{coating.name2}}</a>
</div>
</div>
</div>
See, that whole place (single-page-application) is under the "TotalCalc" controller and from there I cannot access the values from the other two controllers inside it.
I understand that I should use the Service(?) somehow, if I want to access any values/scopes from the different controllers throughout the whole application. But after several days reading up and trying, I cannnot find a way for it to work. :( Can you please use my simplified example above, and to show me how it is done? Thank you in advance.
Upvotes: 0
Views: 210
Reputation: 171669
As @Nikos pointed out, you really don't need multiple nested controllers here. That being said, here is an example of using a service as well as some custom events for communicating. The events aren't needed as you can bind all the data together through the service , but I put them in for inspiration
app.factory('CoatingService', function() {
var thisService = {
colors: [
{name1: "Red",price1: 300},
{name1: "Green",price1: 660},
{name1: "Black",price1: 920}
],
coatings: [
{name2: "Single coating",price2: 2},
{name2: "Double coatings",price2: 4},
{name2: "Triple coating",price2: 7}
],
selected:{
color:{},
coating:{}
}
}
return thisService
})
app.controller('TotalCalc', function($scope, CoatingService) {
$scope.selected=CoatingService.selected;
function updateTotal(){
$scope.totalprice= ($scope.selected.color.price1 ||0) + ($scope.selected.coating.price2||0)
}
updateTotal();
$scope.$on('doPriceUpdate',function(){
updateTotal();
})
});
app.controller('color', function($scope, CoatingService) {
$scope.colors = CoatingService.colors;
$scope.selected = CoatingService.selected;
$scope.updateColor=function(color){
$scope.selected.color=color;
$scope.$emit('doPriceUpdate')
}
});
/* similar pattern for coating controller*/
You could do this all within one controller though quite easily with less code but still keep the service to store data
Upvotes: 1