webentwicklung-frage-antwort-db.com.de

Angular2: Ersetzen Sie das Host-Element durch die Vorlage der Komponente

Ich bin neu in angular im Allgemeinen und speziell in angular2. Ich versuche, eine Containerkomponente zu schreiben, die untergeordnete Komponenten enthalten sollte. 

Zum Beispiel Container-Komponente:

@Component({
  selector: 'my-list',
  template: `
    <ul>
      <ng-content></ng-content>
    </ul>
  `
})
export class MyList {
}

Kindkomponente:

import { Component } from 'angular2/core'

@Component({
  selector: 'my-item',
  template: `
    <li>
      <ng-content></ng-content>
    </li>
  `
})
export class MyItem {
}

Ich möchte diese Struktur machen:

<my-list>
    <my-item>One</my-item>
    <my-item>Two</my-item>
</my-list>

Um auf das folgende gerendert zu werden:

<my-list>
    <ul>
        <li>One</li>
        <li>Two</li>
    </ul>
</my-list>

Stattdessen habe ich auch das Host-Element des Containers und die Elemente erhalten:

<my-list>
    <ul>
        <my-item>
            <li>One</li>
        </my-item>
        <my-item>
            <li>Two</li>
        </my-item>
    </ul>
 </my-list>

Plunk ist hier erhältlich

Question: gibt es eine Möglichkeit, die Host-Elemente zu entfernen und nur die gerenderte Vorlage zu verlassen?

27
Denis Itskovich

Schließlich fand ich die Lösung: ElementRef in MyItem injizieren und deren nativeElement.innerHTML verwenden

Meine Liste:

import { Component, ContentChildren, QueryList } from 'angular2/core'
import { MyItem } from './myitem'

@Component({
  selector: 'my-list',
  template: `
    <ul>
      <li *ngFor="#item of items" [innerHTML]="item.innerHTML"></li>
    </ul>
  `
})
export class MyList {
  @ContentChildren(MyItem) items: QueryList<MyItem>
}

MyItem:

import { Directive, Inject, ElementRef } from 'angular2/core'

@Directive({selector: 'my-item'})
export class MyItem {
  constructor(@Inject(ElementRef) element: ElementRef) {
    this.innerHTML = element.nativeElement.innerHTML
  }
}

Working Plunk ist da

12
Denis Itskovich

Das solltest du bekommen, was du willst:

@Component({
  selector: 'ul[my-list]',
  template: `
    <ng-content></ng-content>
  `
})
export class MyList {
}
@Component({
  selector: 'li[my-item]',
  template: `
    <ng-content></ng-content>
  `
})
export class MyItem {
}
<ul my-list>
    <li my-item>One</li my-item>
    <li my-item>Two</li my-item>
</li my-list>
13

Neue Winkelversionen verfügen über eine wirklich coole Direktive, die auch für Ihren Anwendungsfall verwendet werden kann. Tadaa: NgComponentOutlet . Viel Spaß beim Codieren;)

Beispiel:

@Component({selector: 'hello-world', template: 'Hello World!'})
class HelloWorld {
}

@Component({
  selector: 'ng-component-outlet-simple-example',
  template: `<ng-container *ngComponentOutlet="HelloWorld"></ng-container>`
})
class NgTemplateOutletSimpleExample {
  // This field is necessary to expose HelloWorld to the template.
  HelloWorld = HelloWorld;
}
3
Luckylooke

Es gibt eine harte Problemumgehungslösung, die in älteren Browserversionen möglicherweise nicht unterstützt wird, Aber es funktionierte für mein Projekt und ich denke, es ist ziemlich einfach zu integrieren, ohne __.

Zuerst müssen Sie den Selektor für MyItem -Klasse Komponente von Element-Selektor ändern.

selector: 'custom-element-name'

zu Attribut-Auswahl

selector: '[customAttributeName]'

und schließlich html/- slot element verwenden, um MyItem in MyList html-Vorlage einzuhüllen 

<slot customAttributeName></slot>

Vollständiger Code:

import { Component } from 'angular2/core'

@Component({
  selector: 'my-list',
  template: `
    <ul>
      <slot myItemAsAtribute></slot>
    </ul>
  `
})
export class MyList {
}


@Component({
  selector: '[myItemAsAtribute]',
  template: `
      <li *ngFor="let item of items">{{item}}</li>

  `
})
export class MyItem {
}
0
N.Nonkovic