私は、角度2を使って3d "カードフリップ"を作成しています。親の 'card-flip'コンポーネントは、ネストされた 'card-flip-front'カード・フリップ・バック 'コンポーネントである。ng-contentを持つAngular2コンポーネントの "クローン"を作成する
<card-flip card-flip-id="demo-1" class="grid_col-6">
<card-flip-front class="card">
<div class="card__inner">
Card Front
</div>
</card-flip-front>
<card-flip-back class="card">
<div class="card__inner">
Card Back
</div>
</card-flip-back>
</card-flip>
コンテンツ投影とデータバインディングを備えたカードフリップフロントコンポーネントの「クローン」を作成したいと思います。 「クローン」はアニメーション化に使用され、「オリジナル」は元の位置に隠されたままになります。このようにして、がを元の位置に戻すときに、(クローンをスクロールまたはサイズ変更しても)「クローン」をアニメーション化する場所の参照があります。
私が直面している主な課題は、ng-content
タグ内のコンテンツも「クローン」に投影する必要があることです。問題は、最初のng-content
タグがコンテンツ投影にAngularによって使用され、ラベルなしの追加のng-content
タグが空になることです(予想される動作です)。
DOMで要素のダムで静的なコピーを作成するだけではどうですか?私はこれを避け、ネストされたコンポーネントとデータを挿入するデータバインディング(それによって要素の寸法を変更する)が引き続き機能するようにしたいと思います。
「クローン」として機能するためにComponentFactoryを介してCardFlipFrontコンポーネントのインスタンスを作成し、単に「元の」CardFlipFrontのinnerHTMLを挿入する私の仕事はここまでです。
import {
Component,
ComponentFactory,
ComponentFactoryResolver,
ComponentRef,
ContentChild,
Inject,
Input,
OnInit,
ViewChild,
ViewContainerRef
} from '@angular/core';
import { CardFlipFrontComponent } from './card-flip-front.component';
import { CardFlipBackComponent } from './card-flip-back.component';
import { CardFlipService } from './card-flip.service';
@Component({
selector: 'card-flip',
templateUrl: './card-flip.component.html',
styleUrls: ['./card-flip.component.css'],
entryComponents: [
CardFlipFrontComponent
]
})
export class CardFlipComponent implements OnInit {
@Input('card-flip-id') public id: string;
@ContentChild(CardFlipFrontComponent) private front: CardFlipFrontComponent;
@ContentChild(CardFlipBackComponent) private back: CardFlipBackComponent;
@ViewChild('frontCloneContainer', { read: ViewContainerRef }) private frontCloneContainer: ViewContainerRef;
private frontComponentRef: ComponentFactory<CardFlipFrontComponent>;
private frontClone: ComponentRef<CardFlipFrontComponent>;
constructor(
@Inject(CardFlipService) private _cardFlipService: CardFlipService,
private _componentFactoryResolver: ComponentFactoryResolver
) {
this.frontComponentRef = this._componentFactoryResolver.resolveComponentFactory(CardFlipFrontComponent);
}
ngOnInit() {
this._cardFlipService.register(this.id);
}
ngAfterViewInit() {
// Create a card-flip-front component instance to serve as a "clone"
this.frontClone = this.frontCloneContainer.createComponent(this.frontComponentRef);
// Copy the innerHTML of the "original" into the "clone"
this.frontClone.instance.el.nativeElement.innerHTML = this.front.el.nativeElement.innerHTML;
}
ngOnDestroy() {
this.frontClone.destroy();
}
}
<ng-content select="card-flip-front"></ng-content>
<ng-container #frontCloneContainer></ng-container>
<ng-content select="card-flip-back"></ng-content>
import {
Component,
ElementRef,
HostBinding,
Input,
OnInit,
Renderer
} from '@angular/core';
@Component({
selector: 'card-flip-front',
templateUrl: './card-flip-front.component.html',
styleUrls: ['./card-flip-front.component.css']
})
export class CardFlipFrontComponent implements OnInit {
constructor(private _el: ElementRef, private _renderer: Renderer) { }
public get el(): ElementRef {
return this._el;
}
public get renderer(): Renderer {
return this._renderer;
}
ngOnInit() { }
}
<ng-content></ng-content>
UPDATE:
[OK]を、ので、いくつかの類似した課題やgithub issue hereについて読んだ後、私は次のことを試してみました。
<ng-template #frontTemplate>
<ng-content select="card-flip-front"></ng-content>
</ng-template>
<ng-container *ngIf="isOpen == true" #front1>
<ng-container *ngTemplateOutlet="frontTemplate"></ng-container>
</ng-container>
<ng-container *ngIf="isOpen == false" #front2>
<ng-container *ngTemplateOutlet="frontTemplate"></ng-container>
</ng-container>
<ng-content select="card-flip-back"></ng-content>
基本的に、私たちは、テンプレート内に配置し、唯一のクラスのプロパティisOpen
に基づいて、テンプレートの1つのインスタンスが表示されます*ngIf
文で2個のng-container
のタグを使用してng-content
で単一の投影問題を回避することができます。
これはすべての問題を解決するわけではありませんが、同時に1つのコンテナしかレンダリングされないためです。だから、私は "元"の現在の位置を取得して、上記のリターンアニメーションの間に "クローン"をアニメーション化する場所を特定することはできません。
考えてくれてありがとうございますが、私は誤解の可能性があると思います。この例では、ng-contentを2回使用しています。最初のng-contentタグだけが投影されたコンテンツを含むので、主な問題は依然として残ります。 – Jbird
このコンテンツの制限は、意図された動作です。ここでは、https://github.com/angular/angular/issues/7795で詳しく説明しています – Jbird