【问题标题】:How to Bind to a Custom Template within a Custom bindingHandler in Knockout如何在 Knockout 的自定义 bindingHandler 中绑定到自定义模板
【发布时间】:2018-01-09 16:30:11
【问题描述】:

我需要生成一个 Bootstrap Popover。我找到了一两篇文章,但在我的情况下,它们似乎没有 100% 有效。我可以让 Popover 显示,但是模板中的绑定没有被绑定。

这是我的自定义bindingHandler:

ko.bindingHandlers.popover = {
  init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
    var $element = $(element);
    var attribute = ko.utils.unwrapObservable(valueAccessor());
    var placement = attribute.placement || "top";
    var trigger = attribute.trigger || "click";
    var template = attribute.template;
    var container = attribute.container || false;
    var boundTemplate = $(template).html();

    $element.popover({
      container: container,
      placement: placement,
      trigger: trigger,
      html: true,
      content: boundTemplate
    });

    ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
      $element.popover("destroy");
    });
  }
};

html 在table 的td 节点内,因此在绑定中我允许container 以body 的形式传入,因为Bootstrap 需要这个表中的弹出框:

<span class="bottom-right faded"
      data-toggle="popover"
      title="Weekly Breakdown:"
      data-trigger="hover"
      data-bind="text: Number(PayPeriodTime()).toFixed(2), css: { 'less-hours': HasRequiredHours() === false, 'requirement-met': (HasRequiredHours() && WorkDays() > 0) }, popover: { template: '#weekly-template', placement: 'left', container: 'body', trigger: 'hover' }"></span>

最后,这是我的自定义模板:

<script type="text/html" id="weekly-template">
  <pre data-bind="text: ko.toJSON($data, null, 2)"></pre>
  <table class="table table-bordered">
    <tr>
      <td>Full Weeks Hours</td>
      <td data-bind="text: Number(TotalTime()).toFixed(2)">5</td>
    </tr>
    <tr>
      <td>Required Hours</td>
      <td data-bind="text: Number(RequiredHours()).toFixed(2)"></td>
    </tr>
    <tr>
      <td>Entered Hours</td>
      <td data-bind="text: Number(PayPeriodTime()).toFixed(2)"></td>
    </tr>
    <tr>
      <td>Remaining Needed</td>
      <td data-bind="text: Number(RequiredHours() - PayPeriodTime()).toFixed(2)"></td>
    </tr>
  </table>
</script>

pre 元素似乎是空的,无论我在那里放什么。当弹出窗口出现在hover 上时,它会呈现 html,但不会呈现我的 ko 项目。我看到的只是5,我强行输入Full Weeks Hours,只是为了看看有什么东西进来了。

绑定中的boundTemplate 变量在其中包含完整的html 和ko 代码。我似乎只需要通过某种处理方法来运行它,这将在将Number(TotalTime()).toFixed(2) 放入某个值之前将其放入弹出为content: boundTemplate。

【问题讨论】:

  • 请发布正确答案,并将该答案标记为已接受。
  • @NisargShah 我已将解决方案移至答案。在 2 天内(当我被允许时)我会将其标记为答案。
  • 太棒了。谢谢!

标签: twitter-bootstrap knockout.js


【解决方案1】:

与同事交谈后,这是解决方案(注意以 // 为前缀的 cmets):

ko.bindingHandlers.popover = {
  init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
    var $element = $(element);
    var attribute = ko.utils.unwrapObservable(valueAccessor());
    var placement = attribute.placement || "top";
    var trigger = attribute.trigger || "click";
    var template = attribute.template;
    var container = attribute.container || false;

    var rawTemplate = $(template).html(); // Updated code
    var boundContent = $("<div></div>"); // New code
    boundContent.html(rawTemplate); // New code

    ko.applyBindings(bindingContext, boundContent.get(0)); // New code

    $element.popover({
      container: container,
      placement: placement,
      title: title,
      trigger: trigger,
      html: true,
      content: boundContent // Updated code
    });

    ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
      $element.popover("destroy");
    });
  }
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-31
    • 1970-01-01
    • 1970-01-01
    • 2014-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多