наблюдаемый шаблон нокаута не работает при передаче значения во внутренний шаблон

#templates #knockout.js #two-way-binding #knockout-templating

#шаблоны #knockout.js #двусторонняя привязка #нокаут-шаблонизация

Вопрос:

Я создаю шаблон, который принимает наблюдаемый массив, а внутри он использует внутренний шаблон для отображения содержимого свойства в виде входного текста. Если я напрямую отображаю входной текст в «foreach» в родительском файле, то любые изменения в тексте являются двусторонней привязкой и отражаются в соответствующем свойстве элемента observable array, но при использовании внутреннего шаблона он становится односторонним.

—========== Родительский шаблон =======—

   <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 для внутреннего шаблона (SkilRatingCommentTemplate.html )====

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

—======= Js-код для внутреннего шаблона ================

 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'
        }
    });
});
  

Ответ №1:

Похоже, это действительно работает. Взгляните на фрагмент ниже. Я немного обновил HTML, чтобы подчеркнуть внешнюю и внутреннюю (компонентную) привязку, и изменил привязку значения на привязку TextInput, чтобы сразу увидеть изменения в соответствующем наблюдаемом.

 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>  

Комментарии:

1. Привет, Филипп, спасибо за ответ. один вопрос здесь, у моих элементов массива есть больше свойств, а не только комментарий. Нужно ли мне делать каждое отдельное свойство наблюдаемым, если мне нужно иметь двустороннюю привязку? что здесь делает «observableArray»? И если я удалю наблюдаемый из комментария, почему он работает для внешнего ввода, но не для шаблона?

2. Короче говоря: an observableArray необходим для двусторонней привязки элементов, добавленных в массив или удаленных из него. Для observable каждого свойства одного элемента требуется двусторонняя привязка.