2016-06-24 3 views
3

Angular2에서 이미 구성 요소가 파괴되기 전에 알림을받을 수 있습니까? 즉 파괴 될 때입니다.Angular2는 onDestroy 전에보기를 분리합니까?

동적으로 뷰를로드하는 데 사용되는 ViewContainerRef를 하위 컨테이너에 보유하고있는 컨테이너 구성 요소가 있습니다. 컨테이너 구성 요소 자체가 파괴 된 경우 (부모 구성 요소의 * ngFor 지시문으로 인해) 현재 ViewContainerRef에로드 된 뷰를 분리하여 다른 컨테이너에 다시 첨부하려고합니다.

설명 : ngOnDestroy() 라이프 사이클 후크에서 ViewContainerRef가 이미 지워져 있으므로 모든보기가 삭제되고 더 이상 분리되지 않습니다. 은 반복되는 콜렉션이 변경 될 때 통지를 얻을

const LIFECYCLE_INTERFACES: Map<any, Type> = MapWrapper.createFromPairs([ 
    [LifecycleHooks.OnInit, OnInit], 
    [LifecycleHooks.OnDestroy, OnDestroy], 
    [LifecycleHooks.DoCheck, DoCheck], 
    [LifecycleHooks.OnChanges, OnChanges], 
    [LifecycleHooks.AfterContentInit, AfterContentInit], 
    [LifecycleHooks.AfterContentChecked, AfterContentChecked], 
    [LifecycleHooks.AfterViewInit, AfterViewInit], 
    [LifecycleHooks.AfterViewChecked, AfterViewChecked], 
]); 

const LIFECYCLE_PROPS: Map<any, string> = MapWrapper.createFromPairs([ 
    [LifecycleHooks.OnInit, 'ngOnInit'], 
    [LifecycleHooks.OnDestroy, 'ngOnDestroy'], 
    [LifecycleHooks.DoCheck, 'ngDoCheck'], 
    [LifecycleHooks.OnChanges, 'ngOnChanges'], 
    [LifecycleHooks.AfterContentInit, 'ngAfterContentInit'], 
    [LifecycleHooks.AfterContentChecked, 'ngAfterContentChecked'], 
    [LifecycleHooks.AfterViewInit, 'ngAfterViewInit'], 
    [LifecycleHooks.AfterViewChecked, 'ngAfterViewChecked'], 
]); 
+0

라이프 사이클 후크가 없습니다. 커스텀'ngFor'를 만들 수 있습니다. 소스 코드는 복잡하지 않습니다. 이 커스텀'ngFor'에서 추가 된 컴포넌트에 대해 메소드를 호출하거나 파괴 될 것이라는 컴포넌트에 통지하는 이벤트를 낼 수 있습니다. –

+0

멋진 생각. 나는 그것을 시도 할 것이다 – seraph

답변

1

현재 해결책은 아니지만 ngFor 지시문을 사용하는 부모 구성 요소의 ngOnChanges()를 구현하는 것입니다. ngFor에 의해 반복되는 배열이 변경되었고 길이가 이전보다 짧으면 모든 컨테이너 (@ViewChildren containers : QueryList)의 뷰를 분리하고 컨테이너 (Map)에 매핑합니다. 그런 다음 새 컨테이너 목록을 반복하고 maps.changed 수신기에서지도의 ViewRef를로드하여 매핑 된 뷰를 다시 삽입합니다.

@Component({ 
selector: 'container-collection', 
directives: [Container], 
template: `<container *ngFor="let i of views"></container>` 
}) 
export class ContainerCollection { 
public views = []; 

@ViewChildren(Container) private containers: QueryList<Container>; 

private viewMap = new Map<Container, ViewRef>(); 

public ngOnChanges(changes: {[key: string]: SimpleChange]}): void { 
    if(changes['views']) { 
    //detach all views and remember which container had which view 
    this.viewMap = new Map<Container, ViewRef>(); 

    this.containers.forEach(container => { 
    var view = container.viewContainer.detach(); 
    if(view) 
    this.viewMap.set(container, view); 
    }); 
    } 
} 

public ngAfterViewInit(): void { 
    //insert the views again (into the appropriate containers) 
    this.containers.changes.subscribe(() => { 
    this.containers.forEach(container => { 
    var view = this.viewMap.get(container); 
    if(view) 
    container.viewContainer.insert(view); 
    }); 
    }); 
} 
} 

@Component({ 
selector: 'container', 
template: `<div #viewContainer></div>` 
}) 
export class Container { 
@ViewChild('viewContainer') public viewContainer; 
} 

코드는 초안이며 구문 오류가있을 수 있습니다. 그러나 (나를 위해 일하는) 아이디어는 분명해야합니다.

구성 요소가 실제로 소멸되기 전에 호출되는 LifeCycle 후크를 추가하는 것은 Angular2 팀의 위대한 일입니다. (예 : ngBeforeDestroy()).

0

확실하지 않음 *ngFor으로 인해 파괴되었습니다.

그런 다음 @ViewChildren 주석을 사용하여 *ngFor에있는 렌더링 된 모든 구성 요소의 목록을 보유하십시오. 당신은 #mycomponents에 의해 확인 된 구성 요소를 반복 변경하는 하나 찾아 당신이 필요로하는 어떤 분리 몇 가지 사용자 정의 메소드를 호출 할 수

<my-component 
    #mycomponents 
    *ngFor="let c of collection" 
</my-component> 

:처럼 뭔가.

또 다른 어쩌면 쉬운 방법은 바로 @ViewChildrenQueryList 사용할 수 그것이 *ngFor으로 반복 컬렉션에 대한 변경 사항을 통보해야하는 Observable<any> 지금 가입이다 재산 changes을 가지고 있기 때문에. 그러나 어떤 시점에서 이벤트가 방출되는지 확실하지 않으므로 onDestroy으로 설명한 것처럼 너무 늦을 수 있습니다.

1

은 어쩌면 당신은 OnChanges 후크를 사용할 수 있고 당신이되고보기를 기대하는 것입니다 : 당신의 조건을 만족하는 어떤 다른 라이프 사이클 후크가있는 경우

+0

대답 주셔서 감사합니다. 그러나 예, 변화 이벤트가 파견 될 때 이미 너무 늦었습니다. – seraph

+0

그러나 onChanges 아이디어는 기본적으로 모두 효과가있었습니다. 전체 솔루션을 얻으려는 전체 답변을 추가했습니다. – seraph