清理时重复元素并使用子视图模型重新应用绑定

时间:2015-08-17 15:58:23

标签: javascript knockout.js

我有一个viewStodel,它包含一个observableArray中的子viewModels,它使用foreach绑定绑定到某个标记。

在页面生命周期的后期,我需要删除旧的viewModel并在其位置应用一个新的viewModel。我这样做是通过调用ko.cleanNode()然后使用新的视图模型调用applyBindings。

出于某种原因,当发生这种情况时,即使父observableArray中包含正确数量的viewModel,所有子视图模型最终都会获得重复的标记。

我确信我只是错误地使用了一些淘汰赛功能,但我无法弄清楚如何让它发挥作用。

问题在此复制:http://jsfiddle.net/a7xLxwxh/

标记:

<div class="container">
    <label>RANGES</label>
    <div class="rangeContainer" data-bind="foreach: ranges">
        <div class="range"> 
            <span>START <br /><span data-bind="text: start"></span></span>
            <span>END <br /><span data-bind="text: end"></span></span>
        </div>
    </div>
</div>

JS:

var ParentViewModel = function (data) {
    var self = this;

    self.ranges = ko.observableArray([]);

    data.Ranges.forEach(function (range) {
        self.ranges.push(new RangeViewModel(range));
    });
};

var RangeViewModel = function (data) {
    var self = this;

    self.start = ko.observable(moment(data.Start).format('MM/DD/YYYY'));
    self.end = ko.observable(moment(data.End).format('MM/DD/YYYY'));
};

var vm = new ParentViewModel({
    Ranges: [{
        Start: '/Date(1439438400000)/',
        End: '/Date(1439611200000)/'
    },
    {
        Start: '/Date(1439265600000)/',
        End: '/Date(1439352000000)/'
    }]
});

var element = $('.container')[0];
ko.applyBindings(vm, element);

ko.cleanNode(element);
ko.applyBindings(vm, element);

2 个答案:

答案 0 :(得分:4)

  

在页面生命周期的后期,我需要删除旧的viewModel和   在它的位置申请一个新的。

替换视图模型的更好方法是使视图模型本身成为可观察的:

var vm = ko.observable(new ParentViewModel(
{
    Ranges: [{
        Start: '/Date(1439438400000)/',
        End: '/Date(1439611200000)/'
    },
    {
        Start: '/Date(1439265600000)/',
        End: '/Date(1439352000000)/'
    }]
}));

ko.applyBindings(vm);

然后当你想要替换它时:

vm(new ParentViewModel({
    Ranges: [{
        Start: '/Date(1439438400000)/',
        End: '/Date(1435611200000)/'
    }]
}));

请参阅localAdress

答案 1 :(得分:1)

使用with绑定来换出视图模型。 cleanNode是一种未记录的方法。

<div class="container" data-bind="with: viewModel">
    ...
</div>

http://jsfiddle.net/a7xLxwxh/3/