2016-01-26 10 views
8

Attualmente sto importando un componente di terze parti. Per il mio caso d'uso ho bisogno di sovrascrivere quel modello di componente specifico.Ignora/estendi il modello di componenti di terze parti

Poiché si tratta di un componente di terze parti e importato tramite il pacchetto npm, non desidero modificare il componente in modo da non doverlo aggiornare ogni volta che il pacchetto viene aggiornato.

C'è un modo per sovrascrivere il modello di un altro componente?

So che è possibile utilizzare <ng-content> se si desidera iniettare qualche elemento. Ma qui non è fattibile.

il codice HTML è qualcosa di simile:

<third-party-component [items]="items" [example]="example"> 

Il controller è qualcosa di simile:

import {THIRD_PARTY_DIRECTIVES} from 'ng2-select/ng2-select'; 

@Component({ 
    selector: 'example-component', 
    directives: [THIRD_PARTY_DIRECTIVES] 
}) 
export class Example { 

    private items: Array<string> = [ 
    'whatever', 'whatever2', 'whatever3' 
    ]; 
} 

C'è un modo posso specificare il modello che voglio per <third-party-component> senza modificare tale componente specifico dichiarazione? O anche solo estenderlo?

risposta

1

È possibile utilizzare Reflect per modificare i metadati del componente. Ecco il super simple example:

import {Component} from 'angular2/core' 

@Component({ 
    selector: 'thing', 
    template: `Hi!`, 
}) 
export class Thing {} 

annotations = Reflect.getMetadata('annotations', Thing); 
for (let i = 0; i < annotations.length; i += 1) { 
    if (annotations[i].constructor.name === 'ComponentMetadata') { 
    annotations[i].template = 'Ho!'; 
    break; 
    } 
} 

@Component({ 
    selector: 'my-app', 
    directives: [Thing], 
    template: `<thing></thing>`, 
}) 
export class App {} 

solo assicurarsi di aggiornare template prima iniettarlo nel componente genitore. Controlla anche which metadata a cui devi accedere, potrebbe essere DirectiveMetadata nel tuo caso.

+0

Grazie per lo sforzo. Ho trovato una soluzione semplice estendendo solo la classe. Controlla la mia risposta. –

+0

@JoelAlmeida Funziona bene, lo terrò a mente (; È una soluzione migliore di quella che ho offerto, ma suppongo che Reflect Metadata possa essere usato se non si ha accesso ai file TS ... – Sasxa

+0

Sono d'accordo. guess Reflect è l'unica soluzione se non si ha accesso alla classe –

10

Dopo aver giocato con esso. Una semplice estensione funzionerà per il mio caso d'uso.

Fondamentalmente ho creato una classe che estende lo thirdPartyClass.

Quello che succede qui è che sto sovrascrivendo il modello per lo thirdPartyClass creando il mio selettore e importando solo la classe.

Qualcosa di simile a questo:

import {component} from 'angular2/core'; 
import {thirdPartyClass} from 'example/example'; 

@Component({ 
    selector: 'my-selector', 
    template: '<div>my template</div>' 
}) 

export class MyOwnComponent extends thirdPartyClass { 
    constructor() { 
    super() 
    } 
} 

Note:

  • Se si utilizza questo metodo, non dimenticate di importare qualsiasi tubi che vengono utilizzati nel modello thirdPartyClass.
  • Se la funzionalità viene aggiornata nel thirdPartyClass che dipende dal modello, è necessario aggiornarlo manualmente.
  • Ho preferito questa soluzione per fare riferimento a ReflectMetaData perché è una semplice estensione invece di accedere alle annotazioni e forzarne il cambiamento.
Problemi correlati