【问题标题】:Routing & events - backboneJS路由和事件——backboneJS
【发布时间】:2012-12-21 20:10:39
【问题描述】:

我应该如何在 BackboneJS 中处理路由?路由时,在更新我的视图后,我应该触发事件还是直接渲染视图?

以下是两种情况:

触发事件:

routes: {
    'orders/view/:orderId' : 'viewOrder'
},
viewOrder: function (orderId) {
    var viewOrderView = new ViewOrderView();
    vent.trigger('order:show', orderId);
}

在我看来,我有:

var ViewOrderView = Backbone.View.extend({
    el: "#page",
    initialize: function () {
        vent.on('order:show', this.show, this);
    },
    show: function (id) {
        this.id = id;
        this.render();
    },
    render: function () {
        var template = viewOrderTemplate({ id: this.id });
        this.$el.html(template);
        return this;
    }
});

或者,我应该走这条路吗:

routes: {
    'orders/view/:orderId' : 'viewOrder'
},
viewOrder: function (orderId) {
    var viewOrderView = new ViewOrderView({id : orderId });
    viewOrderView.render();
}

在我看来,我有:

var ViewOrderView = Backbone.View.extend({
    el: "#page",
    initialize: function () {
        //init code here
    },
    render: function () {
        var template = viewOrderTemplate({ id : this.id});
        this.$el.html(template);
        return this;
    }
});

认为这是第一个场景 - 鉴于主干是事件驱动的,但第二个显然有更少的代码。

另外,我想第三种情况是将视图代码保留在第一种情况中,但抓住第二种情况的路由器情况...在导航上渲染视图,但如果我想触发它​​,则公开一个事件其他地方。

想法?

【问题讨论】:

    标签: backbone.js backbone-routing


    【解决方案1】:

    因此,所有主干问题通常都会得到许多看似合理的答案。在这种情况下,我相信您的第二个示例是更规范/典型的主干模式。撇开处理加载微调器和数据加载后更新的棘手问题不谈,路由器中简化的基本模式是:

    routes: {
        'orders/view/:orderId' : 'viewOrder'
    },
    
    viewOrder: function (orderId) {
        //Use models to represent your data
        var orderModel = new Order({id: orderId});
        //models know how to fetch data for themselves given an ID
        orderModel.fetch();
        //Views should take model instances, not scalar model IDs
        var orderView = new OrderView({model: orderModel});
        orderView.render();
        //Exactly how you display the view in the DOM is up to you
        //document.body might be $('#main-container') or whatever
        $(document.body).html(orderView.el);
    }
    

    我认为这是教科书的模式。同样,谁触发数据的获取并在数据到达后重新呈现的问题是棘手的。我认为最好是视图知道如何呈现自身的“加载”版本,直到模型获取数据,然后当模型在获取完成后触发更改事件时,视图会使用加载的模型数据重新呈现自身。但是,有些人可能会将这种逻辑放在别处。 This article on building the next soundcloud 我认为代表了许多非常好的“最先进”主干模式,包括它们如何处理未获取的模型。

    通常,您可以根据自己的喜好使用回调或事件编写代码。但是,一个好的经验法则是问自己一些问题:

    1. 是否会有多个独立的逻辑工作来响应此事件?
    2. 我是否需要将此事件的来源与响应事件发生的事情分离?

    如果这两个都是“是”,那么事件应该很合适。如果两者都是“否”,那么简单的函数逻辑更合适。在“导航到这个 URL 触发这个视图”的情况下,通常这两个问题的答案都是“否”,所以你可以把这个逻辑编码到路由器的路由处理方法中并完成它。

    【讨论】:

    • 我认为要考虑的另一件事是“谁应该知道谁”。即路由器应该知道视图,还是视图应该知道路由器(或两者都不知道)?在这种情况下,我会使用路由器应该知道视图,反之亦然,因为路由器就像一个“全局”对象”,并且视图应该只管理与视图关联的视图和模型(可能还有子视图) .在场景(1)中,视图必须知道路由器触发的事件,这没有意义。在场景2中,路由器知道视图,但视图不知道路由器,这很好
    • (仅供参考今年余下时间。没有时间消费/测试并标记为答案)
    【解决方案2】:

    我会使用第二种情况。看不到使用第一种方法的任何好处。这样会更有意义(但仍有争议):

    /* ... */
    routes: {
        'orders/view/:orderId' : 'viewOrder'
    },
    viewOrder: function (orderId) {
        vent.trigger('order:show', orderId);
    }
    /* ... */
    vent.on('order:show', function(orderId) {
        var viewOrderView = new ViewOrderView();
        viewOrderView.render();
    });
    
    var ViewOrderView = Backbone.View.extend({
        el: "#page",
        initialize: function (options) {
            this.orderId = options.orderId;
        },
    
        render: function () {
            var template = viewOrderTemplate({ 
                id: this.orderId 
            });
            this.$el.html(template);
            return this;
        }
    });
    

    这样至少您可以在不更新 url 的情况下触发路由操作。但是使用Backbone.router.viewOrder(1) 可能会达到相同的效果。事件非常强大,但如果我真的不需要,我不会使用它们。

    【讨论】:

    • 我认为您的全局事件与我们已经拥有的路由器事件完全相同,并增加了复杂性而没有任何好处。
    • 我同意你的观点,彼得。在我看来,这段代码比 Scott 描述的第一种方法更有意义(特别是如果他在获取成功回调中没有事件触发)。我一般会使用他的第二种情况。
    • (仅供参考今年余下时间。没有时间消费/测试并标记为答案)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多