30

私は次の 2 つの素晴らしい記事を読みました。

Jonathan Creamerによる angularjs コントローラーの状態

Todd Motto によるAngularJS コントローラーの再考

これらの記事では、コントローラー (ビューとモデルの間の貧弱なブリッジを作成する) とファクトリー/サービス (ビジネス ロジックが実際に存在する必要がある場所) の正しい使用方法について著者が説明しています。

これは素晴らしい情報であり、自分のプロジェクトの 1 つでコントローラーのリファクタリングを開始することに非常に興奮しましたが、リッチ オブジェクト モデルを使用すると、記事に示されている構造が崩れることがすぐにわかりました。

「Angularjs コントローラーの再考」のセットアップの要約を次に示します。

コントローラーは次のとおりです。

app.controller('InboxCtrl', function InboxCtrl (InboxFactory) {

    var vm = this;

    vm.messages = InboxFactory.messages;

    vm.openMessage = function (message) {
      InboxFactory.openMessage(message);
    };

    vm.deleteMessage = function (message) {
      InboxFactory.deleteMessage(message);
    };

    InboxFactory
      .getMessages()
      .then(function () {
      vm.messages = InboxFactory.messages;
    });

});

そしてここに工場があります:

app.factory('InboxFactory', function InboxFactory ($location, NotificationFactory) {

  factory.messages = [];

  factory.openMessage = function (message) {
    $location.search('id', message.id).path('/message');
  };

  factory.deleteMessage = function (message) {
    $http.post('/message/delete', message)
    .success(function (data) {
      factory.messages.splice(index, 1);
      NotificationFactory.showSuccess();
    })
    .error(function () {
      NotificationFactory.showError();
    });
  };

  factory.getMessages = function () {
    return $http.get('/messages')
    .success(function (data) {
      factory.messages = data;
    })
    .error(function () {
      NotificationFactory.showError();
    });
  };

  return factory;

});

これは素晴らしいことです。providers(ファクトリは) シングルトンであるため、データはビュー間で維持され、API からリロードすることなくアクセスできます。

これは、トップレベルの object である場合messagesにうまく機能します。しかし、そうでない場合はどうなりますか? これが他のユーザーの受信トレイを閲覧するためのアプリだとしたら? あなたは管理者で、すべてのユーザーの受信トレイを管理および閲覧できるようにしたいと考えているかもしれません。複数のユーザーの受信トレイを同時にロードする必要があるかもしれません。これはどのように作動しますか?問題は、受信トレイのメッセージがサービスに保存されることInboxFactory.messagesです。

階層が次のような場合はどうなりますか。

                           Organization
                                |
              __________________|____________________
             |                  |                    |
         Accounting       Human Resources            IT
             |                  |                    |
     ________|_______      _____|______        ______|________
    |        |       |    |     |      |      |      |        |
   John     Mike    Sue  Tom   Joe    Brad   May    Judy     Jill
    |        |       |    |     |       |     |      |        |
   Inbox    Inbox  Inbox Inbox Inbox  Inbox Inbox  Inbox    Inbox

現在messages、階層のいくつかのレベルが深くなっており、それ自体には意味がありません。InboxFactory.messages一度に複数のユーザーのメッセージを取得する必要があるため、ファクトリにメッセージを保存することはできません。

これで、OrganizationFactory、DepartmentFactory、UserFactory、および InboxFactory が作成されます。「メッセージ」の取得は、 のコンテキスト内にある のコンテキスト内にある必要がuserありdepartmentますorganization。データはどのように、どこに保存する必要がありますか? どのように取得する必要がありますか?

では、これをどのように解決すべきでしょうか。コントローラ、ファクトリ/サービス、およびリッチ オブジェクト モデルをどのように構築する必要がありますか?

私の考えのこの時点では、リッチなオブジェクト モデルを持たずに、無駄のないものにすることに傾いています。コントローラーに注入された $scope にオブジェクトを保存するだけで、新しいビューに移動する場合は、API からリロードします。ビュー間でデータを永続化する必要がある場合は、サービスまたはファクトリを使用してそのブリッジを構築できますが、ほとんどの場合、この方法で行うべきではありません。

他の人はこれをどのように解決しましたか?これには何かパターンがありますか?

4

3 に答える 3

3

リッチ オブジェクト モデルを使用できますが、最上位ではないオブジェクトの場合、それらのファクトリは、シングルトンとして使用するのではなく、新しいインスタンスを作成するための API を公開する必要があります。これは、オブジェクト指向よりも機能的な、最近目にする多くのアプリの設計とは多少対照的です。どちらのアプローチの長所と短所についてもコメントしていません。また、Angular が採用を強制するとは思いませんどちらか一方。

疑似コードで再設計されたあなたの例:

app.controller('InboxCtrl', function InboxCtrl (InboxFactory) {

   var inbox = InboxFactory.createInbox();

   $scope.getMessages = function(){
      inbox.getMessages()
           .then(...)

   $scope.deleteMessages = function(){
      inbox.deleteMessages()
           .then(...)

});
于 2015-04-16T19:48:28.683 に答える