web-dev-qa-db-ja.com

サービス内の$ watch?

サービス内のオブジェクトの配列に$watchを設定することは可能ですか($watch宣言自体がサービス内にあることを望みます)?

60
Kuba Orlik

$rootScopeを挿入し、関数を使用して$watchメソッドの最初の引数を使用することで、ウォッチセットに任意の式を追加できます。擬似コード:

$rootScope.$watch(function() {
  return //value to be watched;
}, function watchCallback(newValue, oldValue) {
  //react on value change here
});

$watchメソッドへの3番目のブール引数を忘れないでください。オブジェクト全体の変更を詳細に監視する場合は、trueを指定する必要があります。

121

サービスはその性質上、クラスおよびハウスメソッドのようなものです。引数がスコープであり、監視式を適用するコントローラーから呼び出すメソッドを設定できます。

app.service('myservice',function(){
    this.listen = function($scope) {
        $scope.$watch(function(){return someScopeValue},function(){
           //$scope.dosomestuff();
        });
    }
});

//your controller

function myCtrl($scope,myservice) {
    $scope.listen = function() {
        myservice.listen($scope);
    }

    //call your method
    $scope.listen();
}

更新:サービス内のプライベートローカル変数を監視しようとしている場合は、$ rootScopeを使用して受け入れられた答えを参照してください。ローカルスコープ内で$ scope変数を$ watchしようとしている場合は、上記が最善の方法です。彼らは2つの非常に異なることを達成しています。

15
btm1

達成したいことを明確にできますか?私が理解しているように、あなたはモデルとしてサーバーからオブジェクトの配列を取得しています。その後、それは明確ではありません:

  1. 配列内の一部のオブジェクトが変更されているかどうかを確認しますか(繰り返しプールを行う場合のサーバーへの最後の呼び出し以降)。
  2. 配列内の一部のオブジェクトが、フロントエンドコントロール要素を介してユーザーによって変更されたかどうかを確認しますか?

ケース1では、実際に$ watch(または$ watchCollection)を使用する必要はありませんが、サーバーから受け取った配列を反復処理し、変更を確認する必要があります($ watchCollecitonが行うことと同じです)。オブジェクトが現在保持しているものと異なる場合-この要素でobject。$ save()を呼び出します。

ケース2では、パラメーターとしてサービス関数に渡される$ scopeで$ watchCollection()を使用するか、$ rootScopeに配列を保持している場合は$ rootScopeを使用します。

シナリオを明確にする場合は、実際のコードを提供できます。

ちょっと、2つの異なるコントローラーでかなり大きな時計をセットアップする状況がありました。

私は自分のサービスで機能するように定義したコードを複製したくないので:

angular
    .module('invoice')
    .factory('invoiceState', function () {
        var invoice = {
            client_info: {
                lastname: "",
                firstname: "",
                email: "",
                phone: "",
                id_client: "",
                ... 
             }
        }
        invoice.watchAccommodation = function (newVal, oldVal) {
            var accommodation = newVal;
            //Whatever you would normally have in your watch function
        }

次に、サービスを注入したコントローラーのウォッチでこの関数を呼び出すことができます

function NewInvoiceCtrl(invoiceState) {
    $scope.$watch('invoice.accommodation',invoiceState.watchAccommodation, true);
}

私はAngularJSの経験があまりないので、このアプローチのパフォーマンスの側面に実際に入ることはできませんが、動作します;)

0
Dennis de Best