Aurelia js 为 popover 主体提供动态内容

标签 aurelia

我正在按照 Sean Hunter Blog 的结构来实现工具提示.现在我想提供工具提示内容作为动态 html 内容,即我想在内容中显示一个 html 模式。我如何提供使用 Aurelia 框架。在使用自定义绑定(bind)处理程序的 Knockout JS 中,我提供的内容与部门 ID 一样,如下面的代码所示。

敲除结构是

 <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>

如何使用 Aurelia Structure 实现同样的效果:

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

最佳答案

您需要在自定义属性中实现 Bootstrap 的其余 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 Grant 评论的回应。如果为此使用自定义元素,它可以提高清晰度。我不确定他想到的实现方式,但这将是一种在不真正失去灵 active 的情况下使其发挥作用的方法。

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

关于Aurelia js 为 popover 主体提供动态内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39951980/

相关文章:

javascript - 没有 eval() 就无法启动 Aurelia 应用程序

aurelia - 确定是否在提示中作为对话框打开

javascript - Aurelia - 应用程序初始化 - 临时禁用属性更改通知

aurelia - aurelia 中的 .bind 与字符串插值

自定义元素内部的 Aurelia 自定义元素和共享变量

javascript - 无法从客户端应用程序引用插件中定义的静态方法

javascript - Aurelia辅助注入(inject)?

javascript - 如何从头开始设置最小的 Aurelia 项目

javascript - 当 customElements 加载时从 activate() 返回 Promise

javascript - 如何在内联定义的 HTML 中调用 onclick