AngularJS:我需要从angular之外更新服务

Ato*_*mix 26 angularjs

我有一个名为'player'的服务,我需要在flash对象加载完成后更新服务.

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: ''
});
});?
Run Code Online (Sandbox Code Playgroud)

我知道如何使用访问服务

angular.element(DOMElement).injector().get('player')
Run Code Online (Sandbox Code Playgroud)

但是当我需要更新已在模块中创建的实例时,它会返回'player'的新实例.有没有办法做到这一点?我只想要播放器的一个实例,但我需要从外部javascript初始化它.

Ben*_*esh 53

好吧,我无法真正看到你正在做的所有事情,但你可能只有一半左右.

这是我即将描述的工作内容

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)
Run Code Online (Sandbox Code Playgroud)

其他想法:

  • 您可能希望注入$window您的服务,而不是使用窗口对象,以维护您的服务的可测试性.
  • 指令可能是DOM操作的更好选择,例如创建Flash电影播放器​​.

  • 在这个特定的例子中,你可以.但是,只有在将服务添加为范围的属性时才会起作用,但情况并非总是如此.所以`injector.get()`是你必须使用的,如果你想在*all*的情况下工作. (6认同)