2016-12-06 50 views
1

我正在致力於現有的SPA,我們逐步用Aurelia組件替換組件。我們使用TemplatingEngineenhance API。這很好,但我們還需要在移動到應用程序的另一部分(無頁面重新加載)時拆除那些增強的片段(刪除事件監聽器,...)。如何拆卸增強片段

我的想法是將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(); 

但從容器獲取視圖時出現錯誤(無法讀取未定義的的屬性'資源')。我從一個點擊處理程序調用了這個函數。

主要問題:如何手動觸發DfElement其子女的unbinddetached掛鉤?

獎金問題:我的aurelia實例(window.DFAureliaroothost的屬性未定義:這是壞事嗎?你有沒有看到這種在頁面中增強(和不增強)片段的潛在問題?

回答

1

使用從enhance()返回的View方法。

該方法返回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>

+0

我不使用''這個元素,所以第二個選項適用於我。謝謝! –

+0

將'this.view = null;'作爲'removeMyself'的最後一行是否很重要? –

+0

對於垃圾收集器? –