thitemple
thitemple

Reputation: 6059

Understanding how nested components binding works on KnockoutJS

I'm trying to use knockout components, and one thing I'm trying to use is nested components like this:

<parent-component params="parentText: parentText">
    <child-component params="childText: childText"></child-component>
  </parent-component>

parentText and childText are both members of the same view model object, but when I run this I get the following error:

Uncaught ReferenceError: Unable to process binding "template: function (){return { nodes:$componentTemplateNodes} }" Message: childText is not defined

This a sample that I'm trying to run:

var ParentComponent = function(params) {
  var self = this;
  self.parentText = params.parentText;
};

ko.components.register('parent-component', {
  viewModel: ParentComponent,
  template: '<div><p><strong data-bind="text: parentText"></strong></p><!-- ko template: { nodes: $componentTemplateNodes } --><!-- /ko --></div>'
})

var ChildComponent = function(params) {
  var self = this;
  self.childText = params.text2;
};

ko.components.register('child-component', {
  viewModel: ChildComponent,
  template: '<p data-bind="text: childText"></p>'
})

var ViewModel = function() {
  var self = this;
  self.title = 'KnockoutJS component test';
  self.parentText = 'This is the text1';
  self.childText = 'This is the text2';
};

ko.applyBindings(new ViewModel(), document.getElementById('content'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div id="content">
  <h1 data-bind="text: title"></h1>
  <parent-component params="parentText: parentText">
    <child-component params="childText: childText"></child-component>
  </parent-component>
</div>

Can anyone please explain to me what I'm doing wrong?

Thanks,

Upvotes: 2

Views: 470

Answers (1)

Adrian
Adrian

Reputation: 1587

Your doing good. I can see 2 problems here though.

First:

$componentTemplateNodes is not seen in this case because your using knockout 3.2 in which this is not being supported yet, so you better update your lib to the newer one, knockout 3.4 is already out but $componentTemplateNodes support starts at 3.3.

Second:

In your ChildComponent vm you referred params text2

self.childText = params.text2;

But when you declared it in your html binding, it was names as childText.

<child-component params="childText: childText"></child-component>

And also take note that <child-component params="childText: childText"></child-component> is enclosed in an inner component so childText cannot be seen here, so you shoud refer it as $root.childText.

To sum up: Binding should be.

<parent-component params="parentText: parentText"> <child-component params="childText: $root.childText"></child-component> </parent-component>

And ChildComponent vm should be:

self.childText = params.childText;

Upvotes: 1

Related Questions