javascript 创建可注入类(构造函数)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16052664/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 03:04:25  来源:igfitidea点击:

Create injectable class (constructor)

javascriptangularjs

提问by NilsH

I'm an AngularJS newbie, and I'm just starting to understand the concepts and differences of factory, serviceand controller. As I understand, a factoryis used to return a "value object" that can be injected. Most examples I've seen do something like this:

我是一个 AngularJS 新手,我刚刚开始理解factory,service和的概念和区别controller。据我了解, afactory用于返回可以注入的“值对象”。我见过的大多数例子都是这样的:

angular.module('module.factories', function() {
    factory('FactoryObject', function() {
        return {
            someFunction: function(someParam) {};
            someOtherFunction: function(someOtherParam) {});
        };
    });
});

In my controller, I want to be able to use this object, but I would like to initialize/instantiate it in the controller, since it can be re-initialized depending on events/actions in the controller. Therefore, I was wondering if I could return a constructor function in the factory instead?

在我的 中controller,我希望能够使用这个对象,但我想在控制器中初始化/实例化它,因为它可以根据控制器中的事件/动作重新初始化。因此,我想知道是否可以在工厂中返回构造函数?

angular.module('module.factories', function() {
    factory('FactoryObject', function() {

        function FactoryObject(initParam) {
        }

        FactoryObject.prototype.someFunction = function() {};

        return FactoryObject;

    });
});

Is this a suitable pattern for an angular factory? Or is it just "overkill" to use a factory for a custom object like this? Should I just include it in a library js file and reference it from there instead? One benefit of putting it in a factory is that it will be easy to mock it in a test since it will be injected where it's used. Are there any other mechanisms in Angular that could be used instead?

这是一个适合角度工厂的模式吗?还是将工厂用于这样的自定义对象只是“矫枉过正”?我应该将它包含在库 js 文件中并从那里引用它吗?将它放入工厂的一个好处是,在测试中很容易模拟它,因为它将被注入到使用它的地方。Angular 中是否还有其他机制可以替代?

采纳答案by hon2a

You're quite right, this is the way to create injectable "classes" (constructors). However, using factoryis only necessary when you need to inject other stuff to be used by your class:

你说得对,这是创建可注入“类”(构造函数)的方法。但是,factory仅当您需要注入其他类要使用的内容时才需要使用:

.factory('Class', ['$q', function ($q) {
    function Class () {}
    Class.prototype = {
        constructor: Class,
        doSomeAsyncAction: function () {
            return $q(function (resolve, reject) {
                // ...
            });
        },
        // ...
    };
    return Class;
})

If you're creating a completely independent class (e.g. some data structure), you can just use constant, so that your class is available even in service providers:

如果您正在创建一个完全独立的类(例如某些数据结构),您可以只使用constant,以便您的类即使在服务提供者中也可用:

(function (undefined) {
    function Class () {}
    Class.prototype = { ... };
    angular.module(...)
        .constant('Class', Class);
})();


As a sidenote, using provideris not going to help you in this. Providers serve a completely different purpose and (among other things) return a factory function that is then used _once_ on the first requested injection to create a single instance of the service. Providers are used to let you configure that single service instance in the _config phase_ of application construction (see documentation).

作为旁注,使用provider不会在这方面帮助您。提供者服务于一个完全不同的目的,并且(除其他外)返回一个工厂函数,然后在第一次请求注入时_once_使用该函数来创建服务的单个实例。提供程序用于让您在应用程序构建的 _config 阶段_配置该单个服务实例(请参阅文档)。

回答by Foo L

I am having the same problem. Here's what I implemented:

我有同样的问题。这是我实施的:

angular.module('foo', [])
.factory('Foo', ['$http', function($http) {
  return function(a, b) {
    this.arr = [];
    this.a = a;
    this.b = b;
    this.random = Math.floor(Math.random()*11);

    this.someFunc = function(c) {
      this.arr.push(c);
    };
  };
}]);

Now, I can do:

现在,我可以这样做:

var f1 = new Foo('A', 'B');
f1.random;  // i.e. 0
f1.someFunc('z');  // only affects f1.arr
var f2 = new Foo('C', 'D');
f2.random;  // i.e. 8
f2.someFunc('y');  // only affects f2.arr

Makes things more modularized. Hope that helps.

使事情更加模块化。希望有帮助。

回答by jolySoft

Here's how I solved the issue:

这是我解决问题的方法:

(function (myModule) {
    'use strict';

    myModule.service('myService', [
        function() {
            var serivce = this;
            var obj = null;

            service.func1 = function(a, b) {

            }

            service.func2 = function(c, d) {
                . . .
                return something;
            }

            var constructor = function(myObj) {
                obj = myObj;

                return service;
            }

            return constructor;
        }
    ]);
}(angular.module("myModule")))

(function(myModule) {
    'use strict';

    myModule.controller('myController', [
        '$scope', 'myService', function($scope, myService) {

            var service = myService($scope.someObj);

            $scope.someOtherObj = service.func2($scope.a, $scope.b);

        }
    ]);
}(angular.module("myModule")))

The only thing returned from the service is the constructor and then the service returns the rest of the service.

从服务返回的唯一内容是构造函数,然后服务返回服务的其余部分。

回答by Darryl

I had the same question. I found a terrific article on how to setup Object-oriented AngularJS Services. Here's the article. Pay attention to the note about using Factories and not Services. It also covers extending your objects. I found it super easy to setup and it fit perfectly with Angular while keeping the Javascript simple and straight forward.

我有同样的问题。我找到了一篇关于如何设置面向对象的 AngularJS 服务的了不起的文章。 这是文章。注意关于使用工厂而不是服务的注意事项。它还包括扩展您的对象。我发现它非常容易设置,并且与 Angular 完美契合,同时保持 Javascript 简单明了。

For Factory services which are singletons and do not need to be instantiated I use the object literal approach which has some performance advantages.

对于单例且不需要实例化的工厂服务,我使用具有一些性能优势的对象字面量方法。