Новый экземпляр модели представления Durandal, все еще отражающий предыдущие значения.

StackOverflow https://stackoverflow.com//questions/21012712

  •  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;
});
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top