Reza Shirazi
Reza Shirazi

Reputation: 381

knockout template observable not working when passing value to inner template

I am rendering a template that accepts an observable array and inside, it uses an inner template to render the content of a property as input text. If I directly render input text in the "foreach" in the parent then any changes to the text are two-way binding and reflected in the related observable array item property but when using the inner template it becomes one way.

--========== Parent template =======--

  <div class="skill-rating-section" data-bind="foreach: { data: skills, as: 'skill' }">
        <div class="col-comment">

            **<!-- This works fine - two way bdinding -->**
            <input type="text" data-bind="value:skill.Comment" />

            **<!-- This renders the content but is not two way binding -->**
            <skill-rating-comment params="viewModel:skill"></skill-rating-comment>
        </div>
    </div>

--===== Html for inner template(SkilRatingCommentTemplate.html)====

<input type="text" data-bind="value:comment" />

--======= Js code for inner template ================

define('SkillRating/Component/SkilRatingCommentComponent', ['knockout'], function (ko) {
    function skillRatingCommentViewModel(params) {
        var me = this;     
        me.comment = params.viewModel.Comment;
        return me;
    }
    ko.components.register('skill-rating-comment', {
        viewModel: skillRatingCommentViewModel,
        template: {
            require: 'text!../../Content/HtmlTemplate/SkillAssessmentComponent/SkilRatingCommentTemplate.html'
        }
    });
});

Upvotes: 0

Views: 445

Answers (1)

Philip Bijker
Philip Bijker

Reputation: 5115

This actually seems to work. Have a look at the snippet below. I updated the HTML a bit to emphasize the outer and the inner (component) binding and changed the value binding to a textInput binding to immediately see the changes in the related observable.

function skillRatingCommentViewModel(params) {
  var me = this;
  me.comment = params.viewModel.Comment;
  return me;
}

ko.components.register('skill-rating-comment', {
  viewModel: skillRatingCommentViewModel,
  template: '<p>Inner <input type="text" data-bind="textInput:comment" /></p>'
});

ko.applyBindings({
  skills: ko.observableArray([{
    Comment: ko.observable('Comment 1')
  }, {
    Comment: ko.observable('Comment 2')
  }])
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div class="skill-rating-section" data-bind="foreach: { data: skills, as: 'skill' }">
  <div class="col-comment">
    <p>Outer <input type="text" data-bind="textInput:skill.Comment" /></p>
    <skill-rating-comment params="viewModel:skill"></skill-rating-comment>
  </div>
  <hr/>
</div>

Upvotes: 1

Related Questions