私の問題はより大きなプログラムの一部ですが、より単純なjsfiddleで問題のシミュレーションを抽出しました。
todo アイテムの「詳細ビュー」表示/非表示コントローラーを実装しています。リンクをクリックすると、詳細ビューが表示または非表示になります。詳細なビュー ステートは に保存されtodo.showDetails
ます。これはうまくいきます。
Todo を完了としてマークすると、次を使用してサーバー上で現在の状態を保持します。
// Persist immediately as clicked on
$scope.checkTodo = function (todo) {
todo.$save();
};
これにより、状態が永続化されたアイテムの一部ではないため、状態が失われるため、詳細ビューが非表示になりtodo.showDetails
ます (つまり、UI 状態を含まない todo アイテムのサーバーのビューでオーバーライドされますtodo.showDetails
)。私は驚かない、これは理にかなっている。
私の質問は、todo アイテムに、ローカルの UI 状態とサーバー上に永続化されたデータの両方を含めるにはどうすればよいですか? の場合、クライアント コードでの値を保持しながら、 のデータをサーバーに保存しtodo.$save()
たいと考えています。つまり、 を呼び出すたびに、UI の状態を変更しないでおきたいと思います。todo
todo.showDetails
todo.$save()
AngularJS でこれを行う慣用的な方法はありますか? showDetails
サーバーのように UI 値を保持したくありません。
これを実装するために私が考えていた 1 つの方法は、各 todo アイテムの UI 状態を格納する個別のサービスを用意することです。ローカル状態にアクセスする必要がある場合、 like にアクセスする代わりに、 likeまたは類似todo.showDetails
のことを行うことができます。AppState.lookup(todo.id).showDetails
しかし、おそらくもっと簡単な方法があります..
-- 2013 年 2 月 25 日更新--
以下の回答のように行い、$resource.get/query 呼び出しによって作成された todo アイテムから UI 状態を単純に分離しました。思ったよりずっと簡単でした ( 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 アプリのコンテキストではより理にかなっています。質問がわかりにくかったり、些細すぎる場合は、質問を削除する必要がありますか?