2012-11-28 28 views
20

我有一個名爲'player'的服務,當flash對象完成加載時我需要更新服務。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') 

訪問服務,但同時,我需要更新的模塊中已經創建的實例返回「播放器」的新實例。有沒有辦法做到這一點?我只想要一個播放器的實例,但我需要從外部javascript初始化它。

回答

42

嗯,我真的不能看到你正在做的所有事情,但你可能大約有一半的路程。

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

injector.get()應該返回相同的服務實例作爲什麼在你的應用程序。你可能只是看到一個問題,讓你認爲你有一個不同的實例。

所以,你需要做的是:

  • 確保你在你的範圍從您的服務把什麼是對象參考。如果它是原始類型,它將不會是相同的引用,因此它不會更新。
  • 請務必使用angular.element(DOMElement).scope()取消角度元素的範圍,然後在其上調用$apply()

下面的代碼:

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) 

其他的想法:

  • 你可能要注入$window爲您服務,而不是使用窗口對象,以保持你的服務的可測性。
  • 指令可能是DOM操作(如創建Flash電影播放器​​)的更好選擇。
+0

爲什麼它不能直接應用於'scope()。myService'?使用'injector()。get'到'scope()。myService'有什麼區別? – pocesar

+6

在這個特殊的例子中,你可以。然而,這隻有在服務被添加爲範圍的屬性時纔有效,但情況並非總是如此。所以'injector.get()'是你必須使用的,如果你想在*所有情況下工作。 –

+0

你從使用'document.querySelector('[ng-controller]')獲得什麼?使用''[ng-controller]'或''[ng-app]'作爲'angular.element()'的參數的 好像工作的一樣好? – Superole