2016-04-14 12 views
5

Ich schreibe einige Angular2 Vorlagen, die sich wiederholende Teile mit verschiedenen Containern haben. In diesem Fall kann sich die Ansicht ändern, wenn Dinge gruppiert sind und der Multi-Section-Modus aktiviert ist. Bitte entschuldigen Sie die lange Beispiel, aber so etwas wie dies:Angular2 lokale Komponenten/Vorlage wiederverwenden

<template [ngIf]="isCategoryGrouped"> 
    <div *ngFor="#categories of categories"> 
     <div>{{ categories.category.name }}</div> 
     <div *ngFor="#thing of categories.things"> 
      <label *ngIf="isMultiSelectMode"> 
       <input type="checkbox" (change)="updateThingSelection(thing, $event)" /> 
       <img [src]="thing.image" /> {{ thing.name }} 
      </label> 
      <a href="javascript: void(0)" (click)="selectThing(thing)" *ngIf="! isMultiSelectMode"> 
       <img [src]="thing.image" /> {{ thing.name }} 
      </a> 
     </div> 
    </div> 
</template> 
<template [ngIf]="! isCategoryGrouped"> 
    <div *ngFor="#thing of things"> 
     <label *ngIf="isMultiSelectMode"> 
      <input type="checkbox" (change)="updateThingSelection(thing, $event)" /> 
      <img [src]="thing.image" /> {{ thing.name }} 
     </label> 
     <a href="javascript: void(0)" (click)="selectThing(thing)" *ngIf="! isMultiSelectMode"> 
      <img [src]="thing.image" /> {{ thing.name }} 
     </a> 
    </div> 
</template> 

ich wirklich möchte Teile dieser wieder zu verwenden, ohne eine völlig separate Komponente zu schreiben und Draht alles zusammen, was eine Typoskript Datei benötigen würde und ein Vorlage. Ein Verfahren würde mit lokalen Komponenten sein, etwa wie folgt:

<sub-component selector="thing-list" things="input"> 
    <div *ngFor="#thing of things"> 
     <label *ngIf="isMultiSelectMode"> 
      <input type="checkbox" (change)="updateThingSelection(thing, $event)"/> 
      <img [src]="thing.image" /> {{ thing.name }} 
     </label> 
     <a href="javascript: void(0)" (click)="selectThing(thing)" *ngIf="! isMultiSelectMode"> 
      <img [src]="thing.image" /> {{ thing.name }} 
     </a> 
    </div> 
</sub-component> 

<template [ngIf]="isCategoryGrouped"> 
    <div *ngFor="#categories of categories"> 
     <div>{{ categories.category.name }}</div> 
     <thing-list things="categories.things" /> 
    </div> 
</template> 
<thing-list [ngIf]="! isCategoryGrouped" things="things" /> 

Ich weiß, die über eine grobe Skizze ist und wahrscheinlich würde nicht so ist die Arbeit, aber die offensichtliche Unfähigkeit, Teile der Ansicht wieder zu verwenden, wie dies bedauerlich ist, . So etwas ist in React ganz einfach, wenn ich das richtig verstehe.

Ich bin neugierig auf elegante Möglichkeiten, andere haben die Wiederverwendung von Portionen der Ansicht gelöst, ohne so weit zu gehen, eine neue Komponente zu schreiben (was unsere Designer dann wissen müssten und Stil, etc .. .). Vielen Dank.

+0

Es ist mir nicht klar, welche Teile der Ansicht auf welche Weise wiederverwendet werden sollen. –

Antwort

4

Wenn Ihre Abschnitte in der Struktur identisch sind, nur anders in Daten, könnten Sie mit einem allgemeineren Modell kommen. Anstatt direkt auf category und thing zu verweisen, ordnen Sie sie einem generischen Objekt zu, das Sie in einem Service auffüllen, bevor es in die Ansicht gelangt.

<div *ngFor="#item of items"> 
     --- 
</div> 

Hier würden Elemente entweder von Dingen oder Kategorien ausgefüllt werden.

Sie können es dann wie

so nennen
<component [items]="fromThings"></component> 
<component [items]="fromCategories"></component> 

