#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
каждого свойства одного элемента требуется двусторонняя привязка.