如何创建不是单例的角度JS服务?

时间:2013-12-02 06:11:38

标签: angularjs dependency-injection

因为每项服务都是单身人士。 &安培;调用$ injector.get()仍然每次都给我相同的实例。

如何在其他服务中使用多个服务实例?请记住,我的非单件类的声明不得污染全局命名空间等。

我的例子如下:(我希望$ injector.get('serviceCall')每次都是一个不同的实例,但我发现它不可能。

app.factory('reportsService', ['$injector', function ($injector) {
    var o = {};
    o.getServiceCall = function () {
        return $injector.get('serviceCall');
    };
    o.getOriginCompositionData = function (ajaxOptions) {
        ajaxOptions.url = '/test/SpiderRequestOriginComposition';
        o.getServiceCall().initialize(ajaxOptions);
    };
    o.getExeuctionTimeData = function (ajaxOptions) {
        ajaxOptions.url = '/test/SpiderRequestExeuctionTime';
        o.getServiceCall().initialize(ajaxOptions);
    };
    o.getCacheCompositionData = function (ajaxOptions) {
        ajaxOptions.url = '/test/SpiderRequestCacheComposition';
        o.getServiceCall().initialize(ajaxOptions);
    };
    return o;
}]);

和我的serviceCall服务:

app.factory('serviceCall', function () {
    var o = {};
    o.initialize = function (userOptions) {
        o.options = o.getOptions(userOptions);
        o.call();
    };
    o.getOptions = function (userOptions) {
        var defaultOptions = {
            action: 'post',
            url: '', //userOptions
            successCallback: '', //userOptions
            errorCallback: '', //userOptions
            dataType: 'json'
        };
        var options = $.extend(defaultOptions, userOptions);
        return options;
    };
    o.call = function () {
        $.ajax({
            type: o.options.action,
            url: o.options.url,
            data: o.options.data,
            success: function (r) {
                o.options.successCallback(r);
            },
            error: function (xhr, textStatus, errorThrown) {
                //TODO
            },
            dataType: o.options.dataType,
            contentType: o.options.contentType
        });
    };
    return o;
});

2 个答案:

答案 0 :(得分:5)

您需要实施工厂模式。返回为您创建对象实例的服务。 $injector.get('serviceCall')将始终返回一个单例,但没有什么能阻止你让单例的作业为你生成新的对象实例。

而不是使用$ injector,直接DI一个serviceCallFactory服务,并在其上调用方法来生成新的serviceCall实例。

答案 1 :(得分:3)

同意@eddiec。

问题是,当你刚接触角度时,你会认为工厂就像设计模式工厂:一个在每次调用时提供新实例的函数。但是,angular中的'factory'实际上是一个只调用一次的函数,它返回一个将被“缓存”的对象。现在,每次使用工厂名称DI时,都会注入此对象,而不是工厂函数。

因此,如果你想要一个“真实”(设计模式)Factory,你需要创建一个返回一个新对象的函数。

这是一个快速实现

app.factory('serviceCallFactory', function () {

    function o() {
        var o = {};
        o.initialize = function (userOptions) {
            o.options = o.getOptions(userOptions);
            o.call();
        };
        o.getOptions = function (userOptions) {
            var defaultOptions = {
                action: 'post',
                url: '', //userOptions
                successCallback: '', //userOptions
                errorCallback: '', //userOptions
                dataType: 'json'
            };
            var options = $.extend(defaultOptions, userOptions);
            return options;
        };
        o.call = function () {
            $.ajax({
                type: o.options.action,
                url: o.options.url,
                data: o.options.data,
                success: function (r) {
                    o.options.successCallback(r);
                },
                error: function (xhr, textStatus, errorThrown) {
                    //TODO
                },
                dataType: o.options.dataType,
                contentType: o.options.contentType
            });
        };
        return o;
    }

    return {
        create : function () {
            return new o();
        }
    }

});


app.factory('reportsService', ['serviceCallFactory', function (serviceCallFactory) {
    var o = {};
    o.getServiceCall = function () {
        return serviceCallFactory.create();
    };
    o.getOriginCompositionData = function (ajaxOptions) {
        ajaxOptions.url = '/test/SpiderRequestOriginComposition';
        o.getServiceCall().initialize(ajaxOptions);
    };
    o.getExeuctionTimeData = function (ajaxOptions) {
        ajaxOptions.url = '/test/SpiderRequestExeuctionTime';
        o.getServiceCall().initialize(ajaxOptions);
    };
    o.getCacheCompositionData = function (ajaxOptions) {
        ajaxOptions.url = '/test/SpiderRequestCacheComposition';
        o.getServiceCall().initialize(ajaxOptions);
    };
    return o;
}]);