I have a situation where I would like to stop the rendering of a foreach binding in my view when the underlying ko observableArray that it is iterating through is updated. Is this possible?
To expand on why I'm trying to do this, in my Durandal.js app I have run into a situation where I am iterating over a large (up to 400 or more) list of items and creating a child view/viewmodel for each item. These child views can take a while to render and there are pages of results to show. If I want to skip to the next page of results I am running into an error (similar to this one: (
https://groups.google.com/forum/#!searchin/knockoutjs/containerNode.parentNode/knockoutjs/LNU_MrdGmDU/L1zou71YyzMJ) where the console is outputting: "Uncaught TypeError: Cannot read property 'insertBefore' of null". In this case the
containerNode.parentNode is null. The error is being thrown in knockout.js's virtualElements 'prepend' method:
prepend: function(containerNode, nodeToPrepend) {
if (!isStartComment(containerNode)) {
if (containerNode.firstChild) containerNode.insertBefore(nodeToPrepend, containerNode.firstChild);
else containerNode.appendChild(nodeToPrepend);
} else {
// Start comments must always have a parent and at least one following sibling (the end comment)
containerNode.parentNode.insertBefore(nodeToPrepend, containerNode.nextSibling);
}
},
I think that this issue is being caused because when I am navigating to the next page of results I am replacing the observableArray with a new set of results, but the current set of results has not finished running through the foreach loop in my view. Here is a bit of my code to help clarify:
From my html (view), this is a block of code that is bound to the photos observableArray in my viewmodel and is running ko compose on each item in the array
<div id='photosContainer' data-bind="visible: !video_mode_on(), foreach: photos">
<!-- ko compose: $data --><!--/ko-->
</div>
From my javascript (viewmodel), this is the function that is used to replace the contents of the photos observableArray being bound to in the html (view)newHome.prototype.getPhotos = function() {
var self = this;
var defs = [];
var arr = [];
var args, newArr;
self.rawPhotos().forEach( function( set ) {
defs.push( self.some_more_all( set.mf, set.images ) );
});
$.when.apply($, defs).done(function( res ) {
args = Array.prototype.slice.call(arguments, 0);
newArr = args.sort();
newArr.forEach( function( set ) {
set.arr.forEach( function( p ) {
arr.push( self.addPhoto( p, self.mfOwnedByViewer( set.mf ) ? { ownedByViewer: true } : { ownedByViewer: false, owner_uuid: set.mf.owner_uuid } ) );
});
});
self.photos( arr );
});
};
Any ideas on what I can do to avoid this error would be greatly appreciated! I have spent hours trying to come up with a solution, but have yet to come up with anything.
Thank you for any ideas/input you can provide!
Jesse