简体   繁体   English

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

[英]How can I create an angular JS service that isn't a singleton?

Because every service is a singleton. 因为每项服务都是单身人士。 & calling $injector.get() still gives me the same instance everytime. 并调用$ injector.get()仍然每次都给我相同的实例。

How can I use multiple instances of a service inside another service? 如何在另一个服务中使用多个服务实例? Keeping in mind that the declaration of my non-singleton class, must not pollute the global namespace etc. 请记住,我的非单件类的声明,不得污染全局命名空间等。

My example is below: (Where I wanted $injector.get('serviceCall') to be a different instance everytime, but I've since discovered it can't be. 我的例子如下:(我希望$ 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;
}]);

and my serviceCall Service: 和我的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;
});

You'll need to implement the factory pattern. 您需要实现工厂模式。 Return a service that creates object instances for you. 返回为您创建对象实例的服务。 $injector.get('serviceCall') will always return a singleton, but there's nothing stopping you making that singleton's job generating new object instances for you. $injector.get('serviceCall')将始终返回一个单例,但没有什么能阻止你让单例的作业为你生成新的对象实例。

Rather than using $injector, directly DI a serviceCallFactory service, and call methods on that to generate the new serviceCall instances. 而不是使用$ injector,直接DI一个serviceCallFactory服务,并在其上调用方法来生成新的serviceCall实例。

Agree with @eddiec. 同意@eddiec。

The thing is, when you're new to angular, you suppose factory is like the design pattern Factory : a function that provides a new instance at each call. 问题是,当你刚接触角度时,你会认为工厂就像设计模式工厂:一个在每次调用时提供新实例的功能。 However, 'factory' in angular is actually a function that is called only one time and that returns an object that will be "cached". 但是,angular中的'factory'实际上是一个只调用一次的函数,它返回一个将被“缓存”的对象。 Now, every time you DI with the factory name, this object will be injected, not the factory function. 现在,每次使用工厂名称DI时,都会注入此对象,而不是工厂功能。

So, if you want a "real" (the design pattern) Factory, you need to create a function that returns a new object. 因此,如果您需要“真实”(设计模式)Factory,则需要创建一个返回新对象的函数。

Here is a quick implementation 这是一个快速实现

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;
}]);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM