2017-01-29 3 views
1

В Angular2 мне нужно дублировать узел, а не перемещать его в некоторых случаях. У этого узла есть угловые свойства2, поэтому cloneNode не работает. Как мне это сделать?Как динамически добавлять клонированный узел в 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: Cloning component/HTML element and it's functionality

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

Но как добавить шаблон динамически?

+0

Вы пытались использовать 'ngFor'? – yurzui

+0

Зачем? Я хочу сделать это динамически – Gerard

ответ

3

Давайте использовать следующую разметку для иллюстрации:

<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, это не то, что вы хотите.

+0

Я пытаюсь вариант 1, я бы сказал, что вы ошибаетесь в '@ViewChild ('template')', он должен быть '' clone'' (или, по крайней мере, это работает для меня) , Есть ли способ, которым я мог бы динамически определять, куда вводить клонированный шаблон? вид 'document.getElementById.createEmbeddedView'? – Gerard

+0

@Gerard. Ну, вам нужна привязка для вставки клонированного шаблона. AFAIK, в декораторе '@ViewChild (селектор)' 'selector' может быть директивой/компонентом или переменной шаблона, как в моем примере. В документации неясно, можете ли вы использовать другие типы селекторов. Возможно, попробуйте селектор классов, например. '@ViewChild (».active ') 'или' @ViewChild (' [active] ') '. – AngularChef

+0

Хорошо, и важно то, что теперь это работает, и перед тобой это было совершенно неясно. Ты спасибо! :) – Gerard

Смежные вопросы