Новый экземпляр модели представления Durandal, все еще отражающий предыдущие значения.
-
21-12-2019 - |
Вопрос
Я столкнулся со странной проблемой при тестировании немного сложного сценария композиции с использованием дюрандаля.
Я хочу динамически составлять содержимое каждой ячейки таблицы.В качестве примера у меня есть следующие файлы:
Welcome.html => содержит код для динамического отображения таблицы HTML.
<table>
<thead>
<tr data-bind="foreach: columnNames">
<th><span data-bind="text: $data"></span>
</th>
</tr>
</thead>
<tbody data-bind="foreach: items">
<tr data-bind="foreach: $parent.columnNames">
<!-- <td data-bind="text: $parent[$data]"></td>-->
<td data-bind="compose: { model: $root.activeView($index), activationData: $root.activationData($parentContext.$index), cacheViews: false }"></td>
</tr>
</tbody>
</table>
Welcome.js => соответствующая модель представления
define(['knockout'], function (ko) {
var ctor = function () {
var m_items = [{
'Name': 'John',
'Age': 25
}, {
'Name': 'Morgan',
'Age': 26
}];
this.items = ko.observableArray(m_items);
this.columnNames = ko.computed(function () {
if (m_items.length === 0)
return [];
var props = [];
var obj = m_items[0];
for (var name in obj)
props.push(name);
return props;
});
this.activeView = function (index) {
if (index() == 0)
return "viewmodels/cell-1";
else
return "viewmodels/cell-2";
};
this.activationData = function (rowIndex) {
return m_items[rowIndex()];
}
};
return ctor;
});
cell-1.html => представление для отображения для первого столбца
<span data-bind="text : Name"></span>
cell-1.js => соответствующая модель представления для ячейки-1
define(['knockout'], function (ko) {
var model = null;
var name = ko.observable();
var ctr = function () {
this.Name = name;
this.activate = function (modelObject) {
model = modelObject;
name(model.Name);
};
};
return ctr;
});
И аналогично представление и модель представления для ячейки-2.
Проблема, с которой я столкнулся, заключается в том, что, хотя композиция работает нормально и функция активации вызывается дважды для ячейки-1.js (по одному разу для каждой строки), значение наблюдаемой name
будет содержать предыдущее значение.(т.е.значение будет «Джон», когда оно попытается установить его на «Морган»).Это странно, поскольку cell-1.js возвращает конструктор, и, следовательно, Durandal должен был создать еще один экземпляр модели представления.Подводя итог, это приводит к тому, что обе строки содержат одни и те же данные.
Я уверен, что есть что-то незначительное, что мне нужно настроить, чтобы заставить его работать, но все мои усилия были напрасны.
Любая помощь будет принята с благодарностью.
Решение
Проблема в том, что вы заявили о своем model
и name
переменные на уровне модуля в вашем cell-1.js
.
Таким образом, даже если вы вернете конструктор, который вызывается дважды, сам модуль загружается только один раз, поэтому ваши модели представления имеют одно и то же состояние.
Чтобы решить эту проблему, вам просто нужно переместить переменные внутри ctr
:
define(['knockout'], function (ko) {
var ctr = function () {
var model = null;
var name = ko.observable();
this.Name = name;
this.activate = function (modelObject) {
model = modelObject;
name(model.Name);
};
};
return ctr;
});