如何向 class 注入服务,然后用它扩展组件?

How to inject service to class and then extend component with it?

我有 class Layer:

import {AfterViewInit, ViewChild} from 'angular2/core';


export class Layer implements AfterViewInit {
  @ViewChild('element') element;

  public canvas: HTMLCanvasElement = null;
  public context: CanvasRenderingContext2D = null;

  ngAfterViewInit() {
    this.canvas = this.element.nativeElement;
    this.context = this.canvas.getContext('2d');
  }
}

我将用我的组件扩展它 Lines:

import {Component} from 'angular2/core';

import {Layer} from './layer';
import {Game} from '../../providers/Game';


@Component({
  selector: 'lines-component',
  template: require('./template.html'),
  styles: [`
    canvas {
      z-index: 2;
    }
  `]
})
export class Lines extends Layer {
  constructor(public game: Game) {
    super();
  }
}

如您所见,我必须向将从 Layer 继承的每个组件注入 Game 服务。但是,我想向 Layer class 注入服务,因此我可以使用它来创建依赖于该服务的方法,而且它不会强制我向我的组件注入服务每一次都拥有。

不用说,向 Layer 注入服务就像我对任何组件所做的那样是行不通的。

我正在使用 angular 2.0.0-beta.0

将构造函数添加到基础 class Layer 就像您在扩展 class 上所做的那样,并将依赖项作为参数发送到 super 方法中:

export class Layer implements AfterViewInit {
    constructor(public game: Game) {
        console.log(game);
    }
}

export class Lines extends Layer {
  constructor(public game: Game) {
    super(game);
  }
}

我认为 Angular 不支持它。您需要在组件级别有一个构造函数来定义您要注入的内容...

使用您的示例:

export class Layer {
  constructor(public game: Game) {
  }
}

@Component({
  (...)
})
export class Lines extends Layer {
  (...)
}

如果您查看 Lines class 的转译文件,您会发现 game 参数出现在 Lines 构造函数中,Game 服务不存在于 __metadata 函数的第二个参数(组件的提供者列表)中:

Lines = (function (_super) {
  __extends(Lines, _super);
  function Lines() { // <------------------
    _super.apply(this, arguments);
  }
  Lines = __decorate([
    core_1.Component({
      selector: 'lines-component',
      template: "\n    lines\n  ",
      styles: ["\n    canvas {\n      z-index: 2;\n    }\n  "]
    }), 
    __metadata('design:paramtypes', []) // <------------------
  ], Lines);
  return Lines;
})(app_layer_component_1.Layer);

而您在 Lines class 中定义 constructor(public game: Game) 时拥有它:

Lines = (function (_super) {
  __extends(Lines, _super);
  function Lines(game) { // <------------------
    this.game = game;
  }
  Lines = __decorate([
    core_1.Component({
      selector: 'lines-component',
      template: "\n    lines\n  ",
      styles: ["\n    canvas {\n      z-index: 2;\n    }\n  "]
    }), 
    __metadata('design:paramtypes', [app_game_service_1.Game]) // <------------------
  ], Lines);
  return Lines;
})(app_layer_component_1.Layer);

希望对你有帮助, 蒂埃里