Как динамически добавить клонированный узел в angular2 (эквивалентно cloneNode)
В Angular2 мне нужно дублировать узел, а не перемещать его в некоторых случаях. Этот узел имеет свойства angular2, поэтому cloneNode не работает. Как мне это сделать?
* что не работает
let el = <HTMLElement>document.getElementById(divId);
if ((<HTMLElement>el.parentNode).id == 'itsMe')
el = <HTMLElement>el.cloneNode(true);
document.getElementById(anotherId).appendChild(el);
* что будет работать, из Angular2: компонент клонирования / элемент HTML и его функциональность
@Component({
selector: 'my-app',
template: `
<template #temp>
<h1 [ngStyle]="{background: 'green'}">Test</h1>
<p *ngIf="bla">Im not visible</p>
</template>
<template [ngTemplateOutlet]="temp"></template>
<template [ngTemplateOutlet]="temp"></template>
`
})
export class AppComponent {
bla: boolean = false;
@ContentChild('temp') testEl: any;
}
Но как добавить шаблон динамически?
1 ответ
Давайте используем следующую разметку для иллюстрации:
<p>Paragraph One</p>
<p>Paragraph Two</p> <!-- Let's try to clone this guy -->
<p>Paragraph Three</p>
Вариант 1 - Вручную обернуть элемент для клонирования внутри <template>
тег
Это в основном то, что вы сделали, только вместо того, чтобы распечатать шаблон с ngTemplateOutlet
, возьмите ссылку на него в классе вашего компонента и обязательно вставьте его createEmbeddedView()
,
@Component({
selector: 'my-app',
template: `
<p>Paragraph One</p>
<template #clone>
<p>Paragraph Two</p>
</template>
<p>Paragraph Three</p>
<button (click)="cloneTemplate()">Clone Template</button>
<div #container></div>
`
})
export class AppComponent{
// What to clone
@ViewChild('clone') template;
// Where to insert the cloned content
@ViewChild('container', {read:ViewContainerRef}) container;
constructor(private resolver:ComponentFactoryResolver){}
cloneTemplate(){
this.container.createEmbeddedView(this.template);
}
}
В этом примере я вставляю "клон" в определенное место в разметке (<div #container></div>
), но вы также можете добавить его внизу шаблона текущего компонента.
Также обратите внимание, что оригинал <p>Paragraph Two</p>
больше не видно
Вариант 2 - Использовать структурную директиву
Если вы хотите клонировать элемент в его текущем местоположении, в конечном итоге:
<p>Paragraph One</p>
<p>Paragraph Two</p> <!-- Original paragraph -->
<p>Paragraph Two</p> <!-- Cloned paragraph -->
<p>Paragraph Three</p>
Тогда вы могли бы создать структурную директиву *clone
и примените его к абзацу для клонирования, например так:
<p>Paragraph One</p>
<p *clone>Paragraph Two</p>
<p>Paragraph Three</p>
Интересно, что структурная директива заключает в себе элемент, к которому она применяется, внутри <template>
тег. Очень похоже на то, что мы сделали в варианте 1, только в этом случае у нас НЕТ КОНТРОЛЯ над местом, где распечатываются клоны (они появятся там, где был оригинальный абзац).
Это будет по сути копировать *ngFor
поведение, так что это, вероятно, не очень полезно. Кроме того, кажется из вашего комментария yurzui
что это не то, что вы хотите.