angular - Dynamic Component selection in Angular2 -


this question has answer here:

given model page section contains multiple fields , populated data such this:

{     "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"         }     ] } 

i have generic section component not know different types of fields might wrap, avoid lots of conditional logic in section template, , make new field type views/components added dropping in self-contained file rather having modify separate component.

my ideal component's selector specific enough accomplish selecting element in parent component's template based on attribute values bound model. example: (pardon syntax issues coded in window, main part pay attention selector on 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 use boolean fields @component({     selector: 'field[type=bool]' }) @view({     template: `<input type="checkbox" [id]="id" [checked]="value==1"></input>` }) class booleancomponent {     constructor() {} } 

... , on time i'd add new components provide special templates , behaviors other specific field types, or fields captions, etc.

this doesn't work because component selectors must simple element name (in alpha.26 , alpha.27 @ least). research of github conversations lead me believe restriction being relaxed, can't determine if want supported.

alternatively, have seen dynamiccomponentloader mentioned, though can't find example thought on angular.io guide. so, don't know how used dynamically load component doesn't know name or matching criteria for.

is there way accomplish aim of decoupling specialized components parent using either technique similar tried, or other technique unaware of in angular 2?

update 2015-07-06

http://plnkr.co/edit/fal9oa7ghqs1sresutgd?p=preview

i thought best show errors run more explicitly. i've included plunk sample code, though first of these 3 errors visible, each 1 blocks other can show off 1 @ time. i've hard coded around #2 , #3 moment.

  1. whether selector on booleancomponent selector: 'field[type=bool]' or selector: '[type=bool]', error stack angular

    component 'booleancomponent' can have element selector, had '[type=bool]'

  2. <field [type]="field.type"></field> not bind field.type value type attribute, gives me error (which thankfully shows in alpha 28. in alpha 26 on, failed silently). can rid of error adding type property fieldcomponent , derivative booleancomponent , wiring @component properties collection, don't need in components.

    can't bind 'type' since isn't know property of 'field' element , there no matching directives corresponding property

  3. i forced list fieldcomponent , booleancomponent in directives list of sectioncomponent view annotation, or won't found , applied. read design discussions angular team made conscious decision in favor of explicitness in order reduce occurrences of collisions directives in external libraries, breaks whole idea of drop-in components i'm trying achieve.

at point, i'm struggling see why angular2 bothers have selectors. parent component has know child components have, go, , data need. selectors totally superfluous @ moment, convention of class name matching. i'm not seeing abstraction between components i'd need decouple them.

due these limitations in ability of angular2 framework, i'm making own component registration scheme , placing them via dynamiccomponentloader, i'd still curious see responses people have found better way accomplish this.

  1. as error says, component must have unique selector. if want bind component behavior attribute selector [type='bool'] you'd have use directives. use selector='bool-field' boolcomponent.

  2. as error says, generic <field> component not have type attribute bind to. can fix adding input member variable: @input() type: string;

  3. you want delegate component template single component receive type attribute. create generic component , other components use have provide it, not children.

example: http://plnkr.co/edit/huh8fm3vmscsk3kewjf6?p=preview

@component({   selector: 'generic-field',   templateurl: 'app/generic.template.html' }) export class genericfieldcomponent {   @input()    fieldinfo: fieldinfo; } 

using template:

<div>   <span>{{fieldinfo.caption}}</span>    <span [ngswitch]="fieldinfo.type">     <input  *ngswitchwhen="'bool'" type="checkbox" [value]="fieldinfo.value === 1">       <input  *ngswitchwhen="'text'" type="text" [value]="fieldinfo.value">       <select  *ngswitchwhen="'options'" type="text" [value]="fieldinfo.value">       <option *ngfor="let option of fieldinfo.options" >         {{ option }}       </option>     </select>     </span> </div> 

Comments

Popular posts from this blog

PHP DOM loadHTML() method unusual warning -

python - How to create jsonb index using GIN on SQLAlchemy? -

c# - TransactionScope not rolling back although no complete() is called -