有两个部分这个答案,第一部分回答哪一个是更好的选择,另一部分是事实,他们既不是一个不错的选择!
哪一个是正确的?
这一个是:
$scope.addToDo = function(params1, ...) {
alert(params1);
}
为什么?因为A-它是可测试的。即使不编写测试,这一点也很重要,因为可测试的代码从长远来看总是更具可读性和可维护性。
由于B--它对呼叫者来说是不可知的。这个函数可以被任意数量的不同控制器/服务/等重用,因为它不依赖于范围的存在或者范围的结构。
当你不是这样做:
$scope.addToDo = function() {
alert($scope.params1);
}
A和B失败。它本身不容易测试,并且不容易被重用,因为您使用它的范围可能会有不同的格式。
编辑:如果你正在做的事情非常紧密地联系在一起的具体范围和运行从模板的功能,那么你可能会在试图使其可重复使用的只是没有意义的运行情况。该功能根本不是通用的。在那种情况下,不要为此烦恼,某些功能不能被重用。查看我写作的默认模式,但请记住,在某些情况下,它不适合。
为什么都错了?
因为作为一般规则,你不应该在你的控制器中做逻辑,那就是服务的工作。控制器可以使用服务并调用该函数或将其暴露在模型中,但不应该对其进行定义。
为什么这很重要?因为它再次使得重用该功能变得容易。在控制器中定义的函数不能在其他控制器中重用,也不会限制在HTML中调用控制器的方式。在服务中定义的函数可以注入并在任何你喜欢的地方重用。
但我不需要重用该功能! - 是的,你做!也许不是现在,也许从来没有这个特定的功能,但迟早你会最终想重用一个你相信你永远不需要重用的函数。然后,你将不得不重写你已经忘记了的代码,这总是需要额外的时间。
最好从一开始就正确地做,并将所有可以运用的逻辑转移到服务中。这样,如果你曾经需要它们(甚至在另一个项目中),你可以抓住它并使用它,而不必重写它以适应当前的作用域结构。
当然,服务不知道你的范围,所以你不得不使用的第一个版本。奖金!而且不属于整个范围传递到服务的诱惑,永远不会有好下场的:-)
所以这是IMO是最好的选择:
app.service('ToDoService', [function(){
this.addToDo = function(params1, ...){
alert(params1);
}
}]);
,并在控制器内部:
$scope.addToDo = ToDoService.addToDo;
请注意,我写了 “一般规则”。在某些情况下,在控制器本身而不是服务中定义功能是合理的。例如,函数只涉及范围特定的事情,比如以某种方式切换控制器中的状态。在服务中没有真正的方法可以做到这一点,而不会让事情变得陌生。
但这听起来似乎并非如此。
这通常是一个范围问题。如果使用为每次迭代创建子作用域的ng-repeat,则需要将实例变量作为参数传递。否则,你不知道它是什么。除此之外,我会说这只是一个偏好和易于写作的问题。 –
我做了一些关于[这篇文章]范围继承的研究(http://stackoverflow.com/questions/14049480/what-are-the-nuances-of-scope-prototypal-prototypical-inheritance-in-angularjs/14049482 #140494820)。为了澄清我的具体问题,我正在寻找一些关于何时使用这种或那种方法的最佳实践。如果它们相同,假设范围相同,那么我会接受该答案。 –