如何拆除增强片段
How to tear down an enhanced fragment
我正在开发一个现有的 SPA,我们在其中逐步将组件替换为 Aurelia 组件。我们使用enhance
API的TemplatingEngine
。这工作得很好,但我们还需要在移动到应用程序的另一部分(不重新加载页面)时拆除那些增强的片段(删除事件侦听器,...)。
我的想法是在页面中保留 aurelia 实例并重复使用它。
目前我增强片段是这样的:
function enhanceFragment(targetElement) {
function proceed() {
let aurelia = window.DFAurelia;
let engine = aurelia.container.get(TemplatingEngine);
engine.enhance({
container: aurelia.container,
element: targetElement,
resources: aurelia.resources
});
}
if (!window.DFAurelia) {
bootstrap(async aurelia => {
aurelia.use
.defaultBindingLanguage()
.defaultResources()
.eventAggregator()
.developmentLogging()
.globalResources('app/df-element');
await aurelia.start();
window.DFAurelia = aurelia;
proceed();
});
} else {
proceed();
}
}
我增强的HTML看起来像:
<df-element></df-element>
我在自定义元素本身的函数中尝试了这个 (DfElement::removeMyself()
):
let vs: ViewSlot = this.container.get(ViewSlot);
let view: View = this.container.get(View);
vs.remove(view);
vs.detached();
vs.unbind();
但是从容器获取视图时出现错误(无法读取未定义的 属性 'resources')。我从点击处理程序调用了这个函数。
主要问题:如何手动触发DfElement
和子类的unbind
和detached
钩子?
额外问题:我的 aurelia
实例 (window.DFAurelia
) root
和 host
的属性未定义:这是一件坏事吗?您是否发现这种增强(和取消增强)页面片段的方式存在任何潜在问题?
使用从 enhance()
方法返回的 View
。
enhance()
方法returns增强View
对象。从您调用 enhance()
的同一位置管理拆卸是一个很好的做法,因为您可能无法相信某个元素会记得拆卸自己。但是,您始终可以向增强容器注册 View
实例,以便从自定义元素中访问它。
function proceed() {
let aurelia = window.DFAurelia;
let container = aurelia.container;
let engine = container.get(TemplatingEngine);
let view = engine.enhance({
container: container,
element: targetElement,
resources: aurelia.resources
});
container.registerInstance(View, view);
}
这将告诉 DI 容器使用此 View
响应对 View
的调用。
import { inject, Aurelia, View } from 'aurelia-framework';
@inject(Aurelia, Element)
export class DFCustomElement {
// element is passed to the constructor
constructor(aurelia, element) {
this.container = aurelia.container;
this.element = element;
}
// but View is only available after attached
attached() {
this.view = this.container.get(View);
}
removeMyself() {
this.element.remove();
this.view.detached();
this.view.unbind();
}
}
使用 created(view)
生命周期方法
更好的做法是在自定义元素中使用 created(view)
生命周期方法。
import { inject } from 'aurelia-framework';
@inject(Element)
export class DFCustomElement {
constructor(element) {
this.element = element;
}
created(view) {
this.view = view;
}
removeMyself() {
this.element.remove();
this.view.detached();
this.view.unbind();
}
}
这是让自定义元素获取自己的元素的更直接、最佳实践方法 View
。但是,在尝试为您编写此答案时,我测试了在 <compose>
元素中嵌套自定义元素。结果是我的自定义元素中的 View
实际上是 <compose>
元素的 View
,而 removeMyself()
完全删除了 <compose>
。
我正在开发一个现有的 SPA,我们在其中逐步将组件替换为 Aurelia 组件。我们使用enhance
API的TemplatingEngine
。这工作得很好,但我们还需要在移动到应用程序的另一部分(不重新加载页面)时拆除那些增强的片段(删除事件侦听器,...)。
我的想法是在页面中保留 aurelia 实例并重复使用它。
目前我增强片段是这样的:
function enhanceFragment(targetElement) {
function proceed() {
let aurelia = window.DFAurelia;
let engine = aurelia.container.get(TemplatingEngine);
engine.enhance({
container: aurelia.container,
element: targetElement,
resources: aurelia.resources
});
}
if (!window.DFAurelia) {
bootstrap(async aurelia => {
aurelia.use
.defaultBindingLanguage()
.defaultResources()
.eventAggregator()
.developmentLogging()
.globalResources('app/df-element');
await aurelia.start();
window.DFAurelia = aurelia;
proceed();
});
} else {
proceed();
}
}
我增强的HTML看起来像:
<df-element></df-element>
我在自定义元素本身的函数中尝试了这个 (DfElement::removeMyself()
):
let vs: ViewSlot = this.container.get(ViewSlot);
let view: View = this.container.get(View);
vs.remove(view);
vs.detached();
vs.unbind();
但是从容器获取视图时出现错误(无法读取未定义的 属性 'resources')。我从点击处理程序调用了这个函数。
主要问题:如何手动触发DfElement
和子类的unbind
和detached
钩子?
额外问题:我的 aurelia
实例 (window.DFAurelia
) root
和 host
的属性未定义:这是一件坏事吗?您是否发现这种增强(和取消增强)页面片段的方式存在任何潜在问题?
使用从 enhance()
方法返回的 View
。
enhance()
方法returns增强View
对象。从您调用 enhance()
的同一位置管理拆卸是一个很好的做法,因为您可能无法相信某个元素会记得拆卸自己。但是,您始终可以向增强容器注册 View
实例,以便从自定义元素中访问它。
function proceed() {
let aurelia = window.DFAurelia;
let container = aurelia.container;
let engine = container.get(TemplatingEngine);
let view = engine.enhance({
container: container,
element: targetElement,
resources: aurelia.resources
});
container.registerInstance(View, view);
}
这将告诉 DI 容器使用此 View
响应对 View
的调用。
import { inject, Aurelia, View } from 'aurelia-framework';
@inject(Aurelia, Element)
export class DFCustomElement {
// element is passed to the constructor
constructor(aurelia, element) {
this.container = aurelia.container;
this.element = element;
}
// but View is only available after attached
attached() {
this.view = this.container.get(View);
}
removeMyself() {
this.element.remove();
this.view.detached();
this.view.unbind();
}
}
使用 created(view)
生命周期方法
更好的做法是在自定义元素中使用 created(view)
生命周期方法。
import { inject } from 'aurelia-framework';
@inject(Element)
export class DFCustomElement {
constructor(element) {
this.element = element;
}
created(view) {
this.view = view;
}
removeMyself() {
this.element.remove();
this.view.detached();
this.view.unbind();
}
}
这是让自定义元素获取自己的元素的更直接、最佳实践方法 View
。但是,在尝试为您编写此答案时,我测试了在 <compose>
元素中嵌套自定义元素。结果是我的自定义元素中的 View
实际上是 <compose>
元素的 View
,而 removeMyself()
完全删除了 <compose>
。