在MarionetteJS ComspositeView中创建一个包装器

时间:2014-03-12 12:24:42

标签: javascript jquery backbone.js grid marionette

您好亲爱的SO用户和贡献者。我不确定如何使用基于BackboneJS的JS框架MarionetteJS来操作compositeViews。希望有人能够就如何继续给我一些建议。

应用程序上下文:我正在构建的应用程序是一个可以接受可拖动项目的GRID。正在使用两个 CompositeView 来构建此网格,以在页面部分中构建行,并为每个实际表示在其上的字段构建 ItemView 网站。

应用程序视图:我拥有一个gridView,它有一个gridModel集合,可以在initialize方法中分割成多行。这会在HTML中生成一个部分,它将保存GRID。 gridRowView将从所有gridItems为gridView构建中的每一行生成一个带有“day”类的div。

  

有人提到,在之前关于我的GRID的问题中,treeView可能更适合于此目的。但我觉得这与我的问题范围无关。

planboard.gridItemView = Backbone.Marionette.ItemView.extend({
    model: planboard.gridModel,
    collection: planboard.gridCollection,
    template: "#grid-item-template",
    onShow: function() {
        //code to plan dropped orders
    }
});
planboard.gridRowView = Backbone.Marionette.CompositeView.extend({
    template: "#grid-row-template",
    itemView: planboard.gridItemView,
    itemViewContainer: "div.day",
    initialize: function() {
        this.collection = new Backbone.Collection(_.toArray(this.model.attributes));
    }
});
planboard.gridView = Backbone.Marionette.CompositeView.extend({
    template: "#grid-template",
    itemView: planboard.gridRowView,
    tagName: "section",
    initialize: function() {
        var grid = this.collection.groupBy(function(list, iterator) {
            return Math.floor(iterator / collums); // 4 == number of columns
        });
        this.collection = new Backbone.Collection(_.toArray(grid));
    }
});

应用程序模板:

<!-- Grid templates -->
<script type="text/template" id="grid-item-template">
    <div class="gridItem droppable" id="{{cid}}"><b>{{data}}</b></div>
</script>

<script type="text/template" id="grid-row-template">
    <div class="day"></div>
</script>

<script type="text/template" id="grid-template">
    <section></section>
</script>

问题:下面的代码(减去事件包装器)类似于DOM中的结构化代码。如您所见,视图会生成预期结果。然而,我需要使用定位在GRID上放置项目。为此,我在部分(GRID的开头)周围开始使用div容器。

虽然这样可行,但一旦引入滚动条,这就成了问题。由于GRID的起始位置没有实际改变,您可以向下滚动,但订单将始终保持在屏幕上的相同位置。

可能的解决方案:观看Google日历我意识到他们在行内部使用了额外的事件包装器进行定位。这对我来说似乎是合乎逻辑的,因为从那时起确定位置的偏移将不再是你的GRID的开始,而是行的开始(类'day')。这应该可以解决滚动条可能造成的问题。

在我看来,这看起来像下面的代码:

<section>
<div> <!-- wrapper generated by framework -->
<div class="day">
    <div class="event-x"> <!-- used as offset for positioning -->
       <div id="c39" class="gridItem droppable"> <!-- grid column --></div>
    </div>
</div>
<div>
</section>

我的问题:由于我的行(带有'day'类的div)是由MarionetteJS CompsositeView自动生成的,我无法给它一些独特的值来识别它并没有改变。拥有一个带有唯一标识符的附加事件包装器很可能会解决我的问题,因为那时我可以使用JQuerySelectors来获取该元素的定位。

然而...... Marionette实际上为我生成了包装器,我不确定如何在此行中添加一个独特的包装器。你们中的任何人(有MarionetteJS或Backbone的经验)有任何想法如何解决这个问题吗?

我是否正朝着正确的方向前进?任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

如果您只需要为View生成的包装器分配唯一的ID /类,则以下答案可能有所帮助。注意,它实际上没有任何额外的包装器,它只是将属性添加到自动生成的包装器。

您可以定义View的属性(或任何扩展它的属性,例如CompositeView)。这些属性将自动分配给包装器元素。您可以在extendfunction or hash

中定义它们

如果您只需要静态标识符,请使用第一种方法:

planboard.gridRowView = Backbone.Marionette.CompositeView.extend({
    template: "#grid-row-template",
    itemView: planboard.gridItemView,
    itemViewContainer: "div.day",
    id: "some-id",
    initialize: function() {
        this.collection = new Backbone.Collection(_.toArray(this.model.attributes));
    }
});

如果您需要根据模型生成ID,请使用第二种方法:

planboard.gridRowView = Backbone.Marionette.CompositeView.extend({
    template: "#grid-row-template",
    itemView: planboard.gridItemView,
    itemViewContainer: "div.day",
    attributes: function() {
        return {
            id: this.model.get("id") // or something like this
        };
    },
    initialize: function() {
        this.collection = new Backbone.Collection(_.toArray(this.model.attributes));
    }
});