2016-12-02 2 views
2

Я хотел бы знать, если это возможно, чтобы сделать что-то вроде следующего в угловых 2. Имея компонент с этим шаблоном (например):Удаление дочерних элементов программно через родительский компонент

шаблон ParentComponent

<div> 
    <childOne></childOne> 

    <childTwo *ngFor="let item of items"> 
    whatever 
    </childTwo> 
</div> 

Есть ли способ удалить эти элементы с помощью ViewContainerRef из ParentComponent, как показано ниже?

var viewContainerRef = /* get ParentComponent ViewContainerRef */ 
var index = viewContainerRef.indexOf(childViewRef); 
viewContainerRef.remove(index); 

Я попытался с помощью раствора, аналогичного предложенных здесь, чтобы получить ребенок ViewRef: Angular2 , How to find index of a view inside a viewContianer

Но IndexOf возвращается -1, а если ребенок ViewRef нет в контейнере.

Я хотел удалить эти дочерние компоненты вне ParentComponent, а не внутри кода ParentComponent, например, удаление из массива элементов или привязок.

Я также попытался использовать метод destroyView из Renderer, но без эффекта. NgFor выполняет итерацию по массиву элементов и создает встроенные представления для каждого childTwo. Я не делаю, если в этом случае ViewRef, полученный от инжектора ChildTwo (как предлагается в решении для ссылок), совпадает с этим EmbeddedViewRef.

Есть ли способ сделать что-то подобное?

спасибо.

*********************** ОБНОВЛЕНИЕ ********************** *****

Я попытаюсь немного упростить то, чего я пытаюсь достичь. Я разрабатываю приборной панели, где пользователь может создавать свои компоненты, используя API, как следующее:

@Component({ selector: 'child' }) 
class UserChildComponent extends DashboardComponent { 
    (...) 
} 

@Component({ selector: 'parent' }) 
class UserParentComponent extends DashboardComponent { 

    @ViewChildren(UserChildComponent) m_children: QueryList<UserChildComponent>; 

    private models: Array<ChildModel>; 

    (...) 
} 

/* UserParentComponent template 
<div> 
    <child></child> 
    <child *ngFor="let model of models"></child> 
</div> 

У меня есть логическое дерево всех компонентов Dashboard и его отношения друг с другом (родитель/потомок), из-за подтипирование и другие вещи, которые ведут сцены, которые здесь не касаются.

Это сценарий, о котором я думаю: пользователь сможет удалить любой из этих компонентов дочерней панели. Я хотел бы, имея все дерево отношений, удалить ребенка из родителя и уведомить пользователя (возможно, через ViewChildren в родительском элементе). Или я мог бы называть метод родителем, так что пользователь мог бы обновлять свои модели Array, возможно, это был бы лучший способ.

Я просто думал так, что пользователь будет иметь меньше работы возможно, не придется беспокоиться о синхронизации модели \ компонента (в данном случае)

Еще раз спасибо.

+1

Что вы на самом деле пытаетесь достичь? Какой элемент или компонент вы хотите удалить и почему? –

+0

Точно, причиной удаления элементов обычно является задание Угловое по директивам – Reyraa

+0

Я хочу, чтобы убрать любой дочерний компонент компонента извне. @ GünterZöchbauer, мне нужен общий способ удалить любого ребенка из любого родительского компонента извне. Это лучший способ реализовать то, что я хочу. –

ответ

0

Вы можете использовать

let element = querySelector(...); 
element.parentNode.removeChild(element) 

Но это не рекомендуется использовать прямой доступ к DOM в Angular2. Сам Angular2 не предоставляет API для того, что вы хотите. В Angular2 вы должны просто обновить модель и позволить Angular выполнять манипуляции с DOM.

+0

Да, я хотел избежать использования DOM напрямую из-за этого. Кроме того, это вызовет ngOnDestroy удаленного компонента? Спасибо, Гюнтер! –

+0

Почему вы не хотите, чтобы его уничтожали, когда вы его удаляли? –

+0

На самом деле, я хочу, чтобы меня вызвали. ;) Просто подтвердил, был ли он фактически вызван при удалении его непосредственно из DOM. Спасибо, но мне придется искать другой способ не работать с DOM. :( –

1

Одно из возможных решений, которые я могу думать о том, чтобы создать службу, которая имеет эмиттер событие так:

export class ChildRemoveNotifierService{ 

    public $remove = new EventEmitter<string>(); 

} 

И потом, мы должны были бы директиву, которая может удалить элемент и создать их, а также :

@Directive({ selector: '[remover]' }) 
export class RemoveDirective { 

    @Input remove = ''; 
    constructor(
    private removerService:ChildRemoveNotifierService , 
    private _templateRef: TemplateRef, 
    private _viewContainer: ViewContainerRef 
    ) { 


      let subscription = 
      this.removerService.$remove.subscribe((tobeRemoved)=>{ 
      if(tobeRemoved===this.remove){ 
       this._viewContainer.clear(); 
       subscription.unsubscribe(); 
      } 
      }) 
    } 

И потом, вы бы использовать это так:

<span *remover='my-component'> 
    <my-component></my-component> 
</span> 

В основном, ny, который необходимо удалить динамически, следует обернуть директивой * remover.

А потом, теперь каждый может удалить все :)

Вы родительский компонент может стрелять событие так:

export class ParentComponentOrAnyOther{ 

    constructor(private removerService:ChildRemoveNotifierService){ 

     } 

     removeAComponent(){ 

      removerService.$remove.emit('my-component'); 

     } 
} 

Это не идеально, или, может быть, я не знать.

Но я знаю, что это абсолютно Угловой способ, и вы не делаете никаких манипуляций с DOM.

Таким образом, у вас есть все жизненные циклы Angular2, особенно событие onDestroy будет запущено внутри моего компонента.

EDIT:

Я думаю, что это будет работать тоже:

<my-component *remover='my-component'></my-component> 
+0

Это действительно интересный подход. это правильно, в вашем примере всегда останется элемент , когда ребенок будет удален. Не то, чтобы это было слишком беспокоиться. Спасибо за неприятность написания этого. :) –

+0

Да, вот почему я сказал это может быть не совсем приятно, но проблема в том, что вы не загружаете компонент d ynamically самостоятельно и позволить Angular2 загружать его в обычном режиме, вы не сможете его уничтожить. – Milad

+0

На самом деле, я думаю, вы также можете * удалить и мой компонент! , не было бы какого-либо промежутка влево, я думаю – Milad

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

  • Нет связанных вопросов^_^