8

I know this isn't a good method to use long term, but for troubleshooting, is there any way I can pass a simple string while binding a template and then access it as a variable within the template? For instance, if this was my binding:

<!-- ko template: { name: tmplOne }, myvar: 'apple' -->

and this was tmplOne:

<div>
    <span>Fruit: </span>
    <span data-bind="text: myvar"></span>
</div>

It would result in the folowing:

fruit: apple

Even if I have to declare an observable in the viewmodel called "fruit", can I manually set it at template binding?

4 Answers4

7

Use

<!-- ko template: { name: tmplOne, templateOptions: {myvar: 'apple'} } -->

More here: http://www.knockmeout.net/2011/03/quick-tip-reusing-template-by-passing.html

Ainsof
  • 124
  • 1
  • 1
  • How is this different than the accepted answer? What is the difference between/advantages of `templateOptions` vs `data`? –  Jun 05 '15 at 13:14
  • I think this is the correct approach for this problem, don't know why it's downvoted. – Zoltán Tamási Jan 11 '16 at 10:09
  • @DevilsAdvocate The underlying viewmodel and a render-time template parameter are two different things. The accepted answer messes with the viewmodel and introduces a new binding context while you asked for a simple render-time parameter, keeping the binding context tree untouched (if I understood correctly).. – Zoltán Tamási Jan 11 '16 at 10:15
  • 1
    Unfortunately `templateOptions` is no longer supported – sad comrade Apr 24 '17 at 20:25
5

You can supply a data parameter to the template binding and define an object literal if you want just like you are doing:

<!-- ko template: { name: tmplOne }, myvar: 'apple' -->

instead do this:

<!-- ko template: { name: tmplOne, data: { myvar: 'apple' } } -->

http://knockoutjs.com/documentation/template-binding.html

Organiccat
  • 5,633
  • 17
  • 57
  • 104
  • and then I access it using "myvar" just as I did in my example? –  Dec 06 '13 at 18:32
  • Wait, reading the docs you just linked, does this mean if I include the data object it will overwrite the currently applied viewmodel? –  Dec 06 '13 at 18:33
  • You'll be accessing the $parent or $root objects in order to get the 'myvar' object. – Organiccat Dec 06 '13 at 18:34
  • Sorry, I'm having trouble understanding. Now all my existing bindings don't work. How can I pass the existing object AND specify the custom variable? eg, data: { $data, myvar: 'apple' } –  Dec 06 '13 at 18:40
  • 1
    I figured you were defining the viewmodel on your template page already. In which case you'd use the model as normal and access 'myvar' as previously shown. If that doesn't work, you can also try adding a 'myvar' to your viewmodel object on your template page (and then access it as normal). A last try would be just passing your object with the other variable as you just suggested, but I don't think that should be necessary. data: { mydata: mydataobject, myvar: 'apple' } – Organiccat Dec 06 '13 at 19:18
  • I obviously am fairly new to KO and templating both, so I appreciate your patience and help. I have a POC coming up soon which is why I'm trying to hack it for now :\, ultimately I'll figure out a way to do it right :) –  Dec 06 '13 at 19:23
  • You technically answered my question, and I have made progress, so I went ahead and accepted your answer. –  Dec 06 '13 at 19:23
1

For people reading on later versions of knockout, this would appear to be a good usecase for components vs templates.

Ryan Leach
  • 4,262
  • 5
  • 34
  • 71
1

You can pass arbitrary data to a template, while maintaining the currently applied viemodel, by supplying a composition to the data parameter of the binding.

You could for example wrap the template content in a with binding, bound to the composed $data property, creating a new binding context. This way, the currently applied bindings don't need to be updated.

ko.applyBindings({
  fruits: ['banana', 'orange']
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

<div data-bind="template: { name: 'tmplOne', data: { myModelData: $data, myVar: 'apple' } }"></div>

<script type="text/html" id="tmplOne">
  <!-- ko with: myModelData -->
    <span>My model</span>
    <ul data-bind="foreach: fruits">
      <li data-bind="text: $data"></li>
    </ul>
    <div>
      <span>My custom data:</span>
      <span data-bind="text: $parent.myVar"></span>
    </div>
  <!-- /ko -->
</script>
Philip Bijker
  • 4,955
  • 2
  • 36
  • 44