Here's a breakdown of the answer: one part focuses on determining the better choice between two options, while the other part emphasizes that neither option is ideal!
So, which option is correct?
It looks like this one:
$scope.addToDo = function(params1, ...) {
alert(params1);
}
Why? First off, A - it's testable. Even if you're not specifically writing tests, having code that can be tested makes it more readable and maintainable in the long term.
Additionally, B - it's agnostic to the caller. This means it can easily be reused by various controllers or services without being tied to a specific scope structure.
If you go with this approach instead:
$scope.addToDo = function() {
alert($scope.params1);
}
Both A and B fall short. It lacks ease of testability and reusability due to its dependence on the structure of the scope.
Edit: If your scenario involves closely tied logic to a specific scope and calling the function from the template, making it reusable might not be practical. In some cases, functions are just not generic enough for reuse. Keep the default mode but acknowledge when it may not apply.
Why are both approaches flawed?
As a general rule, logic shouldn't reside in controllers; that's where services come into play. Controllers should utilize services to handle logic or expose it in a model rather than defining it themselves.
The reason behind this principle? Once again, it promotes function reusability. Functions defined in controllers limit their use across different controller contexts embedded in HTML, whereas service-defined functions can be injected and applied wherever needed.
"But I won't need to reuse the function!" - Think again! While immediate reuse may not seem necessary, future scenarios may call for integrating that function elsewhere. Start off correctly by shifting most logic to services. This way, when the need arises, you can seamlessly transfer the function to new contexts without adapting it to fit existing scope structures.
Remember, services lack knowledge of scope, so opting for the initial version simplifies implementation. And resist the urge to pass an entire scope to a service; that road only leads to trouble :-)
Hence, in my opinion, the preferred setup would be:
app.service('ToDoService', [function(){
this.addToDo = function(params1, ...){
alert(params1);
}
}]);
And within the controller:
$scope.addToDo = ToDoService.addToDo;
Note the mention of a "general rule." Some situations may warrant defining functions within the controller itself rather than resorting to a service. For instance, when a function pertains solely to scope-specific tasks, such as toggling controller states. However, based on the context presented here, that doesn't seem to be the case.