如何绑定到Knockout中自定义bindingHandler中的自定义模板

时间:2017-08-02 12:31:14

标签: twitter-bootstrap knockout.js

我需要生成一个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的{​​{1}}节点内,因此在绑定中我允许将td作为container传递给body Bootstrap需要为表中的Popovers提供此功能:

<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 HoursboundTemplate只是为了看到有东西进入那里。

绑定中的Number(TotalTime()).toFixed(2)变量在其中包含完整的html和ko代码。我似乎需要通过某种处理方法运行它,将content: boundTemplate转换为某个值。以ArrayList<Leaderboardmodel> leaderboard= gson.fromJson(json, type); 的形式输入到popover中。

1 个答案:

答案 0 :(得分:0)

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

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