2017-05-18 7 views
0

Ich versuche, eine Komponente basierte Anwendung zu bauen, die die meisten der Code sollte mit einigen anderen Stylesheets usw.Angular2 Komponenten Fabrik für erweiterte Komponenten

Das Ziel ist wiederverwendbar, auch sein, dass wir einige Kernkomponenten haben , die wir auch für andere Projekte verwenden können. Sie sollten erweiterbar sein, so können Sie den Stil, Funktionalität anpassen, usw.

Nun Ich versuche, eine Lösung für mein Problem zu finden: Ich mag würde, einen Mechanismus haben, dass, wenn ich eine Komponente erweitern, Die Anwendung lädt bereits die erweiterte Komponente und nicht die Super-Komponente. Ich weiß, dass ich eine neue Komponente für die erweiterte Komponente erstellen könnte, aber ich muss den Code in der gesamten Anwendung anpassen.

Ein kleines Beispiel: Ich habe eine Komponente EditableList, mit einem grundlegenden Styling und Logik und einer runden Schaltfläche Komponente (ListButton). Die EditableList-Komponente wird wie in App1 verwendet.

Jetzt in der App2, möchte ich erweitern/überschreiben die ListButton-Komponente, die es nicht mehr rund ist, sondern eine rechteckige (RectListButton). Wenn ich jedoch die Komponente erweitere, muss ich eine neue Komponente erstellen (zum Beispiel RectListButton), den Code von EditableList in eine neue Komponente kopieren, den ListButton in RectListButton (in der EditableList-Komponente) ändern und diese neue EditableList2-Komponente in meinem App2 verwenden .

Gibt es eine Möglichkeit, eine Fabrik zu haben, die erkennt, dass ich diese Komponente erweitert habe und die erweiterte Komponente stattdessen die Basiskomponente lädt? Das bedeutet für mein Beispiel, ich muss nur den ListButton erweitern und die EditableList Komponente erkennt automatisch, dass der ListButton überschrieben wurde und lädt meine erweiterte RectListButton in (oder vielleicht ListButtonExtended für eine bessere Benennung). Daher kann ich die EditableList-Komponente wiederverwenden, ohne sie zu kopieren und zu ändern.

Vielen Dank!

Grüße Fabian

Antwort

0

Hier ist eine Lösung, die

für mich gearbeitet

Schritt 1

Platzieren Sie Ihre Kernkomponenten in einem Kernmodul (Coremodule in ca. 1, enthaltend EditableList und ListButton Komponenten).

Schritt 2

Irgendwo erklären die folgende CustoModule fonction

declare var Reflect : any; 

export function CustomModule(annotations: any) 
{ 
    return function (target: Function) 
    { 
    let parentTarget = Object.getPrototypeOf(target.prototype).constructor; 
    let parentAnnotations = Reflect.getMetadata("annotations", parentTarget); 

    let parentAnnotation = parentAnnotations[0]; 
    Object.keys(parentAnnotation).forEach(key => 
    { 
     if (parentAnnotation[key] != null) 
     { 
     if (typeof annotations[key] === "function") 
     { 
      annotations[key] = annotations[key].call(this, parentAnnotation[key]); 
     } 
     else if (typeof Array.isArray(annotations[key])) 
     { 
      let mergedArrayItems = []; 
      for (let item of parentAnnotation[key]) 
      { 
      let childItem = annotations[key].find(i => i.name == item.name); 
      mergedArrayItems.push(childItem ? childItem : item); 
      } 

      annotations[key] = mergedArrayItems; 
     } 
     else if (annotations[key] == null) 
     { // force override in annotation base 
      annotations[key] = parentAnnotation[key]; 
     } 
     } 
    }); 

    let metadata = new NgModule(annotations); 

    Reflect.defineMetadata("annotations", [metadata], target); 
    }; 
} 

Schritt 3

In App 2, eine neue ListButton Komponente (die rechteckigen im Fall erstellen) aber nenne es ListButton (wichtig für die nächsten Schritte). Es hat die gleiche Selektor als Kernmoduls ListButton

Schritt 4

dann einige App2ComponentModule Modul App2, die Coremodule haben, erstreckt.Erklären Sie das Modul mit dem CustomModule Anmerkung oben (nicht NgModule verwenden)

Das neue Modul erklären sollte und Export ListButton

@CustomModule({ 
    declarations: [ ListButton ], //ListButton from app2 
    exports: [ ListButton],//ListButton from app2 
    bootstrap: [AppComponent] 
}) 
export class App2ComponentModule extends CoreModule 
{ 
} 

Schritt 5

In ca. 2, Import App2ComponentModule vom app2 Hauptmodul.

Was die Modulfunktion fusionieren tun Anmerkungen der 2 Module ist, und Coremodule der Komponenten von Komponenten App2ComponentModule die ausgetauscht werden, wenn sie den gleichen Namen haben

Verwandte Themen