通过主干路由器回调突出显示所选项目

发布于 2025-01-05 04:10:54 字数 2215 浏览 1 评论 0原文

应用程序布局

我有一个应用程序,带有一个包含许多项目的侧边栏和一个显示这些项目的ma​​in 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 *|               |
                  +---------+---------------+

启动时,我初始化 SidebarViewMainRouterSidebarView 将其 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 文档中没有找到任何方法)并在渲染时突出显示该项目?

或者我的初始化只是愚蠢的,我应该以不同的方式处理事情吗?

The Application Layout

I have an application, with a sidebar that holds many items and a main div which displays these items. There is also a simple Backbone.Router, a ItemsCollection and a Item model. I've got a SidebarView for the sidebar and a ShowView to show the selected item.

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

On startup, I initialize the SidebarView and the MainRouter. The SidebarView attaches its render method to the ItemCollection#all event. I also attach the ItemCollection#refresh event to Backbone.history.start(), then I fetch the ItemCollection.

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

The problem

I want to highlight the currently selected item. This works by binding the route.show event from the router:

# 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")

It works perfectly when I select an Item when the app is loaded. But when the page is loaded with #/show/123 as the URL, the item is not highlighted. I run the debugger and found out, that the sidebar is not rendered yet, when the highlight_item callback is invoked.

Possible solutions

Is there any way to reorder the bindings, so that the Item#refresh event invokes SidebarView#render first and then start the routing?

Maybe a workaround that just takes the current route from the window.router (I did not find any method in the Backbone Docs) and highlights the Item when its rendered?

Or is my initialization just stupid and should I handle things differently?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

想你只要分分秒秒 2025-01-12 04:10:54

您可以做两件事:

  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 设置,一切都应该正常。

You could do two things:

  1. highlight_item could keep track of which item is supposed to be highlighted.
  2. Update your render to initialize the highlighted item.

Something like this:

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')

So, as long as highlight_item gets called, highlight_current will also get called with the appropriate @highlighted_id set and everything should work out.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文