Reputation: 1790
I've written a pretty simple test app as follows:
angular.module('tddApp', [])
.controller('MainCtrl', function ($scope, $rootScope, BetslipService) {
$scope.displayEvents = [
{
id: 1,
name: 'Belarus v Ukraine',
homeTeam: 'Belarus',
awayTeam: 'Ukraine',
markets: {home: '2/1', draw: '3/2', away: '5/3'},
display: true
}
];
$scope.betslipArray = BetslipService.betslipArray;
$scope.oddsBtnCallback = BetslipService.addToBetslip;
$scope.clearBetslip = BetslipService.clearBetslip;
})
.directive('oddsButton', function () {
return {
template: '<div class="odds-btn">{{market}}</div>',
replace: true,
scope: {
market: '@',
marketName: '@',
eventName: '@',
callback: '&'
},
link: function (scope, element) {
element.on('click', function() {
scope.callback({
name: scope.eventName,
marketName: scope.marketName,
odds:scope.market
});
});
}
};
})
.factory ('BetslipService', function ($rootScope) {
var rtnObject = {};
rtnObject.betslipArray = [];
rtnObject.addToBetslip = function (name, marketName, odds) {
rtnObject.betslipArray.push({
eventName: name,
marketName: marketName,
odds: odds
});
};
rtnObject.clearBetslip = function () {
rtnObject.betslipArray = [];
};
return rtnObject;
});
I've assigned an array to a controller variable. I've also assigned functions to modify the array. To add an object to the array the callback is called by a directive with isolate scope. There's some strange behaviour happening that I don't quite understand:
=> clicking the directive runs the callback in the service. I've done some debugging and it seems that the controller variable is updated but it doesn't show in the html. => clicking the button to clear the array isn't working as expected. The first time it's causing an element to display, after which it has no effect.
I think that this may have to do with the nested ng-repeats creating their own scopes
NB
I fixed the array not clearing by changing the function in the service to:
while (rtnObject.betslipArray.length > 0) {
rtnObject.betslipArray.pop();
}
// instead of
rtnObject.betslipArray = [];
This makes sense as the service variable was being pointed at a new object while the old reference would persist in the controller.
I got the html to update by wrapping the callback call in the directive in a scope.$apply(). This part I dont really understand. How can scope.$apply() called in the directive have an effect on the controller scope when the directive has an isolate scope? updated fiddle: http://jsfiddle.net/b6ww0rx8/7/
Any thought's greatly appreciated
jsfiddle: http://jsfiddle.net/b6ww0rx8/5/
C
Upvotes: 0
Views: 288
Reputation: 3538
I got it working here: http://jsfiddle.net/b6ww0rx8/8/
Added $q
, $scope.$emit
and $timeout
clauses to help with communications between your directive / service and controller.
I would like to also say that I wouldn't assign service functions to a controller $scope,
You should define functions in the controller that call service functions.
Instead of this:
$scope.clearBetslip = BetslipService.clearBetslip;
Do this:
$scope.clearBetslip = function(){
BetslipService.clearBetslip().then(function(){
$scope.betslipArray = BetslipService.getBetslipArray();
});
};
Upvotes: 1