0

我们正在使用木偶,我们正在为 $(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); 
            }
        });
    });
});

在此示例中,我可以看到窗口滚动功能与我的模型无关的位置,所以看起来没问题,但我的模板中的元素触发的操作不应该在相关视图中,尤其是如果成功功能可能返回我的模型需要的数据?

感谢您的关注!

4

1 回答 1

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();
于 2013-10-08T11:00:44.513 回答