Angular2 在 onDestroy 之前分离视图?
Angular2 detach view before onDestroy?
在 Angular2 中是否有可能在组件被销毁之前得到通知!?即当它即将被销毁时。
我有一个容器组件,它的一个子组件上有一个 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'],
]);
也许您可以使用 OnChanges
钩子在迭代集合发生变化时得到通知,并且您预计视图会因 *ngFor
.
而被销毁
然后使用 @ViewChildren
注释保存 *ngFor
中所有渲染组件的列表。类似于:
<my-component
#mycomponents
*ngFor="let c of collection"
</my-component>
您可以迭代由 #mycomponents
标识的组件,找出哪个已更改并调用一些自定义方法来分离您需要的任何内容。
另一个可能更简单的方法是只使用 @ViewChildren
和 QueryList
因为它有 属性 changes
这是一个 Observable<any>
所以订阅它应该通知您有关使用 *ngFor
迭代的集合的任何更改。但是,我不确定事件是在哪一点发出的,所以可能为时已晚,正如您在 onDestroy
.
中描述的那样
我现在的解决方案(不是真正的解决方法)是实现使用 ngFor 指令的父组件的 ngOnChanges() 。如果由 ngFor 迭代的数组已经改变并且它的长度比以前更短,我只需分离所有容器的视图(@ViewChildren 容器:QueryList)并将它们映射到容器(Map)。
然后,我在 containers.changed 侦听器中通过迭代新容器列表并从地图加载 ViewRefs 再次重新插入映射视图。
@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() )左右。
在 Angular2 中是否有可能在组件被销毁之前得到通知!?即当它即将被销毁时。
我有一个容器组件,它的一个子组件上有一个 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'],
]);
也许您可以使用 OnChanges
钩子在迭代集合发生变化时得到通知,并且您预计视图会因 *ngFor
.
然后使用 @ViewChildren
注释保存 *ngFor
中所有渲染组件的列表。类似于:
<my-component
#mycomponents
*ngFor="let c of collection"
</my-component>
您可以迭代由 #mycomponents
标识的组件,找出哪个已更改并调用一些自定义方法来分离您需要的任何内容。
另一个可能更简单的方法是只使用 @ViewChildren
和 QueryList
因为它有 属性 changes
这是一个 Observable<any>
所以订阅它应该通知您有关使用 *ngFor
迭代的集合的任何更改。但是,我不确定事件是在哪一点发出的,所以可能为时已晚,正如您在 onDestroy
.
我现在的解决方案(不是真正的解决方法)是实现使用 ngFor 指令的父组件的 ngOnChanges() 。如果由 ngFor 迭代的数组已经改变并且它的长度比以前更短,我只需分离所有容器的视图(@ViewChildren 容器:QueryList)并将它们映射到容器(Map)。 然后,我在 containers.changed 侦听器中通过迭代新容器列表并从地图加载 ViewRefs 再次重新插入映射视图。
@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() )左右。