【问题标题】:How to extend an Angular factory如何扩展 Angular 工厂
【发布时间】:2016-05-19 18:24:38
【问题描述】:

我有一个数据服务文件,我想将其分解为更小的模块/部分。目前,代码如下:

angular
    .module('myapp')
    .factory('DataService', DataService)

DataService.$inject = ['$http'];

function DataService($http) {
    var service = {
        methodOne: methodOne,
        methodTwo: methodTwo,
        methodThree: methodThree
    };
    return service;
}

我想要做的:把这个文件分成另外三个文件,把每个方法放在各自的文件中。例如,有一个通用 DataService 文件和另外 3 个包含 3 个方法的实际实现的文件。我正在尝试创建如下所示的不同工厂,但我不确定这是否正确。调用它时我无法让它工作

angular
    .module('myapp')
    .factory('DataService', DataService)

DataService.$inject = ['$http'];

function DataService($http) {
    var service = {}; //creating empty object
    return service;
}


//File 1
angular
    .module('myapp')
    .factory('dataServiceOne', function(DataService){
        var extended = angular.extend(DataService, {})
        extended.methodOne = function() {
            console.log('working method one')
        }
        return extended;
    });

//File 2
angular
    .module('myapp')
    .factory('dataServiceTwo', function(DataService){
        var extended = angular.extend(DataService, {})
        extended.methodOne = function() {
            console.log('working method two')
        }
        return extended;
    });

//File 3
angular
    .module('myapp')
    .factory('dataServiceThree', function(DataService){
        var extended = angular.extend(DataService, {})
        extended.methodOne = function() {
            console.log('working method three')
        }
        return extended;
    });

然后在应用程序的其他地方调用它。给我一个错误,说 methodOne 不是函数。

...
DataService.methodOne() //this is implementation
...

【问题讨论】:

    标签: angularjs angularjs-directive angularjs-scope angular-ui-router angular-services


    【解决方案1】:

    代码的问题是dataServiceOnedataServiceTwodataServiceThree 如果您不注入它们,工厂不会被初始化 DataService 不会扩展,我创建了一个小提琴,它创建了一个包装服务来这样做,

    因此,您可以注入 WrapperService 而不是注入 DataService,它会反过来扩展 DataService(不确定是否能解决您的目的)

    JSFiddle

     //File 4
     angular
       .module('myapp')
       .factory('WrapperService', function(dataServiceOne, dataServiceTwo,    dataServiceThree, DataService) {
           return DataService
       });
    
     angular
      .module('myapp')
        .controller("MYController", ["$scope", "WrapperService",    function($scope, DataService) {
          DataService.methodOne();
          DataService.methodTwo();
          DataService.methodThree();
       }]);
    

    【讨论】:

    • 我注意到您在 MYController 中注入了“WrapperService”,但随后您在参数中使用了 DataService。您是说参数中的 WrapperService 而不是 DataService 吗?
    • 不!如果你在 Wrapperservice 中看到我正在返回 DataService 的对象,并且在注入时我刚刚将 WrapperService 重命名为 DataService,你可以调用你想要的任何东西:)
    • 我已经这样做了,但是当我尝试在指令中使用 DataService.methodOne() 时,我收到一条错误消息,指出 methodOne 不是函数。我得到了所有方法的这个......我已经注入了所有必要的组件。
    • 你查看过JSFiddle,你能创建一个Fiddle并分享给我吗?
    【解决方案2】:

    这就是你要找的吗? AngularJS 中的继承

    // Inject your factories in your controller(s)
    var module = angular.module();
    module.controller('yourController', ['$scope', 'DataServiceOne', 'DataServiceTwo', 'DataServiceThree', 
    function($scope, DataServiceOne, DataServiceTwo, DataServiceThree) {
        // use these factories
    }
    ]);
    
    
    module.factory('DataService', function ($q, $http) {
       return {
          //public API
       };
    });
    
    module.factory('DataServiceOne', function (DataService, $sce) {
       var child = Object.create(DataService);
       child.methodOne = function () {
         //extending the parent
         console.log('working method one');
       };
       return child;
    });
    
    module.factory('DataServiceTwo', function (DataService, $sce) {
       var child = Object.create(DataService);
       child.methodOne = function () {
          //extending the parent
          console.log('working method two');
       };
       return child;
    });
    
    module.factory('DataServiceThree', function (DataService, $sce) {
       var child = Object.create(DataService);
       child.methodOne = function () {
          //extending the parent
          console.log('working method three');
       };
       return child;
    });
    

    【讨论】:

    • 是的,像这样,但是,我该如何实现它。假设我想从 DataService 中调用 methodOne? DataService.methodOne?
    • 我更新了我的答案。请看一看。您可以将这些子工厂注入到您的控制器中。
    【解决方案3】:

    您可以将动态方法添加到任何对象,只需将函数分配给对象的属性即可。我在这里使用了控制器,所以很容易看到,但概念是一样的。

    <html>
    <head>
        <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/angular_material/1.0.7/angular-material.min.css" />
    </head>
    
    <body ng-app="app">
        <div ng-controller="myController as ctrl">
            <div>{{ctrl.hello}}</div>
            <div>{{ctrl.method1()}}</div>
            <div>{{ctrl.method2()}}</div>
            <div>{{ctrl.method3()}}</div>
        </div>
    
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js "></script>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-animate.min.js "></script>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-aria.min.js "></script>
        <script src="https://ajax.googleapis.com/ajax/libs/angular_material/1.0.7/angular-material.min.js "></script>
        <script src="dynamicmethods.js"></script>
            <script>
            angular.module('app', []).controller("myController",myController);
    
            function  myController($scope){
                var ctrl = this;
                ctrl.hello ="Hello"
                decorate() ;
    
                function decorate() {
                    ctrl.method1 = method1
                    ctrl.method2 = method2
                    ctrl.method3 = method3
                }    
    
            };
        </script>
    </body>
    </html>
    

    dynamicmethods.js

    function method1() {
        return "I'm one"
    }
    
    function method2() {
        return "I'm two"
    };
    
    function method3() {
        return "I'm three"
    }
    

    【讨论】:

    • 这与我想要实现的目标完全不同。我想为我指定的功能有不同的工厂。这就是我要努力的方向
    • 我想我当时没有关注这个问题。据我所知,您基本上是在尝试动态地向工厂添加方法,但看起来您对我来说过于复杂了。基本上只要这些函数在内存中,您就可以将它们作为成员分配给您喜欢的任何对象。我有一个通用服务,用于我的所有 oData 源,我用它做一些非常相似的事情。
    • 如果我这样做并且method1在我的工厂中并且实际的method1定义在另一个文件中,我会收到错误“ReferenceError:method1未定义”
    • 您是否在某处加载了单独的 Javascript 文件?我只是将答案中的代码更改为来自单独文件的引用函数,它仍然有效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-02
    • 1970-01-01
    • 2011-04-20
    • 1970-01-01
    • 1970-01-01
    • 2018-06-22
    相关资源
    最近更新 更多