使用骨干路由器回调突出显示所选项目

时间:2012-02-10 19:20:57

标签: javascript jquery javascript-events backbone.js coffeescript

应用程序布局

我有一个应用程序,侧边栏包含许多项目,主要 div显示这些项目。还有一个简单的Backbone.Router,一个ItemsCollection和一个Item模型。我有侧边栏SidebarViewShowView来显示所选项目。

                  +-------------------------+
                  | 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 *|               |
                  +---------+---------------+

启动时,我会初始化SidebarViewMainRouterSidebarViewrender方法附加到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 个答案:

答案 0 :(得分:5)

你可以做两件事:

  1. highlight_item可以跟踪哪些项目应该突出显示。
  2. 更新您的render以初始化突出显示的项目。
  3. 这样的事情:

    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集调用,一切都应该解决。