durandal viewmodel的新实例仍然反映了以前的值

时间:2014-01-09 06:03:28

标签: knockout.js durandal-2.0

在使用durandal尝试稍微复杂的构图场景时,我遇到了一个奇怪的问题。

我想动态组合表格的每个单元格的内容。例如,我有以下文件:

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 =&gt;相应的视图模型

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 =&gt;视图显示第一列

<span data-bind="text : Name"></span>

cell-1.js =&gt; cell-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的视图和视图模型。

我面临的问题是,即使组合工作正常,并且为cell-1.js调用了两次activate函数(每行一次),observable name的值将包含先前的值(即当它试图将其设置为“摩根”时,该值将为“John”)。这很奇怪,因为cell-1.js返回一个构造函数,因此durandal应该创建另一个视图模型实例。总而言之,这会导致两个行都包含相同的数据。

我确信有一些小问题需要调整才能让它发挥作用,但我所有的努力都是徒劳的。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

问题是您已在model的模块级别声明了namecell-1.js个变量。

所以即使你返回一个被调用两次的构造函数,模块本身只加载一次,所以你的viewmodels共享相同的状态。

要解决此问题,您只需将变量移到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;
});