2015-10-06 17 views
7

Ich brauche eindeutige Anker Namen/Komponenten in einer ngFor-Schleife, um es mit ComponentResolver.resolveComponent zu verwenden.create dynamic anchorName/Komponenten mit ComponentResolver und ngFor in Angular2

<div> 
    <table> 
    <tr *ng-for="#vIndex of vArr"> 
     <td *ng-for="#hIndex of hArr"> 
     <div #uniqueanchorname{{vIndex}}_{{hIndex}}></div> 
     </td> 
    </tr> 
    </table> 
</div> 

sollte die resultierende html so ähnlich aussehen:

<div> 
    <table> 
    <tr> 
     <td> 
     <div #uniqueanchorname0_0></div> 
     </td> 
     <td> 
     <div #uniqueanchorname0_1></div> 
     </td> 
    </tr> 
    <tr> 
     <td> 
     <div #uniqueanchorname1_0></div> 
     </td> 
     <td> 
     <div #uniqueanchorname1_1></div> 
     </td> 
     <td> 
     <div #uniqueanchorname1_2></div> 
     </td> 
    </tr> 
    </table> 
</div> 

, die mit i die DynamicComponentLoader wie verwenden:

loader.loadIntoLocation(responseDependentComponent, elementRef, 'uniqueAnchorName1_2'); 

die resultierende HTML ersetzt bekommen nicht und etwas aussehen wird wie:

<div> 
    <table> 
    <tr> 
     <td> 
     <div #uniqueanchorname{{vIndex}}_{{hIndex}}></div> 
     </td> 
     <td> 
     <div #uniqueanchorname{{vIndex}}_{{hIndex}}></div> 
     </td> 
    </tr> 
    <tr> 
     <td> 
     <div #uniqueanchorname{{vIndex}}_{{hIndex}}></div> 
     </td> 
     <td> 
     <div #uniqueanchorname{{vIndex}}_{{hIndex}}></div> 
     </td> 
     <td> 
     <div #uniqueanchorname{{vIndex}}_{{hIndex}}></div> 
     </td> 
    </tr> 
    </table> 
</div> 

Wenn die Erstellung von eindeutigen Ankernamen nicht möglich ist. Gibt es eine andere Möglichkeit, Komponenten an einem bestimmten Ort zu laden?

+0

Sie so etwas wie '# versuchen könnte {{‘ uniqueAnchorName '+ vIndex +' _ '+ hIndex}} ' –

+0

Ich habe dein Problem nicht wirklich verstanden. Hat es funktioniert? Es nicht? Ich habe es nicht ausprobiert, aber das einzige, was ich sehen kann, ist die Tatsache, Großbuchstaben in Ihren Variablennamen zu verwenden. Wenn Sie 'uniqueAnchorName' schreiben, wird der Browser sie vor der Kompilierung von ng2 in' uniqueanchorname' unterteilen. –

+0

@PankajParkar-Schnurrbart ({{xxx}}) wird nicht in Attributen ersetzt, das resultierende HTML sieht immer noch wie #uniqueAnchorName {{vIndex}} _ {{hIndex}} –

Antwort

4

Entschuldigung, es gab ein Missverständnis.

import { 
    Directive, 
    Component, 
    View, 
    CORE_DIRECTIVES, 
    ElementRef, 
    DynamicComponentLoader, 
    Input, 
    QueryList, 
    ViewChildren 
} from 'angular2/angular2' 

@Component({ 
    selector: 'my-cmp' 
}) 
@View({ 
    template: 'my component' 
}) 
class MyCmp {} 

@Directive({ 
    selector: '[location]' 
}) 
class Location { 
    @Input() h: number; 
    @Input() v: number; 
    constructor(public elementRef: ElementRef) { 
    } 
} 

@Component({ 
    selector: 'my-table' 
}) 
@View({ 
    template: ` 
    <table border> 
    <tr *ng-for="#v of vArr"> 
     <td *ng-for="#h of hArr"> 
     <div location v="{{v}}" h="{{h}}">{{v}}-{{h}}</div> 
     </td> 
    </tr> 
    </table> 
    h:<input #hi value="1"><br> 
    v:<input #vi value="2"><br> 
    <button (click)="load(hi.value, vi.value)">load</button> 
    `, 
    directives: [CORE_DIRECTIVES, Location] 
}) 
class MyTable { 
    vArr = [1, 2, 3]; 
    hArr = [1, 2, 3]; 
    @ViewChildren(Location) locations: QueryList; 
    constructor(
    private loader: DynamicComponentLoader, 
    ) { 
    } 

    load(h, v) { 
    let elementRef = null; 
    for(let i = 0; i < this.locations._results.length; i++) { 
     if(this.locations._results[i].h == h && this.locations._results[i].v ==v) { 
     elementRef = this.locations._results[i].elementRef; 
     } 
    } 

    if(elementRef) { 
     this.loader.loadNextToLocation(MyCmp, elementRef); 
    } 
    } 
} 

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

http://plnkr.co/edit/dqfPCW3MBa9hM23EW3cS?p=preview Ist das, was Sie brauchen?

+0

Ihre Lösung macht, was ich brauche. Es ist ein wenig unangenehm, viele Richtlinien zu erstellen, nur um eine Referenz zu haben. Meines Erachtens wäre es besser, wenn wir String-Anker als Referenzen erstellen könnten. Aber Ihre Lösung funktioniert, thx. –

+0

Ich denke #xxx als lokale Variable Name ist nicht bindbar. Der einzige Weg, dies zu tun, ist von ElementRef, deshalb verwenden Sie die Direktive. –

0

Lösung für Angular2 rc.0

HTML:

<div style="display: block"> 
    <table> 
    <tr *ngFor="let v of arr; let i = index"> 
     <td *ngFor="let h of arr[i]; let j = index"> 
     <div location v="i" h="j"></div> 
     </td> 
    </tr> 
    </table> 
</div> 

Ort Richtlinie:

@Directive({ 
    selector: '[location]' 
}) 
class Location { 
    @Input() h: number; 
    @Input() v: number; 

    constructor(public viewContainerRef: ViewContainerRef) { 
    } 
} 

Komponente

@Component({ 
    selector: 'example-cmp', 
    directives: [CORE_DIRECTIVES, Location] 
}) 
export class ExampleComponent implements AfterViewInit { 
    public arr: Array<Array<number>> = []; 
    public componentRef: ComponentRef<any>; 

    @ViewChildren(Location) private locations: QueryList<Location>; 

    constructor(private resolver: ComponentResolver) { 
    } 

    ngAfterViewInit() { 
    this.loadTag(0,0,SomeViewComponent); 
    } 

    loadTag(x:number, y:number, component) { 
    let viewContainerRef: ViewContainerRef = null; 
    let locs = this.locations.toArray(); 
    for (let i = 0; i < locs.length; i++) { 
     if (+locs[i].h === x && +locs[i].v === y) { 
     viewContainerRef = locs[i].viewContainerRef; 
     } 
    } 
    if (viewContainerRef != null) { 
     var injector = ReflectiveInjector.fromResolvedProviders(ReflectiveInjector.resolve([ 
     provide(NeededAttribute, { useValue: 42 })]), 
     this.componentRef.injector); 

     this.resolver.resolveComponent(component).then((factory: ComponentFactory<any>) => { 
     var compRef: ComponentRef<any> = viewContainerRef.createComponent(factory, -1, injector); 
     }); 
    } 
    } 
}