为什么从外部角度调用服务而不是单例?

时间:2014-05-04 21:14:49

标签: javascript angularjs

我正在开展一个项目,我需要从角度服务外部访问服务。不幸的是,似乎从angular外部检索的服务与app内部的实例不同。实际上,每次调用它都是一个新实例。我在下面创建了一个示例来演示问题。

<div ng-controller="controller">
    <div>
        <span ng-bind="count"></span>
        <input type="button" value="Inside" ng-click="inc()"></input>
    </div>
    <div>
        <span id="outside-count">0</span>
        <input type="button" value="Outside" onclick="outside()"></input>
    </div>
</div>

和javascript ...

angular.module('Services', [])
.service('svc', function() {
    var svc = {
        count: 0,
        increment: function(){svc.count++;}
    };
    return svc;
});

angular.module('MyApp', ['Services'])
.controller('controller', ['$scope', 'svc', function($scope, svc) {
    $scope.count = svc.count;
    $scope.inc = function() {
        svc.increment();
        $scope.count = svc.count;
    };
}]);

var outside = function() {
    var svc = angular.injector(['ng', 'Services']).get('svc');
    svc.increment();
    angular.scope().$apply();
    document.getElementById('outside-count').innerHTML = svc.count;
};

我期望外部计数按钮会增加与ng-controller中相同的服务对象。但是,每次都会获得一个新实例,因为对该按钮的连续单击始终显示1。 “内部”按钮继续按预期增加单个服务。

我是否有不同的方式从外部角度访问该服务以获取该服务的单例实例?

Here is a fiddle上述代码。

2 个答案:

答案 0 :(得分:3)

Angular中的服务是单例,因为每个注射器只创建一次。

然而,

angular.injector会创建一个新的注入器功能。

您需要获取当前的应用注入器:angular.element(domElement).injector()

演示http://jsfiddle.net/BsLK8/

演示内部同步的演示http://jsfiddle.net/kW2BC/

答案 1 :(得分:2)

您正在从这些模块创建新的注入器,这就是您获取所请求服务的新实例的原因。相反,您需要获取属于具有所需数据/实例的元素的当前注入器。要做到这一点,请使用:

//assuming ng-app='MyApp' is on the html tag
//otherwise pass in the correct element.
var svc = angular.element(document).injector().get('svc');