5

さて、シナリオを設定しましょう。

シナリオ: コンテンツ コントローラーがあります。このコンテンツは、写真、ブログ投稿など、何でもかまいません。これで、このコンテンツの html 内に、コメント コントローラーができました。CommentController の仕事は、コメントの読み込み、コメントの送信の許可などです。ただし、このコントローラーの機能は、その親に依存します。結局のところ、親がいない場合、あなたは何についてコメントしていますか?

問題: そうは言っても、問題を紹介しましょう。ContentController は、サーバーにデータを入力するために情報を要求する必要があり、その一部は一意の ID です。url-state を一意の ID として使用するなど、この問題には別の方法がありますが、これがこの問題を説明するために思いつく最善の方法です。

一意の ID がサーバーから ContentController に読み込まれます。次に、$scope にこの ID と実際のコンテンツを設定します。一方、CommentController はそれ自身のリソースをロードしたいと考えていますが、そのリソースのロードはすべて、親 ContentController のロードされたデータに依存しています。両方のコントローラーが同時にロードされるため、子 CommentController の実行の実行を通知または遅延させる方法が必要です。そうしないと、存在しない unique-content-id についてサーバーからコメントを要求しようとします。

質問: これは非常に基本的な問題で、多くの明白な答えがあります。しかし、私の質問は、このようなAngularはどのように行われるのでしょうか? 「角度のある方法」に最適な解決策は何でしょうか。

最も明白な方法は、単純にイベントのクリエーター/コンシューマーを持つことです。Angular には、これに対処する複数の方法があります。サービス、$scope.promise = promise、解決の約束、$scope.$broadcastなど。しかし、私には、この種のイベント化されたデザインは、ぎこちなく感じられます。私の ContentController が、その中にあるかもしれないし、ないかもしれないものによって行き詰まらないことを望みます。

別の方法は$watch、 など、必要な変数のスコープにすることです$scope.$watch('content.uid', function(newValue) {})。これは、上記のソリューションよりも良い感じで、結合が少ないです。まだ完璧ではありません..少なくとも私には。

最善の解決策は、達成方法がわからないものだと思います。コントローラーができるようにしたいと思います..遅延、子コントローラー(親)が非同期の何かをしている場合。これは単純さを暗示しているため、イベントよりも優れていると思います。これは基本的にはイベント ブロードキャストですが、「イベント」は 1 つしかないため、構文がきれいになることを願っています。不完全または完全です。ただし、上記のイベント化されたメソッドのいずれかを使用せずに、このようなことが可能かどうかはわかりません..これを達成する方法はありますか?

とにかく、これは、数週間前に Angular を学び始めて以来、私の頭の中で転がっている問題です。この件に関する洞察は大歓迎です。

読んでくれてありがとう!

4

1 に答える 1

7

特にAngularは非常に多くのものを非常にきれいにするため、Angularではイベントデザインや、$watch説明しているような目的での変数の使用を避けたくなる傾向がありますが、それは決してそれらを使用してはならないという意味ではありません.

とは言うものの、Angular を使用すればするほど、データ操作をコントローラーから引き出して、コントローラーが使用する「API」を公開するサービスやファクトリに取り込んでいることに気付きます。

たとえば、リストからアイテムを選択し、その情報を詳細ビューに表示する、従来のリスト ビュー/詳細ビュー シナリオがあるとします。

$resourceリスト用のバックアップされたファクトリと、選択したアイテムを管理するためだけのサービスがあるかもしれません:

app.factory('Thing', function($resource) {
  return $resource('/things/:id')
});

app.service('Selected', function() {
  this.thing = null;

  this.select = function(thing) { this.thing = thing; }
  this.clear = function(thing) { this.thing = null; }
});

このように分割することで、コントローラーは調整とビューへの応答のみを担当します。ええ、私はサービスをしなければ$watchなりSelectedませんが、そのようなことは多かれ少なかれ避けられません. ただし、次のように、データで何かを直接監視することから切り離しますuid

app.controller('List', function($scope, Thing, Selected) {
  $scope.things = Thing.query();

  // assuming something like 'ng-click="select(thing)"' in the view
  $scope.select = function(thing) {
    Selected.select(thing);
  };
});

app.controller('Detail', function($scope, Selected) {
  $scope.Selected = Selected;

  $scope.$watch('Selected.thing', function(thing) {
    $scope.thing = thing;
  });
});

そして、選択した「もの」のコメントをロードする必要があると仮定すると、Thingその機能でファクトリを拡張するだけです:

app.factory('Thing', function($resource) {
  var Thing = $resource('/things/:id');

  Thing.prototype.CommentResource = $resource('/things/:thingId/comments/:id');

  return Thing.
});

そして、コントローラーからその機能を使用します。

app.controller('Detail', function($scope, Selected) {
  $scope.Selected = Selected;

  $scope.$watch('Selected.thing', function(thing) {
    $scope.thing = thing;
    $scope.comments = thing.CommentResource.query({id: thing.id});
  });
});

概要

Angular を使用しているときに「古い方法に戻る」ように感じることを行うときに得られる不快感を私は知っています。

トリックは、コントローラーから調整以外のすべてを引き出すことだと思います。その後、いくつかのイベントを使用したり、大量の を割り当てたりする必要がある$watches場合でも、疎結合の方法でそうしています。

それはちょうど私の 2 セントです、それが役に立つことを願っています。

于 2013-02-21T21:59:32.777 に答える