2016-02-24 12 views
8

Ho classi diverse (modelli) che sono figli di un genitore. Ogni bambino ha una propria forma, ma vorrei che la Componente che ha i riferimenti principali restituisca la forma specifica a seconda del bambino. Un esempio:Polimorfismo tra componenti angolari2

modelle

export interface Item { 
    title: string; 
} 

export class Exercise implements Item { 
    constructor(public title:string, public description:string); 
} 

export class Break implements Item { 
    constructor(public title:string, public time:number); 
} 

Forme

@Component({ 
    selector: 'item-form', 
    template: `<item></item> 
    `, 
    inputs: ['model:item'] 
}) 
export abstract class ItemFormComponent { 
    model: Item; 
} 

@Component({ 
    selector: 'item-form', 
    template: ` 
     <form #exerciseForm="ngForm"> 
      <input type="text" class="form-control" required 
      [(ngModel)]="model.title" 
      ngControl="title" #name="ngForm" > 
      <input type="text" class="form-control" required 
      [(ngModel)]="model.description" 
      ngControl="desription" #name="ngForm" > 
     </form> 
    `, 
    providers: [ExerciseService], 
    inputs: ['model:exercise'] 
}) 
export class ExerciseFormComponent extends ItemFormComponent { 
    model = new Exercise("Title", "Description"); 

    constructor(private _exerciseService: ExerciseService) { 
     super(); 
    } 
} 

@Component({                       
    selector: 'item-form',                    
    template: ` 
     <form #exerciseForm="ngForm"> 
      <input type="text" class="form-control" required 
      [(ngModel)]="model.title" 
      ngControl="title" #name="ngForm" > 
      <input type="text" class="form-control" required 
      [(ngModel)]="model.time" 
      ngControl="number" #name="ngForm" > 
     </form> 
    `,              
    inputs: ['model:break']                   
})                                                   
export class BreakFormComponent extends ItemFormComponent {           
    model = new Break("Title", 10);                    

} 

App

@Component({ 
     selector: 'app', 
     template: ` 
      <h1>App</h1> 
      <div *ngFor="#item of items"> 
       <item-form [model]="item"></item-form> <!-- HERE IS WHERE FORM SHOULD BE INSERTED! --> 
      </div> 
     `, 
     directives: [ItemFormComponent] 
}) 
export class App { 
    items: Item[] = [new Exercise("Exercise", "Description"), new Break("Break", 10)]; 
} 
+1

TypeScript supporta il polimorfismo, ma l'annotazione angolare no. Penso che sia necessario specificare il nome preciso della classe nel campo delle direttive, non la superclasse astratta. – MatthewScarpino

+0

È questo "chi sono figli di un genitore". davvero sulla relazione genitore-figlio o significa relazione superclasse-sottoclasse? –

+0

La ricetta della forma dinamica del ricettario Angular ha una classe Questions di base con una proprietà 'controlType' che ha derivato l'uso della classe per indicare il controllo che dovrebbe essere usato, e un singolo componente di domanda con un'istruzione switch che usa' controlType' come variabile switch e un caso per ogni controllo differenza che la domanda potrebbe utilizzare: https://angular.io/docs/ts/latest/cookbook/dynamic-form.html Questo potrebbe essere il meglio che puoi fare. – Ergwun

risposta

1

Penso che avete bisogno di qualcosa di simile:

 <div *ngFor="#item of items"> 
      <item-form-a *ngIf="item instanceOf A" [model]="item"></item-form-a> 
      <item-form-b *ngIf="item instanceOf B" [model]="item"></item-form-a> 
     </div> 

Non faccio uso dattiloscritto e non so se instanceOf è supportato nelle espressioni angolari. In caso contrario, è necessario spostare il controllo su una funzione di App e chiamarlo come *ngIf="isInstanceOf(item, A).

+2

Ho provato con '* ngIf =" instance instanceof A "' ma non è supportato. Inoltre ho provato con '* ngIf =" isInstanceOf (item, A) 'ma A è sempre indefinito, non so perché, quindi ho creato:' * ngIf = "isA (item)' ma item è intanceof object! ? –

+0

Questo era in qualche modo previsto. I tipi non sono membri della classe del componente e le associazioni non consentono di riferire cose al di fuori del componente. Pertanto, 'A' non può essere usato in nessuna espressione vincolante. Non so perché 'isA (item) {return item instanceOf A; } 'non funziona. Non uso TS Ho appena controllato il tipo di controllo. Forse hai bisogno di una soluzione alternativa in modo che gli elementi forniscano una proprietà che permetta di controllare il loro tipo (come un campo stringa contenente il nome della classe). –

+0

@Franb: questo in realtà non risponde alla tua domanda e pertanto non dovrebbe essere contrassegnato come tale. –