有兩個部分這個答案,第一部分回答哪一個是更好的選擇,另一部分是事實,他們既不是一個不錯的選擇!
哪一個是正確的?
這一個是:
$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)。爲了澄清我的具體問題,我正在尋找一些關於何時使用這種或那種方法的最佳實踐。如果它們相同,假設範圍相同,那麼我會接受該答案。 –