2016-03-31 5 views
1

私は表形式のデータを生成するカスタム要素を作成しました。正当な理由から、これは実際のHTMLを生成し、テンプレートを使用せずにDOMに挿入します。Aurelia dynamic binding

クリックオブザーバーを特定の要素にアタッチする必要があります。クリックに応じてカスタム要素で関数を実行できます。テンプレートを使用している場合は、click.delegateを使用しますが、生成されたHTMLではそのテンプレートを使用できません。

jQueryを使用する以外に、Aureliaでイベントハンドラをどのようにアタッチしますか?

+2

イベントハンドラを使用して、生成されたhtmlではなく親要素にイベントハンドラをアタッチできます。それがあなたの問題を解決しますか? –

答えて

4

私はこの答えは遅れている知っているが、場合には、これは(適切に)されていない、まだ解決および/または他の誰かが、将来的にこれを見つけた:動的に生成して任意のアウレリア行動の作業を行うために

HTML、あなたはそのHTMLをコンパイルする必要があります。

私はあなたがHTMLの文字列を渡すことを可能にするとbindables、カスタム要素/属性のような任意の行動がするように、それは、その後、コンパイルされます(どのようアウレリアの enhancecompose作業に基づく)カスタム要素に取り組んできました

ただ仕事。 htmlが変更されたときにも再コンパイルされます。/app.html

<template> 
    <dynamic-html html.bind="dynamicHtml"></dynamic-html> 
</template> 

srcが/

export class App { 
    public dynamicHtml: string = ` 
<button click.delegate="handleClick()">Click me</button> 
`; 

    public handleClick(): void { 
    alert("Hello!") 
    } 
} 

のsrc /ダイナミックHTMLをapp.ts https://gist.run?id=1960218b52ba628f73774822aef55ad7

SRC:

は、ここでの例です。 t

import { 
    customElement, 
    TaskQueue, 
    bindable, 
    ViewCompiler, 
    ViewSlot, 
    View, 
    ViewResources, 
    Container, 
    ViewFactory, 
    inlineView, 
    inject, 
    DOM 
} from "aurelia-framework"; 

@customElement("dynamic-html") 
@inlineView("<template><div></div></template>") 
@inject(DOM.Element, TaskQueue, Container, ViewCompiler) 
export class DynamicHtml { 
    @bindable() 
    public html: string; 

    public element: HTMLElement; 

    private tq: TaskQueue; 
    private container: Container; 
    private viewCompiler: ViewCompile; 

    private runtimeView: View; 
    private runtimeViewSlot: ViewSlot; 
    private runtimeViewFactory: ViewFactory; 
    private runtimeViewAnchor: HTMLDivElement; 

    constructor(element, tq, container, viewCompiler) { 
     this.element = <HTMLElement>element; 
     this.tq = tq; 
     this.container = container; 
     this.viewCompiler = viewCompiler; 
    } 

    public bindingContext: any; 
    public overrideContext: any; 
    public bind(bindingContext: any, overrideContext: any): void { 
     this.bindingContext = bindingContext; 
     this.overrideContext = overrideContext; 

     if (this.html) { 
      this.htmlChanged(this.html, undefined); 
     } 
    } 

    public unbind(): void { 
     this.disposeView(); 

     this.bindingContext = null; 
     this.overrideContext = null; 
    } 

    public needsApply: boolean = false; 
    public isAttached: boolean = false; 
    public attached(): void { 
     this.runtimeViewAnchor = this.element.firstElementChild; 

     this.isAttached = true; 
     if (this.needsApply) { 
      this.needsApply = false; 
      this.apply(); 
     } 
    } 

    public detached(): void { 
     this.isAttached = false; 

     this.runtimeViewAnchor = null; 
    } 

    private htmlChanged(newValue: string, oldValue: void): void { 
     if (newValue) { 
      if (this.isAttached) { 
       this.tq.queueMicroTask(() => { 
        this.apply(); 
       }); 
      } else { 
       this.needsApply = true; 
      } 
     } else { 
      if (this.isApplied) { 
       this.disposeView(); 
      } 
     } 
    } 

    private isApplied: boolean = false; 
    private apply(): void { 
     if (this.isApplied) { 
      this.disposeView(); 
     } 

     this.compileView(); 
    } 

    private disposeView(): void { 
     if (this.runtimeViewSlot) { 
      this.runtimeViewSlot.unbind(); 
      this.runtimeViewSlot.detached(); 
      this.runtimeViewSlot.removeAll(); 
      this.runtimeViewSlot = null; 
     } 

     if (this.runtimeViewFactory) { 
      this.runtimeViewFactory = null; 
     } 

     if (this.runtimeView) { 
      this.runtimeView = null; 
     } 

     this.isApplied = false; 
    } 

    private compileView(): void { 
     this.runtimeViewFactory = createViewFactory(this.viewCompiler, this.container, this.html); 

     this.runtimeView = createView(this.runtimeViewFactory, this.container); 

     this.runtimeViewSlot = createViewSlot(this.runtimeViewAnchor); 
     this.runtimeViewSlot.add(this.runtimeView); 
     this.runtimeViewSlot.bind(this.bindingContext, this.overrideContext); 
     this.runtimeViewSlot.attached(); 

     this.isApplied = true; 
    } 

} 

function createViewFactory(viewCompiler: ViewCompiler, container: Container, html: string): ViewFactory { 
    if (!html.startsWith("<template>")) { 
     html = `<template>${html}</template>`; 
    } 
    let viewResources: ViewResources = container.get(ViewResources); 
    let viewFactory = viewCompiler.compile(html, viewResources); 
    return viewFactory; 
} 

function createView(viewFactory: ViewFactory, container: Container): View { 
    let childContainer = container.createChild(); 
    let view = viewFactory.create(childContainer); 
    return view; 
} 

function createViewSlot(containerElement: Element): ViewSlot { 
    let viewSlot = new ViewSlot(containerElement, true); 
    return viewSlot; 
}