任务: 在 Controller 中,我有一个默认对象,需要根据许多条件进行修改。 修改逻辑是重复的,因此我将其移植到名为 colorService 的服务/实用程序(也可以创建私有(private)方法)。 要求仅将一种颜色设置为 true,将其他颜色设置为 false。
情况1:
//CONTROLLER
$scope.colorObj = {
red:true,
green:true,
blue:true,
white:true,
yellow:true
};
$scope.changeColor = function(){
var color = 'r';
switch(color){
case 'r':colorService.setColor('red',$scope.colorObj);break;
case 'b':colorService.setColor('blue',$scope.colorObj);break;
case 'g':colorService.setColor('green',$scope.colorObj);break;
case 'w':colorService.setColor('white',$scope.colorObj);break;
case 'y':colorService.setColor('yellow',$scope.colorObj);break;
default: colorService.setColor('',$scope.colorObj);break;
}
}
//SERVICE
colorService.setColor = function(type, colorObj){
angular.forEach(colorObj,function(val,color){
if(color === type){
colorObj[color] = true;
}else{
colorObj[color] = false;
}
});
};
如果我遵循这种方法,那么当共享对象引用时,更改会立即反射(reflect)在 $scope.colorObj 上。因此不需要“返回”。
但是这种方法将 $scope 作为参数传递给服务,我知道这不是最佳实践。此外,服务方法没有返回语句,这也违背了服务的原则。
情况2:
//CONTROLLER
$scope.colorObj = {
red:true,
green:true,
blue:true,
white:true,
yellow:true
};
$scope.changeColor = function(){
var color = 'r';
switch(color){
case 'r': $scope.colorObj = colorService.setColor('red');break;
case 'b': $scope.colorObj = colorService.setColor('blue');break;
case 'g': $scope.colorObj = colorService.setColor('green');break;
case 'w': $scope.colorObj = colorService.setColor('white');break;
case 'y': $scope.colorObj = colorService.setColor('yellow');break;
default: $scope.colorObj = colorService.setColor('');break;
}
}
//SERVICE
colorService.setColor = function(type){
var colorObj = {
red:true,
green:true,
blue:true,
white:true,
yellow:true
};
angular.forEach(colorObj,function(val,color){
if(color === type){
colorObj[color] = true;
}else{
colorObj[color] = false;
}
});
return colorObj;
};
在本例中,我隔离了 $scope,但必须在服务方法中添加一个本地对象 colorObj,该方法返回并复制到 $scope.colorObj 上。
我发现这更容易测试,但我再次需要在 Controller 和服务中维护多个 colorObj。
情况3:
//CONTROLLER
$scope.colorObj = {
red:true,
green:true,
blue:true,
white:true,
yellow:true
};
$scope.changeColor = function(){
var color = 'r';
switch(color){
case 'r': setColor('red');break;
case 'b': setColor('blue');break;
case 'g': setColor('green');break;
case 'w': setColor('white');break;
case 'y': setColor('yellow');break;
default: setColor('');break;
}
};
setColor = function(type){
angular.forEach(colorObj,function(val,color){
if(color === type){
$scope.colorObj[color] = true;
}else{
$scope.colorObj[color] = false;
}
});
};
在这里,我可以简单地在 Controller 中创建一个私有(private)方法 setColor 来完成任务。缺点是 setColor 不是唯一可测试的;是的,可以通过父方法changeColor发起测试来测试
哪一个选择会更好?
最佳答案
我会继续案例 2。原因是:服务和 Controller 之间的逻辑是分开的。代码更易于测试。
对于情况 1:传递 $scope 是一种代码味道。
对于情况 3:您正在失去测试能力。
关于javascript - 定义可能需要修改 AngularJS 中 $scope 数据的实用程序/帮助程序方法的理想方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26561866/