2013-02-23 10 views
28

私は、このHTMLました:AngularJSは、サービスを利用するこの方法ですか?

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

をし、コントローラは次のようになります。この場合、結果には

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

サービスが正常に動作しますので、私はここにコードを貼り付けていない... 私は、このようにHTMLを変更し、 "こんにちは、世界!" です :

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

しかし、これはうまくいかない。

私は、コントローラ変更:

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

をして、HTML

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

は、これは動作します!

だから私の質問は次のとおりです。

が、これはHTMLで直接サービスの機能を使用するための唯一の方法である、または私は何かが欠けていますか?

答えて

61

AngularJSテンプレートは、スコープで使用可能な関数のみを呼び出すことができます。だから、どのようなアプローチをとっても、スコープ上であなたの機能を持つ必要があります。

あなたは、いくつかのオプション持っているテンプレートから直接呼び出し可能であるためにあなたのサービスの機能が必要な場合:

あなたが試してみた1 - つまり、スコープに全体のサービスを公開します:テンプレートで

$scope.service = service; 

、その後:

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

このIコントローラー内の1つのライナーを使用して、すべてのサービスメソッドをスコープで使用できるようにして、テンプレートに使用できるようにします。

暴露する内容を正確に制御を持っている方法1

ずつを公開:

$scope.getUsername = service.getUsername; 

して、テンプレートに:

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

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

方法 proxing公開:どちらか(一日の終わりに機能がスコープで終わる必要があります

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

あなたがそれらのいずれかの方法を使用したり、ミックスし、それらを組み合わせることができますが、を直接またはスコープ上に公開された別のオブジェクトを介して)。

+4

私はそれがいくつかのタイプのビューサービスではなく、あなたのテンプレートがseriveのすべての機能を必要とするなら、スコープにサービスオブジェクト全体を追加することを避けるでしょう。一般的には、テンプレートに必要な範囲にデータ/関数を追加するだけです。 –

+0

@AndersEkdahl私は同意します。おそらく、あなたはこのメソッドを非常に頻繁に使いたくないでしょう。しかし、私はすべてがサービスに依存していると思います。私は単にここにオプションを提示するだけで、考慮すべき異なるトレードオフがあります。 –

+0

@ pkozlowski.opensource答えが – Bruno

1

$ 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. Best practice concerning proper two way data binding from a service

私は現在、このような何かをしようとしています。

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

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

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

私はこれをやっている理由は、我々は可能な限りクリーンとしてのコントローラを維持し、1つの集中の場所ですべての私たちのデータを持つようにしたいということです。また、サービス内のほとんどのデータを公開する必要があります。

13

それを行うための別の方法は:

$ rootScope上でサービスを公開:

テンプレートで
$rootScope.service = service; 

、その後:

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

あなたはこれを上行うことができますapp.runを実行すると、アプリケーションのすべてのビューでサービスが取得されます。このメソッドを認証サービスに使用できます。

+7

汚れています。大好きです ! –

+0

このようなテストは面白いと思います。 –

関連する問題