当前位置: 动力学知识库 > 问答 > 编程问答 >

javascript - Duplicate elements when cleaning and re-applying bindings with child viewModels

问题描述:

I have a viewModel containing child viewModels in an observableArray that is bound to some markup using a foreach binding.

Later in the page life cycle, I need to remove the old viewModel and apply a new one in its place. I do this by calling ko.cleanNode() and then calling applyBindings with the new view model.

For some reason when this happens, all of the child view models end up getting duplicated markup even though the parent observableArray has the correct number of viewModels in it.

I am sure I am just using some knockout functionality incorrectly, but I cannot figure out how to get it working.

Issue is replicated here: http://jsfiddle.net/a7xLxwxh/

Markup:

<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);

网友答案:

Later in the page life cycle, I need to remove the old viewModel and apply a new one in its place.

The better way to replace the view-model is to make the view-model itself an observable:

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

ko.applyBindings(vm);

Then when you want to replace it:

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

See Fiddle

网友答案:

Use the with binding in order to swap out view models. cleanNode is an undocumented method.

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

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

分享给朋友:
您可能感兴趣的文章:
随机阅读: