【问题标题】:Marionette - populating a set size collection with empty dataMarionette - 用空数据填充集合大小
【发布时间】:2015-03-17 19:31:50
【问题描述】:

我正在尝试填充一组列表,只使用一定数量的元素来指定需要添加到哪一行。

示例: 每个节点项都有一个对应于特定 UL 的数字以及要添加到哪个位置,但元素的“总”数量是已知的。

简化示例数据(假设预先确定的数组大小为 5):

nodes = new Entities.NodeCollection([
  { listID: 1, position: 2, name: "node2" },
  { listID: 1, position: 5, name: "node5" },
  { listID: 2, position: 4, name: "node4" }
]);

预期输出: 每个节点都插入到正确的位置,剩下的位置用空的 LI 填充。

<ul id="list1">
  <li></li>
  <li><div class="template-class" id="node2"></div></li>
  <li></li>
  <li></li>
  <li><div class="template-class" id="node5"></div></li>
</ul>
<ul id="list2">
  <li></li>
  <li></li>
  <li></li>
  <li><div class="template-class" id="node4"></div></li>
  <li></li>
</ul>

预期输出:

如何创建一个模板,让我将数据插入正确的位置并自动填充缺失的部分?

我可以使用 jQuery 轻松完成此操作,(预填充正确的长度并选择子项#)但我需要使用 Marionette/Backbone 来构建应用程序的事件管理和数据库查询端。

最坏的情况,循环遍历已知元素的能力并检查是否有应该去那里的数据点,根据需要填写正确的 html(或空的),但这看起来不像常见的 Marionette/Backbone 范例。

我认为我的实际行的模板是正确的;

<script type="text/template" id="node-list-item">
  <div class="template-class" id="<%- name %></div>
</script>

和意见:

RowView = Backbone.Marionette.ItemView.extend({
  tagName: "li",
  template: "#node-list-item"
  //something goes here to correctly handle empty pieces?
});

ListView = Backbone.Marionette.CompositeView.extend({
  itemView: RowView,
  itemViewContainer: "ul",
  //I don't think template implementation isn't important for this example
  template: "#list-layout"
});

我是不是搞错了,我应该在添加到集合之前修改数据集以包含空白部分? (如果是这样,我需要根据源数组项是否为空来切换模板,但这似乎是一种不同的蠕虫,具有过多的空数据点。)

最终,输出就像一个表格,但数据以列导向的方式结构化,我在尝试构建它时发现有点迷失方向。空行确保所有项目都排成一行,希望有助于在开发过程中进一步简化 jQuery 调用。

完整的预期输出示例 sn-p:

#main-content {
    background: #ccc;
    position: relative;
}
#iconrow {
    border-bottom: solid 1px #999
}
.col-xs-0 {
    width: 55px;
    padding: 0px;
    position: relative;
    float: left;
    min-height: 1px;
}
.icon {
    width: 100%;
    height: 0;
    padding-bottom: 99%;
    margin: 15px 0px;
    border-radius: 100%;
    border: 1px solid #999;
    background: white
}
.timeline {
    padding: 30px 0px;
    position: relative;
}
.timeline ul {
    padding: 0px;
    list-style: none;
    margin: 0px;
    position: relative;
}
.timeline li {
    position: relative;
    width: 100%;
    height: 50px;
    display: block;
}
.timeline li:before {
    width: 6px;
    height: 100%;
    margin-left: -3px;
    position: absolute;
    top: 0;
    left: 50%;
    display: block;
    background: #cc7264;
    content: ' ';
}
.timeline .node2 {
    width: 24px;
    height: 24px;
    margin-left: -12px;
    margin-top: 0px;
    z-index: 2;
    background: #eee;
    border: 4px solid #cc7264;
    position: absolute;
    left: 50%;
    top: -1px;
    border-radius: 100%;
}
.timeline .node2:hover {
    width: 48px;
    height: 48px;
    margin-left: -24px;
    margin-top: -12px;
    border-width: 6px;
}
.timeline .node2:active {
    width: 36px;
    height: 36px;
    margin-left: -18px;
    margin-top: -6px;
    background: #eebaa9;
    border-width: 6px;
}
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container" id="main-content">
	<div class="row clearfix">
		<div class="col-xs-0"></div>
		<div class="col-xs-2 timeline">
			<ul class="year y2014">
				<li> <div class="node2"></div></li>
				<li> </li>
				<li> </li>
				<li> <div class="node2"></div></li>
				<li> <div class="node2"></div></li>
				<li> </li>
				<li> <div class="node2"></div></li>
				<li> </li>
				<li> </li>
				<li> </li>
				<li> </li>
				<li> <div class="node2"></div></li>
			</ul>
			<ul class="year y2015">
				<li> <div class="node2"></div></li>
				<li> </li>
				<li> </li>
				<li> <div class="node2"></div></li>
				<li> <div class="node2"></div></li>
				<li> </li>
				<li> <div class="node2"></div></li>
				<li> </li>
				<li> </li>
				<li> </li>
				<li> </li>
				<li> <div class="node2"></div></li>
			</ul>
		</div>

		<div class="col-xs-2 timeline">
			<ul>
				<li> </li>
				<li> <div class="node2"></div></li>
				<li> <div class="node2"></div></li>
				<li> </li>
				<li> <div class="node2"></div></li>
				<li> </li>
				<li> </li>
				<li> </li>
				<li> <div class="node2"></div></li>
				<li> <div class="node2"></div></li>
				<li> </li>
				<li> </li>
			</ul>
		</div>

		<div class="col-xs-2 timeline">
			<ul>
				<li> </li>
				<li class="disabled"> <div class="node2"></div></li>
				<li class="disabled"> </li>
				<li class="disabled"> </li>
				<li class="disabled"> </li>
				<li class="disabled"> </li>
				<li class="disabled"> </li>
				<li class="disabled"> </li>
				<li class="disabled"> </li>
				<li class="disabled"> </li>
				<li class="disabled"> <div class="node2"></div></li>
				<li class="disabled"> </li>
			</ul>
		</div>

		<div class="col-xs-2 timeline">
			<ul>
				<li class="disabled"> <div class="node2"></div></li>
				<li class="disabled"> </li>
				<li class="disabled"> </li>
				<li class="disabled"> <div class="node2"></div></li>
				<li class="disabled"> <div class="node2"></div></li>
				<li class="disabled"> <div class="node2"></div></li>
				<li class="disabled"> <div class="node2"></div></li>
				<li class="disabled"> </li>
				<li class="disabled"> </li>
				<li class="disabled"> <div class="node2"></div></li>
				<li class="disabled"> </li>
				<li class="disabled"> <div class="node2"></div></li>
			</ul>
		</div>

	</div>
  </div>

