gpt4 book ai didi

javascript - 如何在 marrionete.js 中构建调用链渲染 itemView,并使用 itemView 内的异步函数进行延迟

转载 作者:行者123 更新时间:2023-11-28 07:20:55 25 4
gpt4 key购买 nike

我的结构非常简单

ProductsList.TileListView = Marionette.CollectionView.extend({
tagName: 'section',
className: 'b-list-viewtile',
template: '/static/js/app/list/modules/productslist/templates/tileList',
childView: ProductsList.TileItemView

});



ProductsList.TileItemView = Marionette.ItemView.extend({
tagName: "article",
className: "b-list-viewtile__item",
template: '/static/js/app/list/modules/productslist/templates/tileItem',
_getImage: function(){

var _this = this;

var img = new Image();
img.src = this.model.get("media");
img.onload = function(){
msnry.append( _this.$el )
.masonry( 'appended', _this.$el ).masonry('layout');
};
}
});

但我使用 Masonry 插件来对齐网格上的项目。

问题是,对于每个项目,我需要知道变量的值,例如图像的高度。

这意味着构建每个 itemView 我只能将前一个项目附加到 DOM 中。

维护集合中的顺序也很重要 - 集合中的第一个应该首先渲染,等等。

花了很多时间研究文档但没有找到优雅的解决方案

有人能告诉我如何构建那个“链”吗?每个项目都必须等待先前渲染,但最终结果顺序必须保持在集合中,而不是图像加载优先级中。

我认为这是关于 defered+marrionette.callback 并覆盖 native AttachHtml 或 buildChildView

非常感谢:)

最佳答案

我们将使用 Marionette 内置的 Marionette.Babysitter 和 ES6 Promises 来解决您的问题。

如果您阅读 docs仔细(或浏览源代码)您将了解到 Marionette 按集合顺序呈现 subview 。

By default the CollectionView will maintain the order of its collectionin the DOM.

此外,所有 CollectionView 还将按照其渲染顺序保存对其所有 subview 的引用,这也是按照其集合排序顺序。

您想要的是确保所有 subview 都已渲染,然后添加该 subview el到您的砌体项目列表,按顺序

首先,设置您的 Promise

我们将修改您的 subview 的 ._getImage稍微修改一下方法,并让它返回一个 Promise:

_getImage: function(){
var _this = this;
return new Promise(function (resolve, reject) {
var img = new Image();
img.src = this.model.get("media");
img.onload = function(){
resolve();
};
});
}

当加载此任意 subview 的图像时, getImage 返回的 promise 将得到解决。这对我们有什么帮助?继续阅读。

其次,等待所有图像加载完毕

在您的 CollectionView 中,您将添加此属性 onRenderCollection ,当所有 subview 完成渲染时,Marionette 会触发该事件。在这里,使用 Babysitter,我们将解雇 _getImage方法,并设置您正在寻找的 Masonry promise 链。

onRenderCollection: function () {
var promises = [];
this.children.each(function (childview) {
promises.push(childview._getImage()); // return the promise
})
// When all your children view's images have loaded we begin to fill Masonry
Promise.all(promises).then(_.bind(function () {
this.children.each(function (childview) {
childview.addToMasonry();
}
}, this))
}

第三,添加到 Masonry!

当然,我们还没有名为 addToMasonry 的属性你 child 的观点,但我假设你会使用一个看起来很像你的img.onload上的东西打回来。像这样的事情

addToMasonry: function () {
masonry.append( this.$el )
.masonry( 'appended', this.$el ).masonry('layout');
}

缺点

使用此方法的一个警告是,您首先必须等到所有 subview 都渲染完毕。如果列表很长(超过 1000 个),这可能是一个性能问题,并且解决方法可能并不简单。

关于javascript - 如何在 marrionete.js 中构建调用链渲染 itemView,并使用 itemView 内的异步函数进行延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30330178/

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