如何拆除增强型片段 [英] How to tear down an enhanced fragment

查看:34
本文介绍了如何拆除增强型片段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发现有的 SPA,我们将逐步用 Aurelia 组件替换组件.我们使用 TemplatingEngineenhance API.这很有效,但我们还需要在移动到应用程序的另一部分(不重新加载页面)时拆除那些增强的片段(删除事件侦听器,...).

I am working on an existing SPA where we replace components with Aurelia components step by step. We use the enhance API of the TemplatingEngine. That works pretty well but we also need to tear down those enhanced fragments (remove event listeners, ...) when moving to another part of the application (no page reload).

我的想法是将 aurelia 实例保留在页面中并重复使用.

My idea is to keep the aurelia instance in the page and reuse it.

目前我像这样增强片段:

Currently I enhance fragments like this:

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 如下所示:

The HTML I enhance looks like:

<df-element></df-element>

我在自定义元素本身的函数中尝试了这个 (DfElement::removeMyself()):

I tried this in a function of the custom element itself (DfElement::removeMyself()):

let vs: ViewSlot = this.container.get(ViewSlot);
let view: View = this.container.get(View);
vs.remove(view);
vs.detached();
vs.unbind();

但是从容器获取视图时出现错误(无法读取未定义的属性资源").我从点击处理程序调用了这个函数.

but I get an error when getting the view from the container (Cannot read property 'resources' of undefined). I called this function from a click handler.

主要问题:如何手动触发DfElement 及其子元素的unbinddetached 钩子?

Main question: how to manually trigger the unbind and detached hooks of the DfElement and its children?

额外问题:我的 aurelia 实例 (window.DFAurelia) roothost 的属性未定义:那是一件坏事?您认为这种增强(和取消增强)页面中片段的方式有什么潜在问题吗?

Bonus questions: properties of my aurelia instance (window.DFAurelia) root and host are undefined: is that a bad thing? Do you see any potential issue with this way of enhancing (and un-enhancing) fragments in the page?

推荐答案

使用从 enhance() 方法返回的 View.

enhance() 方法返回增强的 View 对象.从调用 enhance() 的同一位置管理拆卸是一种很好的做法,因为您可能无法相信某个元素会记住拆卸自身.但是,您始终可以向增强容器注册 View 实例以从自定义元素中访问它.

Use the View returned from the enhance() method.

The enhance() method returns the enhanced View object. It is a good practice to manage the teardown from the same location where you call enhance(), as you may not be able to trust an element to remember to tear itself down. However, you can always register the View instance with the enhance container to access it from within the custom element.

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 的调用.

This will tell the DI container to respond to calls for View with this 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) 生命周期方法.

Using the created(view) lifecycle method

A much better practice would be to use the created(view) lifecycle method in your custom element.

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 实际上是我的 元素的 ViewremoveMyself() 完全删除了 .

This is a much more straightforward, best practices way of having a custom element grab its own View. However, when trying to write this answer for you, I tested nesting a custom element in a <compose> element. The result was that the View in my custom element was actually the View for my <compose> element, and removeMyself() removed the <compose> entirely.

这篇关于如何拆除增强型片段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