web-dev-qa-db-ja.com

Angular2:Host要素をコンポーネントのテンプレートに置き換えます

私はangular全般とangular2具体的に。コンテナコンポーネントを記述しようとしていますが、コンテナコンポーネントには子コンポーネントが必要です。

たとえば、コンテナコンポーネント

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

子コンポーネント:

import { Component } from 'angular2/core'

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

この構造を作りたい:

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

次のようにレンダリングされます。

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

しかし、代わりに、コンテナーのHost要素とアイテムも保持されます。

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

Plunkはここから入手可能

質問:Host要素を削除し、レンダリングされたテンプレートのみを残す方法はありますか?

29
Denis Itskovich

最後に解決策を見つけました:ElementRefMyItemに注入し、そのnativeElement.innerHTML

MyList

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
  }
}

ワーキングプランクはこちら

13
Denis Itskovich

これはあなたが欲しいものを手に入れるべきです:

@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>
14

新しいangularバージョンには本当にクールなディレクティブがあり、これはユースケースにも使用できます。Tadaa: NgComponentOutlet 。Happy coding;)

例:

@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;
}
2
Luckylooke

古いブラウザーバージョンではサポートされていないハッキングの回避策がありますが、私のプロジェクトでは機能していたため、多くのコードを変更または追加せずに統合するのは非常に簡単だと思います。

最初に、MyItemクラス/コンポーネントのセレクターをelement selectorから変更する必要があります

selector: 'custom-element-name'

toattribute selector

selector: '[customAttributeName]'

最後にhtml slot 要素を使用してラップMyItemMyListhtmlテンプレート

<slot customAttributeName></slot>

完全なコード:

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