2012-11-28 17 views
20

私は 'player'というサービスを持っています。フラッシュオブジェクトの読み込みが完了したら、サービスを更新する必要があります。AngularJS:角度の外からサービスを更新する必要があります

mySongPlayer.factory('player', function() { 

var isPlayerLoaded = false; 
var playerHolder = ''; 

window.playerReady = function(thePlayer) { 
    playerHolder = window.document[thePlayer.id]; 
    addListeners(); 
    isPlayerLoaded = true; 
} 

var flashvars = { 
    file:"", 
    autostart:"true", 
    skin: "/skins/glow/glow.zip", 
} 

var params = { 
    allowfullscreen:"false", 
    allowscriptaccess:"always" 
} 

var attributes = { 
    id:"player1", 
    name:"player1"      
} 

swfobject.embedSWF("/player.swf", "player_placeholder", "100%", "40", "9.0.115", false, flashvars, params, attributes); 

var playObj; 
return playObj || (playObj = { 
    currentId: 'test', currentUrl: 'url', playerHolder: '' 
}); 
});​ 

私は

angular.element(DOMElement).injector().get('player') 

を使用してサービスにアクセスする方法を知っているが、私はすでにモジュールで作成されたインスタンスを更新する必要がありながら、それはプレイヤーの新しいインスタンスを返します。これを行う方法はありますか?私はプレーヤーのインスタンスを1つしか必要としませんが、JavaScriptの外部から初期化する必要があります。

答えて

42

まあ、あなたがしていることのすべてを実際に見ることはできませんが、おそらくあなたはその約1/2の方法でしょう。

Here is a working plunk of what I'm about to describe

injector.get()アプリで何とサービスの同じインスタンスを返すべきです。あなたはたぶんあなたに問題を見ているでしょうあなたは別のインスタンスを持っているとと思います。

だから、あなたが何をする必要があるかです:

  • 何があなたのサービスからあなたの範囲に入れていることはオブジェクト参照であることを確認してください。プリミティブ型の場合は、同じ参照ではないため、更新されません。
  • 角度要素の範囲をangular.element(DOMElement).scope()にしてから、$apply()を呼び出してください。あなたはおそらく、あなたのサービスに$windowを注入ではなく、あなたのサービスのテスト容易性を維持するために、ウィンドウオブジェクトを使用したい

    • app.controller('MainCtrl', function($scope, myService) { 
          // Set a var on the scope to an object reference of the 
          // (or from the) service. 
          $scope.myService = myService; 
      }); 
      
      app.factory('myService', function(){ 
          return { 
          foo: 'bar' 
          }; 
      }); 
      
      //do a little something to change the service externally. 
      setTimeout(function(){ 
          //get your angular element 
          var elem = angular.element(document.querySelector('[ng-controller]')); 
      
          //get the injector. 
          var injector = elem.injector(); 
      
          //get the service. 
          var myService = injector.get('myService'); 
      
          //update the service. 
          myService.foo = 'test'; 
      
          //apply the changes to the scope. 
          elem.scope().$apply(); 
      }, 2000) 
      

      その他の思考:ここ

  • コードです。
  • ディレクティブはおそらく、Flashムービープレーヤの作成などのDOM操作に適しています。
+0

なぜ 'scope()。myService'に直接適用できないのですか? 'inject()。get'を' scope()。myService'に使用することの違いは何ですか? – pocesar

+6

この特定の例では、ただし、サービスがスコープのプロパティとして追加された場合にのみ機能しますが、必ずしもそうではありません。ですから、 'injector.get()'は、*すべての*ケースでこれを動作させたい場合に使用する必要があります。 –

+0

'document.querySelector( '[ng-controller]')'を使って得られるものは何ですか?'' [ng-controller] ''や' '[ng-app]''を引数として '' angle.element() 'と同じように動作するようですね? – Superole

関連する問題