我写了一个非常简单的测试应用程序如下:
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;
});
我已经为控制器变量分配了一个数组。我还分配了修改数组的函数。要将对象添加到数组,回调将由具有隔离范围的指令调用。发生了一些奇怪的行为,我不太明白:
=&GT;单击该指令将运行服务中的回调。我已完成一些调试,似乎控制器变量已更新,但它没有在html中显示。 =&GT;单击按钮清除阵列不能按预期工作。它第一次导致元素显示,之后它没有效果。
我认为这可能与嵌套的ng-repeats创建自己的范围有关
NB
我通过将服务中的功能更改为:
来修复未清除的数组while (rtnObject.betslipArray.length > 0) {
rtnObject.betslipArray.pop();
}
// instead of
rtnObject.betslipArray = [];
这是有道理的,因为服务变量指向一个新对象,而旧引用将保留在控制器中。
我通过在范围内的指令中包装回调调用来更新html。$ apply()。 这部分我真的不明白。范围如何。当指令具有隔离范围时,指令中调用的$ apply()会对控制器范围产生影响吗?更新小提琴:http://jsfiddle.net/b6ww0rx8/7/
任何想法都非常感激
jsfiddle:http://jsfiddle.net/b6ww0rx8/5/
C
答案 0 :(得分:1)
我在这里工作:http://jsfiddle.net/b6ww0rx8/8/
添加了$q
,$scope.$emit
和$timeout
条款,以帮助您的指令/服务与控制器之间的通信。
我还想说我不会将服务功能分配给控制器$scope,
您应该在控制器中定义调用服务功能的功能。
而不是:
$scope.clearBetslip = BetslipService.clearBetslip;
这样做:
$scope.clearBetslip = function(){
BetslipService.clearBetslip().then(function(){
$scope.betslipArray = BetslipService.getBetslipArray();
});
};