Маршрутизация и события — backboneJS

Как я должен обрабатывать маршрутизацию в 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;
    }
});

Я думаю, что это первый сценарий, учитывая, что магистраль управляется событиями, но во втором явно меньше кода.

Кроме того, я полагаю, что третий сценарий будет состоять в том, чтобы сохранить код представления в первом сценарии, но захватить сценарий маршрутизатора второго... визуализация представления при навигации, но раскрытие события на случай, если я захочу вызвать это в другом месте.

Мысли?


person Scott Silvi    schedule 21.12.2012    source источник


Ответы (2)


Таким образом, все основные вопросы обычно заканчиваются многими правдоподобными ответами. В этом случае я считаю, что ваш второй пример является более каноническим/типичным магистральным шаблоном. Если оставить в стороне сложную проблему загрузки счетчиков и обновления после загрузки данных, упрощенный базовый шаблон в вашем маршрутизаторе будет таким:

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);
}

Я думаю, что это образец учебника. Опять же, вопрос о том, кто инициирует выборку данных и повторную визуализацию после их поступления, является сложным. Я думаю, что лучше всего, если представление знает, как отображать «загружаемую» версию самого себя до тех пор, пока модель не извлечет данные, а затем, когда модель запускает событие изменения после завершения выборки, представление повторно отображает себя с загруженными данными модели. Однако некоторые люди могут поместить эту логику в другое место. Эта статья о создании следующего звукового облака, я думаю, представляет многие очень хорошие «современные» магистральные шаблоны, в том числе то, как они обрабатывают невыбранные модели.

В общем, вы можете кодировать вещи с обратными вызовами или событиями по своему усмотрению. Тем не менее, хорошее эмпирическое правило — задать себе несколько вопросов:

  1. Будет ли реагировать на это событие более чем одна независимая логическая часть работы?
  2. Нужно ли отделять источник этого события от того, что происходит в ответ на него?

Если оба варианта «да», то события должны подойти. Если оба варианта «нет», то лучше подходит прямая логика функций. В случае «переход по этому URL-адресу запускает это представление», как правило, ответ на оба вопроса «нет», поэтому вы можете просто закодировать эту логику в методе обработчика маршрута маршрутизатора и покончить с этим.

person Peter Lyons    schedule 21.12.2012
comment
Я думаю, что еще одна вещь, о которой следует подумать, это то, кто должен знать о ком. т.е. должен ли маршрутизатор знать о представлении, или представление должно знать о маршрутизаторе (или ни то, ни другое)? В этом случае я бы предпочел, чтобы маршрутизатор знал о представлении, а не наоборот, поскольку маршрутизатор подобен глобальному объекту, а представление должно управлять только представлением и моделью, связанными с представлением (и, возможно, подвидами). В сценарии (1) представление должно было знать о событиях, инициированных маршрутизатором, что не имеет смысла. В сценарии 2 маршрутизатор знает о представлении, но представление не знает о маршрутизаторе, и это нормально. - person hajpoj; 22.12.2012
comment
(к вашему сведению, я уезжаю на остаток года. У меня не было времени потреблять / тестировать и помечать как ответ) - person Scott Silvi; 22.12.2012

Я бы использовал второй сценарий. Не вижу никаких преимуществ использования первого подхода. Это имело бы больше смысла таким образом (но все же спорно):

/* ... */
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). События довольно мощные, но я бы не использовал их, если мне это действительно не нужно.

person rinat.io    schedule 21.12.2012
comment
Я бы сказал, что ваши глобальные события здесь являются точной копией событий маршрутизатора, которые у нас уже есть, и добавляют сложности без какой-либо пользы. - person Peter Lyons; 22.12.2012
comment
Я согласен с тобой Петр. На мой взгляд, этот код просто имеет больше смысла, чем первый подход, описанный Скоттом (особенно если у него нет триггера события в обратном вызове успеха выборки). Я бы вообще использовал его второй сценарий. - person rinat.io; 22.12.2012
comment
(к вашему сведению, я уезжаю на остаток года. У меня не было времени потреблять / тестировать и помечать как ответ) - person Scott Silvi; 22.12.2012