2015-12-27 3 views
11

Ich verwende angular2 mit Typescript. Ich versuche, eine base class zu erstellen, die von anderen Klassen vererbt werden kann, und innerhalb der Basisklasse wird ein Dienst injiziert. Bisher kann ich die ajaxServiceinjected nicht richtig in die base class, die inherited in die user class ist. Insbesondere wenn ein Benutzer instanziiert wird und dann die save()-Methode von der user Instanz aufgerufen wird, funktioniert die folgende Zeile in base class: return _this._ajaxService.send(options); nicht, da _ajaxService nicht definiert ist. HierAngular2-Abhängigkeitsinjektion, Service wird während Klassenvererbung nicht injiziert

ist ein user class, das die base class erweitert:

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); 
    } 
} 

Hier ist die 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); 
    }); 
    } 
} 

Dies funktioniert gut, außer dass AjaxService nicht injiziert wird in der Basisklasse. Ich denke, das macht Sinn, da der Benutzer nicht als Basis instanziiert wird.

Also wie kann ich AjaxService in der Base module verwenden, wenn "Base-Modul in einer anderen Klasse erweitert wird?

Ich denke, wenn ich Benutzer instanziiere, wird der Konstruktor in der Benutzerklasse aufgerufen, aber der Konstruktor in der Basisklasse, die den Dienst einspeist, wird nicht aufgerufen.

Hier ist die 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); 
     }); 
    }); 

    } 

} 
+0

Soweit ich weiß injectables (AjaxService) müssen mit '@Injectable() 'in TS kommentiert werden. –

+0

Wo verwenden Sie die 'User' Klasse? Ist es eine Komponente? Hat es eine Vorlage? – yarons

Antwort

2

Jede Klasse in Angular 2, die Sie Sie mit Anmerkungen versehen müssen injizieren wollen. Wenn es keine Komponente ist, müssen Sie es mit @Injectable() Annotation kommentieren. Wenn Sie eine Klasse injizieren, die bereits eine andere Klasse injiziert, müssen Sie einen Provider dafür erstellen.

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

I Plunker für Sie erstellt haben, hoffe ich, dass es Ihr Problem lösen:

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

(bei Konsolenausgabe anschauen)

PS. Verwenden Sie Observable anstelle von Promises

+0

Ich denke, Sie brauchen nur @Injectable in den Diensten, die Sie in andere Komponenten injizieren möchten? –

+0

Ja, das stimmt. Außerdem müssen Sie den Service in ein Array von Anbietern für die Komponente aufnehmen. –

9

Es ist in Ordnung, Dienste in der Basis zu injizieren, aber Sie müssen es unabhängig von der Benutzerklasse übergeben. Sie können die tatsächliche Instanziierung des Dienstes nicht von der Basis erben, daher müssen Sie sie vom Benutzer an die Basis übergeben. Dies ist keine Einschränkung von TypeScript, sondern eher eine Funktion von DI im Allgemeinen.

Etwas wie folgt aus:

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

Wenn die Basis den Service für Sie instanziiert, würden Sie nicht in der Lage sein, die Instanziierung von Benutzer zu beeinflussen. Dies würde viele Vorteile von DI insgesamt zunichte machen, da Sie die Kontrolle verlieren würden, indem Sie die Abhängigkeitskontrolle an eine andere Komponente delegieren.

Ich verstehe, dass Sie versuchen könnten, Code-Duplizierung zu reduzieren, indem Sie dies in der Basis angeben, aber dies widerspricht dem Prinzip von DI.

+0

Danke für die Antwort. Ich versuche, Code-Duplizierung zu reduzieren, aber das wird ein Albtraum sein ... –