2016-10-10 8 views
2

Sean Hunter Blogからツールチップを実装する構造に従っています。今では、ツールチップのコンテンツを動的なHTMLコンテンツとして提供したい、つまりコンテンツ内に1つのhtmlパターンを表示したい。 Aureliaフレームワークの使用方法を教えてください。ノックアウトJSカスタムバインディングハンドラを使用して私は以下のコードのような部門のIDのようにコンテンツを提供しています。Aurelia jsはpopover本体に動的コンテンツを提供します

ノックアウト構造オーレリア構造と同じ達成するためにどのように

<button data-bind="tooltip: { template: 'ElementId', trigger: 'click', placement: 'right', container: 'body' }">Click Me</button> 

    <div id="ElementId" style="display: none;"> 
     <div>Dynamic content will go here</div> 
    </div> 

です:

<template> 
<require from="templates/popover/tooltip"></require> 
<button data-toggle="tooltip" tooltip="placement:bottom;trigger:click;html:true;template:'ElementId';title:tooltip Header">Click Me</button> 

<div id="ElementId" style="display: none;"> 
      <div>Dynamic content will go here</div> 
     </div> 

</template> 

カスタム属性コード

import {customAttribute, inject, bindable} from 'aurelia-framework'; 
import $ from 'bootstrap'; 

@customAttribute('tooltip') 
@inject(Element) 
export class Tooltip { 
    element: HTMLElement; 
    @bindable title: any; 
    @bindable placement: any; 
    @bindable content: any; 
    @bindable template: any; 

    constructor(element) { 
     this.element = element; 
    } 

    bind() { 
     if (this.content) { 
      $(this.element).tooltip({ title: this.title, placement: this.placement, content: this.content }); 
     } 
     else { 
      $(this.element).tooltip({ title: this.title, placement: this.placement, template: $('#'+this.template).html() }); 
     } 


    } 

    // gets fired when the provided value changes, although not needed in this example since the json from reddit is static 
    titleChanged(newValue) { 
     $(this.element).data('bs.tooltip').options.title = newValue; 
    } 
    contentChanged(newValue) { 
     if (this.content) { 
      $(this.element).data('bs.tooltip').options.content = newValue; 
     } 
     else { 
      $(this.element).data('bs.tooltip').options.template = newValue; 
     } 
    } 
    placementChanged(newValue) { 
     $(this.element).data('bs.tooltip').options.placement = newValue; 
    } 
} 
+0

@Sean Hunter:これを達成する方法を教えてください。 – Rayudu

+0

カスタム属性コードを入力してください。 – James

+0

@James:後半は申し訳ありませんが、カスタム属性要素のコードを見てください。 – Rayudu

答えて

6

残りのブートストラップのpopover APIをカスタム属性に実装し、セレクタをテンプレートにするロジックを追加する必要があります。

はここに例を示しますhttps://gist.run?id=909c7aa984477a465510abe2fd25c8a1

注:私は、カスタム属性を持つ明瞭

ためbootstrap popoversからデフォルト値を追加しました:

のsrc/app.html

<template> 
    <h1>${message}</h1> 

<button class="btn btn-block btn-default" popover="title.bind: message; placement: top">Default popover</button> 
<button class="btn btn-block btn-default" popover="title.bind: message; template-selector: #popoverTemplate; placement: bottom; html: true">Custom popover</button> 

<div id="popoverTemplate"> 
    <div class="popover" role="tooltip"> 
    <div class="arrow"></div> 
    <h3 class="popover-title"></h3> 
    <div>Some custom html</div> 
    </div> 
</div> 
</template> 

のsrc /カスタム要素と

export class App { 
    message = "Hello world"; 
} 

のsrc/popover.ts

import {inject, customAttribute, bindable, DOM} from "aurelia-framework"; 

@customAttribute("popover") 
@inject(DOM.Element) 
export class Popover { 
    public element: HTMLElement; 

    constructor(element) { 
    this.element = element; 
    } 

    @bindable({defaultValue: true}) 
    public animation: boolean; 

    @bindable({defaultValue: false}) 
    public container: (string | false); 

    @bindable({defaultValue: 0}) 
    public delay: (number | object); 

    @bindable({defaultValue: false}) 
    public html: boolean; 

    @bindable({defaultValue: "right"}) 
    public placement: (string | Function); 

    @bindable({defaultValue: false}) 
    public selector: (string | false); 

    @bindable({defaultValue: `<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>`}) 
    public template: string; 

    @bindable({defaultValue: false}) 
    public templateSelector: (string | false); 

