7

私は Angular 2-rc3 を使用しており、Componentトランスクルージョンを少し異なる方法で適用したいと考えています。ここに私のコンポーネントがあります:

import { Component, Input } from '@angular/core';

@Component({
    selector: 'my-list',
    template: `<ul>
        <li *ngFor="let item of data">
            -- insert template here --
            <ng-content></ng-content>
        </li>
    </ul>`
})
export class MyListComponent {
    @Input() data: any[];
}

そして、私はそれを次のように使用します:

<my-list [data]="cars">
    <div>{{item.make | uppercase}}</div>
</my-list>

ご覧のとおり、コンポーネントで使用されるインライン テンプレートを定義しようとしています。今、これはひどく間違っています。まず、それを言うデータバインディング例外can't read property 'make' of undefineditem.makeではなく、周囲のコンポーネントから読み取ろうとしていMyListComponentます。しかし、今のところこれを一時的に無効にしても:

<my-list [data]="cars">
    <div>{item.make | uppercase}</div>
</my-list>

次に、2 番目の問題が表示されます。

-- insert template here --
-- insert template here --
-- insert template here --
-- insert template here --
{item.make | uppercase}

したがって、Angular は 内で使用するためにテンプレートを実際にコピーするのではなく*ngFor、要素をバインドするだけで、最終的に最後のアイテムに関連付けられます。

これを機能させるにはどうすればよいですか?

AngularJS でも同じ問題がありました。petebacondarwin が compile を介して DOM を操作するソリューションを投稿しましたが、これは素晴らしいことでした。コンポーネントに注入することで、Angular 2でもこのオプションを使用できますElementRefが、! 大きな違いの 1 つは、AngularJS ではデータバインディングの前にオフになったことです。つまり、テンプレートでのcompile使用に問題はありませんでした。{{item.make}}Angular 2 では、{{item}}事前に解析されているため、これは問題ないようです。では、これについて最善の方法は何ですか?わずかに異なる表記[[item]]と文字列を使用して全体を置き換えることは、最もエレガントな方法とは思えません...

前もって感謝します!

// 編集:問題を再現するPlnkrを次に示します。

4

2 に答える 2

6

メソッドを詳しく説明するにはngForTemplate:

( Angular 4 以降、要素は と呼ばれるようになり<ng-template>ました。)

  1. <template>の代わりに、外側コンポーネントと内側コンポーネントの両方でタグを使用し<ng-content>ます。

  2. <li>app.component html に移動され、このコンポーネントの には、内部コンポーネントの反復変数を参照 <template>する特別な「let-」属性があります。

    <my-list [data]="cars">
      <template let-item>
        <li>
          <div>{{item.make | uppercase}}</div>
        </li>
      </template>
    </my-list>
    
  3. 内部コンポーネント<template>も同様に持っており、次のように ngFor のバリアントを使用しています。

    <ul>
        <template #items ngFor [ngForOf]="data" [ngForTemplate]="tmpl">
            -- insert template here --
        </template>
    </ul>
    
  4. ngForTemplate 属性に割り当てられた 'tmpl' 変数は、コンポーネント コードで取得する必要があります。

    export class MyListComponent {
        @Input() data: any[];
        @ContentChild(TemplateRef) tmpl: TemplateRef;
    }
    
  5. @ContentChild と TemplateRef は角度のあるビットなので、インポートする必要があります

    import { Component, Input, ContentChild, TemplateRef } from '@angular/core';
    

ここplnkrでこれらの変更を加えた plunkr のフォークを参照してください。

データをリストに渡しているため、外側に ngFor がある可能性があるため、これはあなたの述べた問題に対する最も満足のいく解決策ではありません。さらに、追加のコンテンツ (文字どおりの「-- ここにテンプレートを挿入 --」) がドロップされるため、外側のテンプレートにもある必要があることを表示したいと考えました。

内部コンポーネント内で反復が提供される場合 (たとえば、サービス呼び出しから)、コードでテンプレートの操作を行う場合に役立つ可能性があることがわかります。

于 2017-02-13T06:43:30.223 に答える
1
  • <ng-content>内部*ngForは機能しないため、

    <li *ngFor="let item of data">
        -- insert template here --
        <ng-content></ng-content>
    </li>
    

意味のあることはしません。すべてが最初にトランスクルージョンされます<ng-content>

https://github.com/angular/angular/issues/8563は、要件の一部を解決する可能性があります。

于 2016-06-24T17:15:20.283 に答える