1. ホーム
  2. javascript

[解決済み] モデルデータや振る舞いをどこに置くか?[tl; dr; サービスを利用する]

2022-03-16 23:07:08

質問

私は最新のプロジェクトでAngularJSを使用しています。ドキュメントやチュートリアルでは、すべてのモデルデータはコントローラスコープに置かれます。私は、コントローラで利用できるようにするために、そして対応するビューで利用できるようにするために、そこになければならないことを理解しています。

しかし、私はモデルを実際にそこに実装する必要はないと思っています。例えば、モデルは複雑で、プライベートな属性を持っているかもしれません。さらに、別のコンテキストやアプリでそれを再利用したいと思うかもしれません。すべてをコントローラに入れるのは、MVCパターンを完全に壊してしまいます。

どのようなモデルでも、その動作は同じです。もし、私が DCIアーキテクチャ で、データモデルから振る舞いを分離する場合、振る舞いを保持するために追加のオブジェクトを導入しなければならないだろう。これは、ロールとコンテクストを導入することで実現できるだろう。

DCI == (英語) D アト C コラボレーション I 相互作用

もちろん、モデルのデータと動作は、プレーンなjavascriptオブジェクトや任意の"class"パターンで実装することができます。しかし、それを行うためのAngularJSの方法は何でしょうか?サービスを使うのでしょうか?

つまり、この質問に行き着くわけです。

AngularJSのベストプラクティスに従って、コントローラから切り離されたモデルをどのように実装するのでしょうか?

どのように解決するのですか?

複数のコントローラで利用可能なものが欲しい場合は、サービスを利用する必要があります。ここでは、簡単な工夫をした例を紹介します。

myApp.factory('ListService', function() {
  var ListService = {};
  var list = [];
  ListService.getItem = function(index) { return list[index]; }
  ListService.addItem = function(item) { list.push(item); }
  ListService.removeItem = function(item) { list.splice(list.indexOf(item), 1) }
  ListService.size = function() { return list.length; }

  return ListService;
});

function Ctrl1($scope, ListService) {
  //Can add/remove/get items from shared list
}

function Ctrl2($scope, ListService) {
  //Can add/remove/get items from shared list
}