2015-02-11 65 views
1

自從我開始學習AngularJS以來,我已經看到了從視圖調用控制器函數的不同方法。從AngularJS視圖中調用控制器函數

假設我們在AngularJS待辦事項列表應用程序,你可以添加和刪除待辦事項列表項:

function TodoListCtrl() { 
    var vm = this; 
    vm.addItem = addItem; 
    vm.removeItem = removeItem; 

    activate(); 

    function activate() { 
     vm.list = [];  
    } 

    function addItem() { 
     vm.list.push(vm.newItem); 
     // reset the form 
     vm.newItem = null; 
    } 

    function removeItem(item) { 
     vm.list.splice(vm.list.indexOf(item, 1)); 
    } 
    } 

和HTML:

<h3>Todo List</h3> 

<ul> 
    <li ng-repeat="item in vm.list"> 
    {{ item }} <a ng-click="vm.removeItem(item)">Remove</a> 
    </li> 
</ul> 


<h4>Add Item</h4> 

<input type="text" ng-model="vm.newItem" /> <button ng-click="vm.addItem()">Add</button> 

在這個例子中addItem功能取決於vm.newItem被設置爲添加新的列表項目。然而,它也可以重新寫爲:

function addItem(item) { 
    vm.list.push(item); 
    // reset the form 
    vm.newItem = null; 
} 

隨着我們的HTML更新,所以:

<button ng-click="vm.addItem(vm.newItem)">Add</button> 

我可以看到,這使得功能更易於測試,因爲我們不依賴於控制器的狀態,但我們不完全避免,因爲我們在添加項目後重置vm.newItem

當我們應該從我們的視圖傳遞參數,並且我們只能依賴控制器的內部狀態時,是否有最佳實踐?

+0

我認爲這是一個每個案件的情況,在你的情況下應該不重要。在你的情況下,我會在按鈕上做一個'ng-disabled =「!vm.newItem」',也許在控制器函數中包含一個'if(item){}'。 – 2015-02-11 15:13:00

+0

我不認爲這真的很重要......這與問你是否應該在java/c#類中使用字段值或將其他參數添加到方法中一樣。你可以在控制器中使用或不使用vm.newItem - 它仍然存在。 – 2015-02-11 15:18:31

+0

謝謝,我已經更新了示例。 – 2015-02-11 16:10:10

回答

1

在上述兩種情況下,函數addItem都會對控制器的內部狀態(使用vm.newItem = null;)產生副作用,因此無法孤立地進行測試。

然而,在第二種情況下,傳遞不同的變量甚至沒有意義,因爲它會使語句vm.newItem = null;可能有錯誤。

爲了使功能完全無狀態:

vm.addItem(item){ 
    vm.list.push(item); 
} 

你需要重置從形式來看:

<input type="text" ng-model="vm.newItem"> 
<button ng-click="vm.addItem(); vm.newItem = null">Add</button> 

可能是可以接受的,如果重置形式一個僅查看的問題。如果不是,那麼這種方法將不會完全工作,因爲它可能會使控制器處於錯誤狀態(其中vm.newItem仍然指向列表中新增的項目)

在一天結束時,它取決於您的特別的用例。如果你總是隻有一個你可以「添加」的項目,那麼傳遞一個顯式參數就是多餘的。

但是,如果可以在視圖中調用任何新創建的項目,然而addItem,則明確傳遞參考可能是唯一的方法。

在測試方面,您應該始終測試控制器在操作後處於一致狀態。

2

通過vm.newItem意味着您在視圖中有2個位置。雖然可能很清楚,但它也在重複着你自己,讓你打開可能會失去同步。而在什麼額外的價值?我認爲很明顯,沒有像這樣。

<input type="text" ng-model="vm.newItem" /> 
<button ng-click="vm.addItem()">Add</button> 

否則你有這種重複。

<input type="text" ng-model="vm.newItem" /> 
<button ng-click="vm.addItem(vm.newItem)">Add</button> 

你說測試比較容易,但是爲什麼?您正在測試控制器上的一個功能,所以期望該功能在同一個控制器上使用屬性是完全正確的。你可以依賴於控制器,但不是它的成員。

相關問題