Dato un modello per una sezione di pagina che contiene più campi e sarebbe stato popolato con dati quali come questo:componente dinamico in Angular2
{
"fields": [
{
"id": 1,
"type": "text",
"caption": "Name",
"value": "Bob"
},
{
"id": 2,
"type": "bool",
"caption": "Over 24?",
"value": 0
},
{
"id": 3,
"type": "options",
"options" : [ "M", "F"],
"caption": "Gender",
"value": "M"
}
]
}
mi piacerebbe avere una componente generica sezione, che non conosce i diversi tipi di campi che potrebbe avvolgere, per evitare molte logiche condizionali nel modello di sezione e per rendere nuove viste/componenti del tipo di campo aggiunti passando in un file autonomo anziché dover modificare un componente separato.
Il mio ideale sarebbe che il selettore di un componente sia abbastanza specifico da consentirmi di farlo selezionando un elemento nel modello del componente principale in base ai valori di attributo associati al modello. Per esempio: (scusate eventuali problemi di sintassi, come ho codificato questo nella finestra di SO, parte principale di prestare attenzione a è il selettore su BooleanComponent.ts
SectionComponent.ts
@Component({
selector: 'my-app'
})
@View({
template: `
<section>
<div *ng-for="#field of fields">
<field type="{{field.type}}"></field>
</div>
</section>
`,
directives: [NgFor]
})
class SectionComponent {
fields: Array<field>;
constructor() {
this.fields = // retrieve section fields via service
}
}
FieldComponent.ts:
// Generic field component used when more specific ones don't match
@Component({
selector: 'field'
})
@View({
template: `<div>{{caption}}: {{value}}</div>`
})
class FieldComponent {
constructor() {}
}
BooleanComponent.ts:
// specific field component to use for boolean fields
@Component({
selector: 'field[type=bool]'
})
@View({
template: `<input type="checkbox" [id]="id" [checked]="value==1"></input>`
})
class BooleanComponent {
constructor() {}
}
... e con il tempo che vorrei aggiungere nuovo co mponents per fornire modelli e comportamenti speciali per altri specifici tipi di campo, o anche campi con determinate didascalie, ecc.
Questo non funziona perché i selettori di componente devono essere un semplice nome di elemento (in alpha.26 e alpha.27 a meno). La mia ricerca sulle conversazioni github mi porta a credere che questa restrizione sia stata rilassata, ma non posso determinare se ciò che voglio fare sarà effettivamente supportato.
In alternativa, ho visto un DynamicComponentLoader menzionato, anche se ora non riesco a trovare l'esempio che ho pensato fosse sulla guida angular.io. Anche così, non so come potrebbe essere usato per caricare dinamicamente un componente per il quale non conosce il nome o i criteri di corrispondenza.
C'è un modo per raggiungere il mio obiettivo di separare i componenti specializzati dai loro genitori usando una tecnica simile a quella che ho provato, o qualche altra tecnica di cui non sono a conoscenza in Angular 2?
UPDATE 2015-07-06
http://plnkr.co/edit/fal9OA7ghQS1sRESutGd?p=preview
ho pensato che la cosa migliore per mostrare gli errori mi imbatto in modo più esplicito. Ho incluso un plunk con qualche codice di esempio, anche se solo il primo di questi 3 errori sarà visibile, poiché ognuno blocca l'altro in modo che tu possa mostrarlo solo uno alla volta. Ho programmato con difficoltà per aggirare il n. 2 e il n. 3 per il momento.
- Sia il mio selettore BooleanComponent è
selector: 'field[type=bool]'
oselector: '[type=bool]'
, ottengo uno stack di errore da Angular comeComponent 'BooleanComponent' può avere solo un selettore di elemento, ma ha dovuto '[type = bool]'
<field [type]="field.type"></field>
non associa il mio valore field.type all'attributo type, ma mi dà questo errore (che per fortuna si presenta ora in alpha 28.In alpha 26 ero in precedenza, ha fallito silenziosamente). Posso eliminare questo errore aggiungendo una proprietà type al mio componente FieldComponent e derivato BooleanComponent e collegandolo con la raccolta di proprietà @Component, ma non ne ho bisogno per nulla nei componenti.Impossibile associare al 'tipo' in quanto non è una proprietà sapere dell'elemento 'campo' e non ci sono direttive di corrispondenza con una corrispondente proprietà
- sono costretto a elencare FieldComponent e BooleanComponent nell'elenco delle direttive della mia annotazione SectionComponent View, o non verranno trovati e applicati. Ho letto le discussioni sul design del team di Angular in cui hanno preso questa decisione cosciente a favore di esplicitezza al fine di ridurre le occorrenze di collisioni con le direttive in librerie esterne, ma rompe l'intera idea di componenti drop-in che sto cercando di ottenere.
A questo punto, sto faticando a capire perché Angular2 abbia persino fastidio avere selettori. Il componente principale deve già sapere quali componenti figlio avrà, dove andranno e quali dati hanno bisogno. I selettori sono del tutto superflui al momento, potrebbe anche essere una convenzione di abbinamento del nome di classe. Non vedo l'astrazione tra i componenti che avrei bisogno di disaccoppiarli.
A causa di queste limitazioni nella capacità del framework Angular2, sto creando il mio schema di registrazione dei componenti e li posiziono tramite DynamicComponentLoader, ma sarei comunque molto curioso di vedere le risposte per le persone che hanno trovato un migliore modo per realizzare questo.
grande domanda. Sto incontrando lo stesso problema. Ho trovato che in alpha-34 avremo una soluzione parziale. Qualsiasi selettore sarà consentito per i componenti. Puoi controllare qui https://github.com/angular/angular/pull/3336. Ma ancora, il problema della selezione dinamica rimane attuale. Mi piacerebbe vedere la tua soluzione con DynamicComponentLoader, se possibile. –
Buona domanda, stiamo cercando di evitare di avere un blocco swtich o ngIf nella pagina. – nycynik