从AngularJS视图中调用控制器函数
自从我开始学习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
。
当我们应该从我们的视图传递参数,并且我们只能依赖控制器的内部状态时,是否有最佳实践?
在上述两种情况下,函数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
,则明确传递参考可能是唯一的方法。
在测试方面,您应该始终测试控制器在操作后处于一致状态。
通过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>
你说测试比较容易,但是为什么?您正在测试控制器上的一个功能,所以期望该功能在同一个控制器上使用属性是完全正确的。你可以依赖于控制器,但不是它的成员。
我认为这是一个每个案件的情况,在你的情况下应该不重要。在你的情况下,我会在按钮上做一个'ng-disabled =“!vm.newItem”',也许在控制器函数中包含一个'if(item){}'。 – 2015-02-11 15:13:00
我不认为这真的很重要......这与问你是否应该在java/c#类中使用字段值或将其他参数添加到方法中一样。你可以在控制器中使用或不使用vm.newItem - 它仍然存在。 – 2015-02-11 15:18:31
谢谢,我已经更新了示例。 – 2015-02-11 16:10:10