У меня простая разметка HTML со списком моих моделей просмотра в ней и шаблоном. Кроме того, у меня есть свой ViewModel в <pre>
разделе:Наблюдаемые режимы просмотра в наблюдаемом массиве не работают в KnockoutJs
<div class="container">
<div class="row">
<div class="col-md-6">
<div class="col-md-12">
<div class="panel panel-primary">
<div class="panel-heading">
Names
<button type="button" class="btn btn-link" data-bind="click: addName">
<span class="glyphicon glyphicon-plus"></span>
</button>
</div>
<div class="panel-body">
<ul class="list-group" id="namesList" data-bind="foreach: Names">
<li class="list-group-item"><my-comp></my-comp></li>
</ul>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="col-md-12">
<pre data-bind="text: ko.toJSON(Names, null, 2)"></pre>
</div>
</div>
</div>
</div>
<script type="text/html" id="fullNameTmpl">
<p>First name: <strong data-bind="text: firstName"></strong></p>
<p>Last name: <strong data-bind="text: lastName"></strong></p>
<p>First name: <input data-bind="textInput: firstName" /></p>
<p>Last name: <input data-bind="textInput: lastName" /></p>
<p>Full name: <input data-bind="textInput: fullName"></p>
<button data-bind="click: capitalizeLastName">Go caps</button>
</script>
<script>
function AppViewModel() {
var self = this;
self.firstName = ko.observable("Bert");
self.lastName = ko.observable("Bertington");
this.fullName = ko.pureComputed({
read: function() {
return self.firstName() + " " + self.lastName();
},
write: function (value) {
var lastSpacePos = value.lastIndexOf(" ");
if (lastSpacePos > 0) {
self.firstName(value.substring(0, lastSpacePos));
self.lastName(value.substring(lastSpacePos + 1));
}
},
owner: self
});
self.capitalizeLastName = function() {
var currentVal = this.lastName();
this.lastName(currentVal.toUpperCase());
};
}
ko.components.register('my-comp', {
viewModel: AppViewModel,
template: { element: "fullNameTmpl" }
});
function NamesViewModel() {
var self = this;
self.Names = ko.observableArray();
self.addName = function() {
var vm = ko.observable(new AppViewModel());
self.Names.push(vm);
}
}
ko.applyBindings(new NamesViewModel());
</script>
Это хорошо работает, я могу добавить элемент в список и связывания данных в этих пунктов работает. Когда я добавляю новый AppViewModel
, я могу видеть его в разделе <pre>
, в Names
массив. Проблема в том, что когда я изменяю некоторые значения в вложенной среде просмотра, например, набирая новую фамилию, независимо от того, нет изменений в разделе <pre>
в текущей модели просмотра в массиве Names
.
Как я могу сделать действительно наблюдаемый массив наблюдаемых? Какой самый выгодный способ добавить такие компоненты? Я уже сделал вложенную viewmodel наблюдаемой, но, похоже, она не работает.
Я думаю, что проблема здесь в том, что нокаута observableArray обрабатывает массив себя как obversable, уведомляя о событиях, как толчок и удалить, но не известит, если одно свойство из элемента в массиве изменения. Я уверен, что вы останетесь самим реализовать это (в документах есть «ключевой момент», который очень кратко упоминает об этом - http://knockoutjs.com/documentation/observableArrays.html) –
@NickDeFazio, но в 'addName', я добавляю' ko.observable', этого недостаточно? –