问题 Angular2依赖注入,在类继承期间不注入服务


我在用着 angular2 同 Typescript。我正在努力创造一个 base class 可以由其他类继承并在基类内继承服务。到目前为止,我无法得到 ajaxService  injected 正确地进入了 base class 那就是 inherited 进入 user class。特别是当用户被实例化,然后是 save() 方法是从 user 例如,以下行 base classreturn _this._ajaxService.send(options); 从那以后就行不通了 _ajaxService 未定义。

这里有一个 user class 延伸了 base class

import {Base} from '../utils/base';

export class User extends Base {

  // properties
  id = null;
  email = null;
  password = null;
  first_name = null;
  last_name = null;

  constructor(source) {
    _super.CopyProperties(source, this);
  }
}

这里是 base class

import {Component} from 'angular2/core';
import {AjaxService} from './ajax.service';

@Component({
  providers: [AjaxService]
})

export class Base {

  constructor(private _ajaxService: AjaxService) { }

  // methods
  public static CopyProperties(source:any, target:any):void {
    for(var prop in source){
      if(target[prop] !== undefined){
          target[prop] = source[prop];
      }
      else {
          console.error("Cannot set undefined property: " + prop);
      }
    }
  }

  save(options) {
    const _this = this;
    return Promise.resolve()
    .then(() => {
      const className = _this.constructor.name
                            .toLowerCase() + 's';
      const options = {
        data: JSON.stringify(_this),
        url: className,
        action: _this.id ? 'PATCH' : 'POST';
      };

      debugger;
      return _this._ajaxService.send(options);
    });
  }
}

这样可以正常工作 AjaxService 没有注入基类。我想这是有道理的,因为用户被实例化而不是基础。

那我怎么用呢 AjaxService 在里面 Base module 什么时候`Base模块正在另一个类上扩展?

我想当我实例化用户时,会调用用户类中的构造函数,但是不会调用注入服务的基类中的构造函数。

这是 AjaxService

   import {Injectable} from 'angular2/core';

@Injectable()

export class AjaxService {

  // methods
  send(options) {
    const endpoint = options.url || "";
    const action = options.action || "GET";
    const data = options.data || {};

    return new Promise((resolve,reject) => {
      debugger;
      $.ajax({
        url: 'http://localhost:3000' + endpoint,
        headers: {
          Authentication: "",
          Accept: "application/vnd.app.v1",
          "Content-Type": "application/json"
        },
        data: data,
        method: action
      })
      .done((response) => {
        debugger;
        return resolve(response);
      })
      .fail((err) => {
        debugger;
        return reject(err);
      });
    });

  }

}

6158
2017-12-27 07:06


起源

据我所知,注射剂(AjaxService)需要注释 @Injectable() 在TS。 - Günter Zöchbauer
你在哪里用的 User 类?它是一个组件吗?它有模板吗? - yarons


答案:


可以在基础中注入服务,但无论如何都必须从User类传入它。您无法从Base继承服务的实际实例化,因此您必须将其从User传递给Base。这不是TypeScript的限制,而是DI一般工作方式的特征。

像这样的东西:

class User extends Base
  constructor(service: AjaxService) {
        super(service);
  }

如果Base为您实例化了该服务,则无法影响User的实例化。这将否定DI总体上的许多好处,因为您会通过将依赖关系控制委派给不同的组件而失去控制权。

我知道你可能试图通过在Base中指定这个来减少代码重复,但这违背了DI的原则。


9
2017-12-27 15:17



感谢你的回答。我正在努力减少代码重复,但这将成为一场噩梦...... - Sam Jason Braddock


Angular 2中要注入的每个类都必须注释。如果它不是组件,则必须使用它进行注释 @Injectable() 注解。如果您注入已经注入其他类的类,则必须为其创建提供程序。

import {Injectable} from 'angular2/core';
import {Base} from './base';
@Injectable()
export class User extends Base {
}

我为你创造了Plunker,我希望它能解决你的问题:

http://plnkr.co/edit/p4o6w9GjWZWGfzA6cv41?p=preview

(看看控制台输出)

PS。请使用Observable而不是Promises


2
2017-12-27 10:43



我想你只想在要注入其他组件的服务中使用@Injectable? - monty_lennie
是的,这是事实。此外,您需要在组件的提供程序数组中包含Service。 - Vlado Tesanovic