2016-10-10 14 views
2

我正在按照結構實現工具提示Sean Hunter Blog。現在我想提供工具提示內容作爲動態html內容,即我想在內容中顯示一個html模式。我如何提供使用Aurelia框架。在使用自定義綁定處理程序的基因敲除JS中,我提供了與下面的代碼一樣的分區標識的內容。Aurelia js向popover body提供動態內容

淘汰賽結構

<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/app.ts

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 
    }); 
    } 
} 

通過自定義元素:

這是響應@Ashley格蘭特的評論。如果您爲此使用自定義元素,它可以提高清晰度。我不確定他想到的實施情況,但這將是一種使其工作而不真正失去靈活性的方法。

的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/app.ts

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

的src /酥料餅-element.html

<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,以獲取模型綁定。