2013-03-13 11 views
11

これは私の問題です。モデルの値の変更は、その後、モデルの変更をリッスンするために$ウォッチを使用して登録されるハンドラが実行されるならば、そうAngularJSディレクティブ - jQueryウィジェットでngModelを使用する場合のベストプラクティス

module.directive('myWidget', [function() { 
    return { 
     require: "ngModel", 
     restrict: "A", 
     replace: true, 
     templateUrl: "templates/myWidget.html", 
     link: function(scope, element, attrs, ctrl) { 
      element.widget_name().on('value_updated', function(event) { 
       scope.$apply(function() { 
        var newModelValue = event.some_value; 
        ctrl.$setViewValue(newModelValue); 
       }); 
      }); 

      scope.$watch(attrs["ngModel"], function(value){ 
       element.widget_name('set_value', value); 
      }); 
     } 
    }; 
}]); 

:たとえば、私たちは舞台裏でいくつかのjQueryウィジェットを使用して次のディレクティブを、持っていますしたがって、ウィジェットの 'set_value'メソッドも実行されます。これは、 'value_updated'イベントがトリガーされることを意味します。

私の質問は:DOMイベントハンドラとウォッチャーの余分な呼び出しを避けるためにディレクティブで同様の動作を実装するベストプラクティスは何ですか?

答えて

4

scope.$watch()の代わりにctrl.$render()を実装することをおすすめします。 $ renderは、Angular内の何かがモデルを変更する場合にのみ呼び出されるべきです。 Fiddle example

これはあなたが言及しなかった問題を解決します。残念ながら、あなたが言及した問題は解決しません。ウィジェットでは、widget.on()イベントではなくblurイベントがバインドされています。おそらくそれはあなたのために働くでしょう–つまり、すべてのキーストロークではなく、ぼかしでモデルを更新するだけです(これは、あなたのウィジェットがキーストロークを受け入れることを前提としています)。

ウィジェット作成者に、イベントをトリガーしない「セット」メソッドを提供するよう依頼することもできます。それは$ render()メソッドで使うことができます。

+0

ありがとうございました。あなたのソリューションは私の問題を完全に解決します。しかし、ウォッチャーを使用するのが適切なのか、そして$レンダリングの実装時に教えてください。 – oaleynik

+2

@oaleynikでは、ng-modelの値がAngular内で変更されたため、何かしたいときはいつでも$ render()を実装する必要があります。 ng-modelは自動的に時計を設定し、$ render()は変更を通知すると呼び出されます。ですから通常、ng-modelでは独自の$ watchを使う代わりに$ renderを実装したいと思っています。 –

関連する問題