Batman
Batman

Reputation: 6373

How to bind more than 1 property to element?

I'm playing around with knockout and I can't figure out how do I bind more than 1 object property to an element?

This is my template and I tried data-bind="text: name.first name.last":

<script type="text/html" id="person-template">
    <h3 data-bind="text: name.first name.last"></h3>
    <p>Age: <span data-bind="text: age"></span></p>
    <p>Company: <span data-bind="text: company"></span></p>
    <hr>
</script>

In angular I'd use ng-repeat and do something like <h3>{{name.first}} {{name.last}}</h3>but I don't want to load angular for this project

Upvotes: 0

Views: 91

Answers (1)

Jeroen
Jeroen

Reputation: 63830

Like this:

<h3 data-bind="text: name.first + ' ' + name.last"></h3>

or this, if those items are observables:

<h3 data-bind="text: name.first() + ' ' + name.last()"></h3>

or this, if you want to keep things seperate in your view:

<h3 data-bind="with: name">
  <span data-bind="text: first"></span>
  <span data-bind="text: last"></span>
</h3>

or this, if you want to mimick Angular as close as possible:

<h3>
  <!-- ko text: name.first --><!-- /ko -->
  <!-- ko text: name.last --><!-- /ko -->
</h3>

or this, if you want to unit test / make it into business logic:

<h3 data-bind="text: name.fullname"></h3>
function Name() {
  var self = this;
  self.first = ko.observable();
  self.last = ko.observable();
  self.fullname = ko.computed(function() {
    return self.first() + " " + self.last();
  });
}

As a footnote, some relevant differences between KnockoutJS and AngularJS:

  • In Knockout there is (without plugins) no direct equivalent of the AngularJS bracket style (e.g. {{ name.first}}) rendering.
  • In KnockoutJS observable properties are functions (whereas Angular can track changes to plain JS properties). You can only (optionally) leave off parentheses if it's the only thing you're binding to. So supposing first is an observable, these work:

    <span data-bind="text: name.first"></span> shortcut...
    <span data-bind="text: name.first()"></span> equivalent to previous...
    <span data-bind="text: name.first() + name.last()"></span> () are required now...
    

    but this doesn't:

    <span data-bind="text: name.first + 'something else'"></span> !doesn't work!
    

Upvotes: 5

Related Questions