谢谢!

【问题讨论】:

  • 您对用空“行”填充数据集的想法持开放态度吗?也就是说,在node1node4 之间,您将在集合中的索引1 和2 处包含一个空对象(或其他一些占位符变量)。 (注意,这不是稀疏数组)
  • 您可能需要一个布局视图和集合视图来填充多个ul
  • 理想情况下我不想存储空行,我只想从后端角度存储相关行。如果有一种方法可以欺骗数据在检索节点列表和传递到集合之间进行预填充,那可以工作。
  • 您可以预填充collection.parse 上的行。然后你必须使用View.getTemplate
  • 如果您希望我将其写成带有详细信息的答案,请告诉我

标签: javascript html backbone.js marionette dataformat


【解决方案1】:

我的解决方案最终是创建辅助函数来填充数据,并简化新模型的制作。

我首先创建节点模型的主集合,因此每个节点都获取主干 cID 和单个处理程序,然后我使用集合的“where”功能(来自 underscore.js)来获取匹配的节点数组群组。 nodeCollection.where({listID:1})

使用这个特定于列表的数组,我可以创建一个大小为 N 的空数组var emptyArray = Array(N),并在特定于列表的节点上创建一个简单的 foreach 循环,以用节点对象替换数组中的位置。 (注意:这个数组填充了“未定义”的对象)

for(node in nodeSublist){
  i=node.get("position")-1;//subtract 1 for 0-based array position
  emptyArray[i]=node;
}

使用这个填充的节点数组,我可以然后将该数组放入一个新的集合对象中。 new Entities.NodesCollection(paddedArray)。 Backbone 不会创建新的 Node 对象,因为它们已经被实例化了。

对于每个列表,我将这个新填充的 nodeCollection 设置为新“列表”模型中的属性。然后在列表的 CollectionView 中,我只是将视图的集合设置为模型中的节点列表,在 initialize: 传递。

initialize: function(){
    this.collection = this.model.get("nodes");
}

我可以创建这些列表模型的集合,现在我拥有了我需要的每个对象。 Lists 数组的简单 CollectionView 将输出一个容器并呈现每个 NodeList 视图。每个Nodelist都会输出UL,并在Node ItemView或Empty ItemView之间切换。

var NodeList = Marionette.CollectionView.extend({
    tagName: "ul",
    getChildView: function(node){
        //this is a real node
        if(node.get("name")){
            return List.NodeView;
        }
        //otherwise this node is empty, dont render anything
        else{
            return List.EmptyNodeView;
        }
    },
    initialize: function(){
        this.collection = this.model.get("nodes");
        //you cannot set the class on initialize, 
        //because the DOM object is created before the initialize function,
        //so use jquery.
        this.$el.addClass("list"+this.model.get("listID"));
    }
}

我们很好!

感谢@Seebiscuit 让我开始!

【讨论】:

    猜你喜欢
    • 2020-06-23
    • 2019-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-28
    • 2010-11-27
    • 1970-01-01
    • 2016-09-17
    相关资源
    最近更新 更多