gpt4 book ai didi

knockout.js - 是否有可能在渲染完成之前打破 ko foreach 绑定(bind)?

转载 作者:行者123 更新时间:2023-12-04 03:15:22 25 4
gpt4 key购买 nike

这是我在 SO 上的第一篇文章,所以请放轻松 :)

我正在使用 Durandal.js 构建一个 Web 应用程序,并且我有一种情况,我正在运行一个简单的 knockout foreach 数据绑定(bind),该数据绑定(bind)遍历 ko.observableArray 并为数组中的每个项目组成 subview 。该数组由我想在页面上呈现的多个 subview / View 模型组成,但该数组一次可以包含大量项目(有时超过 400 个)。该应用程序还可以有多页结果,当单击新页面时,我通过替换 ko.observableArray 的内容来处理分页。

我偶尔遇到的问题(不是每次,但它是可重复的)是我收到了由 knockout.js 引发的错误(我正在运行 knockout v3.0.0),它显示以下内容:“未捕获的 TypeError:无法读取 null 的属性 'insertBefore'。

这是 knockout.js 的 virtualElements 的 prepend 方法的一部分,它抛出了错误:

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

在挖掘 knockout 代码后,我可以看到被称为 null 的是 containerNode.parentNode。在我下面的 html 代码片段中,containerNode.parentNode 是#photosContainer,所以我觉得奇怪的是它是 null,因为 foreach 显然仍在运行(因为我收到每个尚未渲染的项目的错误) )。

以下是我的 durandal 应用程序中的一些代码片段:
我的 View 中的 html 代码,其中包含迭代“照片”observableArray 并组成 subview 的 foreach 绑定(bind):
<div id='photosContainer' data-bind="visible: !video_mode_on(), foreach: photos">
<!-- ko compose: $data --><!--/ko-->
</div>

这是来自我的 View 模型的代码,它基本上替换了“照片”observableArray 的内容:
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 );
});
};

当我在 foreach 绑定(bind)完成在我的 View 中运行之前导航到另一页结果时,我提到的错误似乎发生了。所以我的问题是:有没有办法在我的 View 中停止或中断 foreach 绑定(bind),以便我可以导航到另一页结果而不必等待当前结果列表呈现?

还有一些我尝试过但没有帮助的事情:我最初删除了照片数组的所有内容,然后在运行我的 getPhotos() 函数时直接插入它,但认为错误可能是由空数组。在迭代我的 getPhotos() 函数中的 rawPhotos() 数组之前,我还尝试在 #photosContainer 上运行 knockout 的 ko.virtualElements.emptyNode() 函数,以查看这是否会清空 View 的 foreach 绑定(bind)中未完成的渲染,但是那似乎也没有做任何事情。我尝试使用检查函数包装我的 compose 绑定(bind),以查看 #photosContainer 节点是否存在,如下所示:
<div id='photosContainer' data-bind="visible: !video_mode_on(), foreach: photos">
<!-- ko if: $parent.checkForPhotosContainer() -->
<!-- ko compose: $data --><!--/ko-->
<!-- /ko -->
</div>

和检查功能:
newHome.prototype.checkForPhotosContainer = function() {
var self = this;

var el = $(self.element).find('#photosContainer');

if( el.length ) {
return true;
} else {
return false;
}
};

到目前为止,没有任何工作,我的想法(和头发!!)已经用完了。任何帮助将不胜感激!

最佳答案

似乎没有办法阻止或突破ko foreach正如 Magnus Ahlin 指向 How to short circuit Array.forEach like calling break? 的链接所指出的那样绑定(bind),但是我的问题的根本原因实际上与我使用虚拟元素而不是普通元素有关。

对于遇到 knockout 问题并提示“未捕获的类型错误:无法读取 null 的属性 'insertBefore'”并使用虚拟元素在 ko.observableArray 中使用 foreach 组成 subview 的任何人绑定(bind),尝试用普通元素替换你的虚拟元素。

因此,在您的 View 中替换 html 代码,类似于:

<div data-bind="foreach: myObservableArray">
<!-- ko compose: $data --><!--/ko-->
</div>

像这样:
<div data-bind="foreach: myObservableArray">
<div data-bind="compose: $data"></div>
</div>

关于knockout.js - 是否有可能在渲染完成之前打破 ko foreach 绑定(bind)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27510831/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com