Выделите выбранный элемент обратными вызовами магистрального маршрутизатора. - PullRequest
5 голосов
/ 10 февраля 2012

Макет приложения

У меня есть приложение с боковой панелью , которая содержит много элементов, и main div, который отображает эти элементы.Существует также простая модель Backbone.Router, ItemsCollection и Item.У меня есть SidebarView для боковой панели и ShowView для отображения выбранного элемента.

                  +-------------------------+
                  | http://app.de/#/show/3  |   <-- Current URL
                  +-------------------------+
                  | Sidebar | Main          |
                  |---------+---------------|
                  | Item 1  |               |
 SidebarView -->  |---------|    Display    |
                  | Item 2  |    Item  3    | <-- MainView handled by
                  |---------|    here       |          MainRouter
Selected Item --> | Item 3 *|               |
                  +---------+---------------+

При запуске я инициализирую SidebarView и MainRouter.SidebarView присоединяет свой метод render к событию ItemCollection#all.Я также присоединяю событие ItemCollection#refresh к Backbone.history.start(), затем извлекаю ItemCollection.

$(function() {
  window.router = new App.MainRouter;
  window.sidebar = new App.SidebarView;
  ItemCollection.bind("reset", _.once(function(){Backbone.history.start()}));
  ItemCollection.fetch();
});

Проблема

Я хочу выделить текущий выбранный элемент.Это работает путем привязки события route.show к маршрутизатору:

# I removed all code which is not necessary to understand the binding
class SidebarView extends Backbone.View
  el: ".sidebar"

  initialize: () ->
    window.router.bind 'route:show', @highlight_item

  # The route is routed to #/show/:id, so I get the id here
  highlight_item: (id) ->
    $(".sidebar .collection .item").removeClass("selected")
    $("#item-" + id).addClass("selected")

Это прекрасно работает, когда я выбираю элемент при загрузке приложения.Но когда страница загружается с #/show/123 в качестве URL-адреса, элемент не выделяется.Я запустил отладчик и обнаружил, что боковая панель еще не отображается при вызове обратного вызова highlight_item.

Возможные решения

Есть ли способ переупорядочить привязки, чтобысобытие Item#refresh сначала вызывает SidebarView#render, а затем запускает маршрутизацию?

Может быть, есть обходной путь, который просто берет текущий маршрут из window.router (я не нашел никакого метода в Backbone Docs) и выделяетЭлемент, когда его визуализируют?

Или моя инициализация просто глупа, и я должен обрабатывать вещи по-другому?

1 Ответ

5 голосов
/ 10 февраля 2012

Вы можете сделать две вещи:

  1. highlight_item может отслеживать, какой элемент должен быть выделен.
  2. Обновите render, чтобы инициализировать выделенный элемент.

Примерно так:

initialize: () ->
  @highlighted_id = null
  window.router.bind 'route:show', @highlight_item

render: () ->
  # Set everything up inside @el as usual
  @highlight_current()
  @

highlight_item: (id) =>
  @highlighted_id = id
  @highlight_current()

highlight_current: () ->
  return unless(@highlighted_id)
  $(@el)
    .find('.selected').removeClass('selected')
    .end()
    .find("#item-#{@highlighted_id}").addClass('selected')

Итак, до тех пор, пока вызывается highlight_item, highlight_current также будет вызываться с соответствующим набором @highlighted_id, и все должно получиться.

...