在Angular2中是否有可能在组件被销毁之前得到通知!?即什么时候要被销毁。
我有一个容器组件,它的一个子容器上有一个ViewContainerRef,用于动态加载视图。如果容器组件本身被销毁(在我的情况下是由于父组件中的* ngFor指令),我想分离当前在ViewContainerRef中加载的视图并再次将它附加到另一个容器上。
事情是:在ngOnDestroy()生命周期钩子中,ViewContainerRef已被清除,因此所有视图都被销毁,不再分离。
答案 0 :(得分:2)
我现在的解决方案(不是真正的解决方法)是实现使用ngFor指令的父组件的ngOnChanges()。如果由ngFor迭代的数组已经改变并且其长度比以前短,我只需分离所有容器的视图(@ViewChildren容器:QueryList)并将它们映射到容器(Map)。 然后,我通过迭代新的容器列表并从maps中加载ViewRef,在containers.changed侦听器中重新插入映射的视图。
@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;
}
代码只是草稿,可能包含语法错误。但这个想法(对我有用)应该是明确的。
Angular2团队会很好地添加一个LifeCycle钩子,它会被一个组件实际销毁之前调用。 (例如ngBeforeDestroy())左右。
答案 1 :(得分:1)
也许您可以使用OnChanges
挂钩在迭代集合发生更改时收到通知,并且您希望视图因*ngFor
而被销毁。
然后使用@ViewChildren
注释来保存*ngFor
中所有渲染组件的列表。类似的东西:
<my-component
#mycomponents
*ngFor="let c of collection"
</my-component>
您可以迭代由#mycomponents
标识的组件,找到哪个组件已更改,并调用一些自定义方法来分离您需要的任何内容。
另一个也许更简单的方法可能只使用@ViewChildren
和QueryList
,因为它的属性changes
是Observable<any>
所以订阅它应该通知您任何更改到使用*ngFor
迭代的集合。但是,我不确定事件的发生点,因此可能为时已晚,因为您使用onDestroy
进行了描述。
答案 2 :(得分:0)
不确定是否有任何其他生命周期钩子可以满足您的条件:
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'],
]);