我的问题是更大程序的一部分,但我在更简单的jsfiddle中提取了问题的模拟。
我正在为待办事项实现“详细视图”显示/隐藏控制器。当我单击链接时,会显示或隐藏详细视图。详细视图状态存储在todo.showDetails
. 这工作正常。
当我将待办事项标记为已完成时,我使用以下方法将其当前状态保留在服务器上:
// Persist immediately as clicked on
$scope.checkTodo = function (todo) {
todo.$save();
};
这会导致我的详细视图在todo.showDetails
状态丢失时隐藏,因为它不是持久化项目的一部分(即,它被服务器的待办事项项目视图覆盖,其中不包含 UI 状态todo.showDetails
)。我并不惊讶,这是有道理的。
我的问题是:我的待办事项如何同时包含本地 UI 状态和保存在服务器上的数据?当 I 时todo.$save()
,我希望将todo
的数据保存在服务器上,同时保留todo.showDetails
客户端代码中的值。即,每当我打电话时todo.$save()
,我都希望我的 UI 状态保持不变。
在 AngularJS 中有没有一种惯用的方法来做到这一点?我不想像showDetails
在服务器上那样保留 UI 值。
我一直在考虑实现这一点的一种方法是拥有一个单独的服务来存储每个待办事项的 UI 状态。当我需要访问本地状态时,而不是访问 like todo.showDetails
,我可以做类似AppState.lookup(todo.id).showDetails
或类似的事情。但也许有一个更简单的方法..
--更新 2013-02-25 --
我按照下面的答案做了,只是将 UI 状态与 $resource.get/query 调用创建的待办事项分开。它比我想象的要简单得多(参见commit):
我的控制器更改:
$scope.todos = Todo.query();
+ $scope.todoShowDetails = [];
+ $scope.toggleShowDetails = function (todo) {
+ $scope.todoShowDetails[todo.id] = !$scope.todoShowDetails[todo.id];
+ }
+
+ $scope.showDetails = function (todo) {
+ return $scope.todoShowDetails[todo.id];
+ }
模板更改:
- <label class="btn btn-link done-{{todo.done}}" ng-click="todo.showDetails = !todo.showDetails">
+ <label class="btn btn-link done-{{todo.done}}" ng-click="toggleShowDetails(todo)">
..
- <div ng-show="todo.showDetails" ng-controller="TodoItemCtrl">
+ <div ng-show="showDetails(todo)" ng-controller="TodoItemCtrl">
当我把它放在代码中时,这很简单。我的 jsfiddle 示例有点做作,在我的 todo 应用程序的上下文中更有意义。如果问题难以理解或太琐碎,也许我应该删除这个问题?