web-dev-qa-db-ja.com

AngularJS、このサービスの使用方法は良いですか?

私はこのHTMLを持っています:

<p>Hello {{name}}</p>

そしてコントローラは:

function myCtrl(scope, service) {
    scope.name = service.getUsername(); // service.getUsername() return "World!"
}
myCtrl.$inject = ['$scope', 'originalService'];

サービスは正常に機能するため、ここにコードを貼り付けません...この場合、結果は "Hello world!"です。HTMLを次のように変更しました。

<p>Hello {{service.getUsername()}}</p>

しかし、これは機能しません。

コントローラを変更しました:

function myCtrl(scope, service) {
    scope.ser = service;
}
myCtrl.$inject = ['$scope', 'originalService'];

そして、HTML

<p>Hello {{ser.getUsername();}}</p>

これで動作します!

だから私の質問は:

これは、HTMLでサービスの機能を直接使用する唯一の方法ですか、それとも何か不足していますか?

28
Bruno

AngularJSテンプレートは、スコープで使用可能な関数のみを呼び出すことができます。したがって、どのようなアプローチをとっても、スコープに関数を含める必要があります。

サービスの関数をテンプレートから直接呼び出すことができるようにする場合は、いくつかのオプションがあります。

試したもの-つまり、スコープでサービス全体を公開します

$scope.service = service;

そしてテンプレートで:

<p>Hello {{service.getUsername();}}</p>

これはコントローラーのワンライナーであり、すべてのサービスメソッドをスコープで、したがってテンプレートで使用できるようにします。

メソッドを1つずつ公開します

公開されるものを正確に制御するには:

$scope.getUsername = service.getUsername;

そしてテンプレートで:

<p>Hello {{getUsername();}}</p>

これには、より多くの作業公開メソッドが必要ですが、公開されるものをきめ細かく制御できます。

露出プロキシメソッド

$scope.getMyUsername = function() {
   //pre/post processing if needed 
   return service.getUsername();
};

これらのメソッドを使用するか、それらを混合して組み合わせることができますが、1日の終わりに、関数はスコープで終了する必要があります(直接またはスコープで公開されている別のオブジェクトを介して)。

61

それを行う別の方法:

$ rootScopeでサービスを公開します:

$rootScope.service = service;

そしてテンプレートで:

<p>Hello {{service.getUsername();}}</p>

これはapp.runで実行でき、アプリのすべてのビューでサービスを取得します。この方法を認証サービスに使用できます。

14

$ scope内でサービスを公開する別の方法は、サービスメソッド/データオブジェクトに関数ポインターを追加することです。

scope.serviceData = service.data;
// Or
scope.getServiceData = service.getData;

ビュー内で、括弧を使用して呼び出すことができます。

<input ng-model="serviceData().key" />
// Or
<input ng-model="getServiceData().key" />
// Or
{{getServiceData().key}}

私はこのアプローチが個人的に気に入っており、複数のビューを同じデータと同期させるために現在使用しています。ただし、ここで説明するように、いくつかの問題が発生します。 AngularJS。サービスからの適切な双方向データバインディングに関するベストプラクティス

多くのデータを公開することに関して、私は現在、このようなことをやろうとしています。

// Within your view.
{{getServiceDataByKey('key')}}

// In your controller.
scope.getServiceDataByKey = service.getServiceDataByKey;

// In your service.
getServiceDataByKey : function (key) {
   return dataObject[key];
}

私がこれを行う理由は、コントローラーをできるだけクリーンに保ち、すべてのデータを1か所に集中させたいからです。また、サービス内のほとんどのデータを公開する必要があります。

1
ngr