Sie sind der Ansicht, grundsätzlich Normalisierung von nicht direkt auf den eigentlichen Objekten abhängig.

+2

Das Problem ist, wenn die Kinder mit verschiedenen Eltern dupliziert werden müssen, so dass ich keine Schleife verwenden kann. Der zweite Teil dieser Antwort ist genau das, was ich vermeiden möchte - eine neue Komponente machen. Der Grund, warum ich keine neue Komponente erstellen möchte, ist, dass die duplizierten Teile des Baumes für diese Ansicht sehr spezifisch sind. Ich möchte grundsätzlich etwas Analoges zu inneren oder Methodenklassen im Java/Scala-Universum haben. –

+0

Also mit diesem Vorschlag behalten Sie es als eine Komponente, aber übergeben Sie es ein Objekt aus den zwei verschiedenen Variationen. Sie normalisieren es im Grunde auf ein drittes Modellobjekt. – TGH

+2

Richtig ... aber Sie haben immer noch eine separate Komponente aus dem Kontext, in dem sie verwendet wird, was genau das ist, was ich vermeiden möchte. Siehe die Antwort von Günter, die auf eine Pull-Anfrage für das Feature hinweist, nach dem ich frage. –

3

Sie können auch *ngFor mit [ngForTemplate] oder dem kommenden NgInsert (Name wird geändert) verwenden, um Teile Ihrer Vorlage wiederverwendbar zu machen.

+0

'ngInsert' scheint neuer Begriff für mich, was die Verwendung derselben, gut, wenn Sie Ihre Antwort mit etwas mehr Erklärung aktualisieren. –

+1

Siehe den Link. Es wird anders benannt. Sie können nur referenzierte Vorlagen stempeln. Ich hoffe, zuerst mehr Informationen über die Anforderungen zu bekommen und dann werde ich meine Antwort verfeinern. –

+0

Das sieht fantastisch aus, und ist fast genau das, was ich will. Ich kann nicht darauf warten, dass es in eine Betaversion fällt. Irgendeine grobe Schätzung, wann das passieren wird? –

0

Komponente rekursiv in Vorlage aufrufen.

isList steuern, welcher Teil verwendet werden soll, Standard false.

thing.html

<template [ngIf]="isLlist"> 
    <div *ngFor="#thing of things"> 
     <label *ngIf="isMultiSelectMode"> 
      <input type="checkbox" (change)="updateThingSelection(thing, $event)"/> 
      <img [src]="thing.image" /> {{ thing.name }} 
     </label> 
     <a href="javascript: void(0)" (click)="selectThing(thing)" *ngIf="! isMultiSelectMode"> 
      <img [src]="thing.image" /> {{ thing.name }} 
     </a> 
    </div> 
</template> 

<template [ngIf]="!isList"> 

    <template [ngIf]="isCategoryGrouped"> 
     <div *ngFor="#categories of categories"> 
      <div>{{ categories.category.name }}</div> 
      <my-thing-component [isList]="true" [things]="categories.things"></my-thing-component> 
     </div> 
    </template> 

    <templete [ngIf]="! isCategoryGrouped"> 
     <my-thing-component [isList]="true" [things]="things"></my-thing-component> 
    </templete> 

</template> 

thing.component.

<ng-container *ngTemplateOutlet="headerPanel"></ng-container> 

Official docs

Hinweis: ts

import {Component,Input} from '@angular/core'; 

@Component({ 
    selector: 'my-thing-component', 
    templateUrl: 'thing.html' 
}) 
export class ThingComponent { 
    @Input() isList = false; 
    @Input() things; 

    //Fill in the rest 
} 
0

können Sie jetzt <ng-template>

<ng-template #headerPanel> 
    <header> 
     This is my reusable header. 
    </header> 
</ng-template> 

Dann wie folgt verwenden verwende ich bin nicht so gut informiert zu erklären anders nce zwischen [ngTemplateOutlet] und *ngTemplateOutlet aber wenn jemand anderes diese Antwort bearbeiten möchte oder ein weiteres Feel free hinzufügen.