【问题标题】:Extending a base class in an Angular service在 Angular 服务中扩展基类
【发布时间】:2014-07-13 07:45:09
【问题描述】:

我有一个基类,我想在服务中扩展它以帮助将数据获取到角度范围内。我在网上搜索了解决方案,但没有找到我喜欢的解决方案。我有一个用于访问设备文件系统的基类

类结构:

var cOfflineStorageBase = Class.extend({
   init: function(){
   },
   CreateFolderDir: function(){
   },
   DeleteAll: function(){
   },
   DeleteDirectories: function(){
   },
   DeleteItem: function(){
   },
   GetFiles: function(){
   },
   FileExists: function(){
   }, 
   GetPath: function(){
   },
   GetObject: function(){
   },
   SaveObject: function(){
   },   
});

我希望能够在几个不同的角度服务(即offlineCart、offlineCustomLists 等)中扩展这个类,其中每个服务都可以使用存储库来存储各种不同的数据类型。我正在寻找最好,最合适的方式来做到这一点。在 vanilla JavaScript 中,只需执行以下操作:

var newClass = cOfflineStorageBase.extend({
   //add new stuff here
});

但我想以有角度的方式做同样的事情。

我一直在考虑的方法是使用 angular.extend 功能,但我不确定这是否合适,或者这样的方法是否更合适:

app.factory('someChild', ['$http' , 'cOfflineStorageBase', 
            function($http, cOfflineStorageBase){
  var SomeClass = cOfflineStorageBase.extend({
     init: function(){
        this._super.init()
     },
     //Add more stuff here
  });
  return SomeClass;
}]);

如果这些方法是正确的,或者是否有另一种更适合我想要完成的方法,我想要一些建议。我也希望或者宁愿需要在大部分代码中使用 Promise,因为它是异步的。

【问题讨论】:

  • 工厂必须返回一个实例(即new SomeClass()),或者您应该使用角度服务(即angular.service('someChild', SomeClass))。当然,除非你想要的是返回一个函数构造函数而不是一个服务实例。

标签: javascript angularjs oop inheritance angular-services


【解决方案1】:

我最近完成了这个技巧。

我将从定义一个普通的 JavaScript 构造函数开始。这不需要是角度服务。我所做的是,稍后,扩展构造函数可以通过参数传递任何必要的注入。所以,这将是我的角度服务的基础“类”。这是我要公开任何我希望所有 Angular 服务继承的地方。

function ParentService($http) {
   this.$http = $http;
}

ParentService.prototype.foo = function () {
    alert("Hello World");
};

然后我将继续使用原型继承定义一个子构造函数。这个构造函数确实是一个角度服务(你可以通过我最后使用的$inject 来判断)。

function ChildService($http) {
    Parent.call(this, $http);
}

ChildService.prototype = new ParentService();
ChildService.prototype.baz = function() {
   return this.$http.get('/sample/rest/call');
}
ChildService.$inject = ['$http'];

然后我将继续在相应的角度模块中注册服务点菜:

var app = angular.module('SampleApp', []);
app.service('child', ChildService);

最后,在我的控制器中,我将简单地注入我的服务,这将是我的 ChildService 构造函数的一个实例,它又扩展了我的 ParentService 构造函数:

app.controller('MainCtrl', ['$scope', 'child', function ($scope, child) {
    child.foo(); //alert("Hello World")
    var promise = child.bar();
}]);

你可以看到一个 JSFiddle here

还有一个来自 ngConf 在 Youtube 上的有趣视频,名为 Writing A Massive Angular App,其中涵盖了其中一些主题以及一些关于 Angular 代码可重用性的其他想法。

【讨论】:

  • 同样的方法是否适用于已经完成的基类,如上面的 cOfflineStorageBase 类。它是由一位程序员同行编写并在现有类中扩展的,我正在寻找一种可能不需要重写类的解决方案
  • 这种方法适用于您有权访问的任何现有构造函数。另外,不需要像我一样做,你也可以使用 Object.create() 和角度工厂方法。
  • 好的,我认为这种方法可能对我有用。我将尝试实现它。感谢您的帮助。
【解决方案2】:

这个问题是在 18 个月前提出并回答的。我最近在一个项目上遇到了同样的问题。我想定义一个基本模型,我可以用它来建立工厂。 Angular 有一个非常简单的 Provider 来帮助解决这个问题,称为 Value Provider,Angular 使用 Value Recipe 来实现它。

我不确定您当时使用的是哪个版本的 Angular,但这可以追溯到 (AFAIK) 版本 1.3.0。 (在撰写本文时,当前稳定版为 1.4.8)

我也在使用 John Resig 的 Simple Inheritance Script. http://ejohn.org/blog/simple-javascript-inheritance/

这是我的代码的 sn-p(删除了大部分应用程序特定的逻辑)。

var MyApp = angular.module( 'MyApp',['ngResource','ngAnimate','ngSanitize'] );

/* ==================================================================================== */
// -   Base Model Class   -------------------------------------------------------------
/* ==================================================================================== */

MyApp

/**
 * BaseModel - Value Provider
 * 
 */
.value( 'BaseModel',Class.extend({

    attribs: {},

    init: function(){

        var self = this;

        _active = true;

        _new = true;

        _origs = {};

        _loadByObject = function( obj ){ ... }
    },

    get: function( key ){ ... },
    set: function( key,val ){ ... },

    isNew: function(){ ... },
    keep: function(){ ... },
    remove: function(){ ... },

    load: function( obj ){ ... }
    verify: function(){ ... },      
    save: function(){ ... },

}))

.factory( 'UserFactory', 
    [ '$http', '$q', 'BaseModel', 
    function( $http, $q, BaseModel ){

    var UserFactory = BaseModel.extend({

        init: function(){

            this._super( false );

            _fields = [
                'first', 'last', 'email', 
                'phone', 'password', 'role'
            ];

            _permitted = [
                'first', 'last', 'email', 
                'phone', 'password', 'role'
            ];

            _required = [
                'first', 'last', 'email', 'role'
            ];

            _resource = "users";

            _api = "users";

        }

    });

    return UserFactory;

}])

我也很想听听任何人的反馈。

这是 Angular 文件: https://code.angularjs.org/1.3.0/docs/guide/providers

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-23
    • 2019-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-07
    • 1970-01-01
    相关资源
    最近更新 更多