Backbone.Marionette - 连接页面操作的最佳方式

时间:2013-10-03 01:37:32

标签: marionette

我们正在使用牵线木偶,我们正在为$(document).ready()函数中的模板中的元素进行布线操作。我想知道是否有一种首选的方法 - 即将其移入模型或应用程序范围内的某个位置。

简化示例

<script type="text/template" id="menu">
    <a href="javascript:void(0)" class="index-link">
</script>


MyApp.module("Entities", function (Entities, MyApp, Backbone, Marionette, $, _) {
    Entities.MenuModel = Backbone.Marionette.Model.extend({});
});

MyApp.module("Views", function (Views, QaApp, Backbone, Marionette, $, _) {
    Views.MenuView = Backbone.Marionette.ItemView.extend({
        template: "#menu"
    });
});

$(document).ready(function() {

    $(window).load(function() {
      $("html, body").animate({ scrollTop: $(document).height() }, 750);
    });

    $(".index-link").on("click", function(e) {
        $.ajax({
            url: "/someurl",
            type: 'POST',
            contentType: 'application/json; charset=utf-8',
            success: function (result) {
                if (result.Status == false)
                    console.warn(result.Message); 
            },
            error: function (result) {
                console.warn(result.Message); 
            }
        });
    });
});

在这个例子中,我可以看到窗口滚动功能与我的模型无关,所以看起来没问题,但是我的模板中的元素触发的动作不应该在相关视图中,特别是如果成功函数可能会返回我的模型需要的数据吗?

感谢您的期待!

1 个答案:

答案 0 :(得分:0)

您需要了解您的Marionette / Backbone实体所承担的不同职责。责任通常遵循这些实体自然可用的信息类型。

在您的特定情况下,这意味着DOM事件必须由包含这些DOM元素的视图处理。关于你的$('.index-link'),你必须先转换成Marionette.View的实例。您可以通过Marionette.ItemView / CollectionView / CompositieView或Marionette.Regions这样做,它们本身可以成为Marionette.Layout的一部分。

无论如何,你的第一个实现必须是,这个逻辑必须在视图中处理,而不是模型。因为只有视图知道DOM。该模型甚至不知道DOM是什么......

示例

看起来与我刚刚告诉你的相反,我会将“视图逻辑”写入集合中。但是,请考虑一下,我在视图的上下文中执行“视图逻辑”,而不是模型/集合!!

var app = new Marionette.Application;

// your dom contains a <nav /> element in its body
app.addRegions({nav: 'nav'});

app.addInitializers( function () {

    // collection containing nav links + the 'target', i.e. an onClick handler
    var NavLinksCollection = new Backbone.Collection([
        {
            title: 'Link 1',
            onClick: function (event) {
                // your ajax request
                // this will be executed in the context of the view
                // so you will have access to the Marionette.ItemView instance, with the element attached etc
                // also, you have access to the model data, via the view's model property, i.e. `this.model`
                // also to the collection the model belongs to, via this.model.collection
                // finally, the event object is also available
            }
        },
        {
            title: 'Link 2'
        }
    ]);

    var NavView = Marionette.CollectionView.extend({
            itemView: Marionette.ItemView.extend({
                template: function (model) {
                    // maybe model is already serialized, then access via model.title
                    return $('<button>' + model.get('title') + '</button>');
                },
                events: {
                    'click': function (event) {
                        // see, although the actual code of the onClick event is contained in the collection, we execute that code in the context of the view, effectively making it code 'of' the view
                        this.model.get('onClick').call(this, event);
                    }
                }
            }),
            collection: NavLinksCollections
        });

    app.nav.show(new NavView);

});

app.start();