    @bindable({defaultValue: ""}) 
    public title: (string | Function); 

    @bindable({defaultValue: "click"}) 
    public trigger: string; 

    @bindable({defaultValue: { selector: "body", padding: 0 }}) 
    public viewport: (string | Object | Function); 

    public attached(): void { 
    let template; 

    if (this.templateSelector) { 
     const templateElement = document.querySelector(this.templateSelector); 
     template = templateElement.innerHTML; 
    } else { 
     template = this.template; 
    } 

    $(this.element).popover({ 
     animation: this.animation, 
     container: this.container, 
     delay: this.delay, 
     html: this.html, 
     placement: this.placement, 
     selector: this.selector, 
     template: template, 
     title: this.title, 
     trigger: this.trigger, 
     viewport: this.viewport 
    }); 
    } 
} 

をapp.ts:

これは@Ashleyグラントさんのコメントに反応しています。このためにカスタム要素を使用すると、明快さが向上する可能性があります。彼が考えていた実装についてはわかりませんが、柔軟性を失うことなく機能させるための1つの方法です。

SRC/app.html

<template> 
    <h1>${message}</h1> 

<popover-element title.bind="message" placement="bottom"> 
</popover-element> 
<popover-element title.bind="message" placement="bottom"> 
    <button slot="popoverTarget" class="btn btn-block btn-default"> 
    Custom popover (custom element) 
    </button> 
    <div slot="popoverTemplate" class="popover" role="tooltip"> 
    <div class="arrow"></div> 
    <h3 class="popover-title"></h3> 
    <div>Some custom html</div> 
    <div>Message: ${message}</div> 
    </div> 
</popover-element> 

</template> 

SRCは/

export class App { 
    message = "Hello world"; 
} 

SRC /ポップオーバー-element.html app.ts

<template> 
    <div ref="target"> 
    <slot name="popoverTarget"> 
     <button class="btn btn-block btn-default">Default popover (custom element)</button> 
    </slot> 
    </div> 
    <div ref="template"> 
    <slot name="popoverTemplate"> 
     <div class="popover" role="tooltip"> 
     <div class="arrow"></div> 
     <h3 class="popover-title"></h3> 
     <div class="popover-content"></div> 
     </div> 
    </slot> 
    </div> 
</template> 

のsrc /ポップオーバー-element.ts

import {customElement, bindable} from "aurelia-framework"; 

@customElement("popover-element") 
export class PopoverElement { 
    public template: HTMLElement; 
    public target: HTMLElement; 

    @bindable({defaultValue: true}) 
    public animation: boolean; 

    @bindable({defaultValue: false}) 
    public container: (string | false); 

    @bindable({defaultValue: 0}) 
    public delay: (number | object); 

    @bindable({defaultValue: false}) 
    public html: boolean; 

    @bindable({defaultValue: "right"}) 
    public placement: (string | Function); 

    @bindable({defaultValue: false}) 
    public selector: (string | false); 

    @bindable({defaultValue: ""}) 
    public title: (string | Function); 

    @bindable({defaultValue: "click"}) 
    public trigger: string; 

    @bindable({defaultValue: { selector: "body", padding: 0 }}) 
    public viewport: (string | Object | Function); 

    public attached(): void { 

    $(this.target.firstElementChild).popover({ 
     animation: this.animation, 
     container: this.container, 
     delay: this.delay, 
     html: this.html, 
     placement: this.placement, 
     selector: this.selector, 
     template: this.template.firstElementChild.outerHTML, 
     title: this.title, 
     trigger: this.trigger, 
     viewport: this.viewport 
    }); 
    } 
} 
+0

偉大な答えですが、正直なところ、これはおそらく属性ではなくカスタム要素としてうまくいくでしょう、と思いませんか? –

+0

ポイントがあるかもしれませんが、「より良い」と定義してください。私はそれがプロジェクトの大きな写真にかかっていると思う。セマンティック的な観点から、カスタム要素は読みやすく/使用することができます。 **カプセル化**の場合、メンテナンス性が向上します。私は通常、マークアップの制約が少ないと感じているので、サードパーティのコンポーネントをカスタム属性で統合する方が好きで、複数のビヘイビアを重ねるのが簡単です。 –

+0

@AshleyGrant私の最新の編集を見てください、これはあなたがカスタム要素のために思いついたことですか? –

0

あなたはこのラインテンプレートから '.outerHTML' を削除することができます。これ。template.firstElementChild.outerHTML、テンプレート:this.template.firstElementChild、モデルバインディングを取得します。

関連する問題