billpull/knockout-bootstrap

Context is lost with popover in a loop

Closed this issue · 5 comments

I am having 2 issues while using the popover binding in a loop.

example

      <ul data-bind="foreach: {data: planList, as: 'plan'}">
        <li>
          <!-- remove a tag and displays fine x of n -->
          <a data-toggle="popover" data-bind="popover: {template: 'plan-template', options: {title: '', placement: 'top'}}">
              <span data-bind='text: plan.net'></span> of <span data-bind='text: plan.my'></span>
          </a>
        </li>
      </ul>

      <script type="text/html" id="plan-template">
          <div class="list-group">
              <!-- what is the context here??? can not read property 'mine' of undefined -->
              <div data-bind="foreach: $root.mine">
                <a class="list-group-item" data-bind="">
                  <span data-bind="text: $data.name"></span></a>
              </div>
          </div>
      </script>
var vm = function(params) {

  this.planList = [
    {my: 0, net: 3},  
    {my: 2, net: 3},  
    {my: 1, net: 3}
  ]

  this.mine = [
    {name: 'fred'},
    {name: 'barney'}
  ]
}

ko.applyBindings(vm)

First issue is the display x of n in the example, if I remove the popover binding, the display is correct. I have tried many variations but can not find a context that will keep the display.

The second issue is when I select an item to show the popover, I get an error Cannot read property 'mine' of undefined, any help identifying the context here would be appreciated

The second issue has been solved by adding withProperties to the binding.

The first issue seems to be beyond context, see here. A simple expression data-bind='text: 1+2' does not get evaluated.

@rsbondi I don't currently work a lot on this project or knockout in general but would love an updated example in the docs to address this issue if you have the time to put together a PR.

I have a solution, make the controlsDescendantBindings an option, my example works if set to false. If I do the following, it should keep the same default behavior but give the option

      var options = popoverBindingValues.options || {
        title: 'popover',
        controlDecendents: true
      };
...

      return {
        controlsDescendantBindings: typeof options.controlDecendents == 'undefined' ? true : options.controlDecendents
      };

I can PR this change, but I am curious why the default of true?

working example

Not sure this was originally built with Knockout 2 so that could have had different behavior. Bindings inside of popovers is one of the more challenging cases within this plugin.

I will PR, maybe next week when I get back home.