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

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

问题描述

我正在开发一个现有的SPA,在该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();

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

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

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天全站免登陆