【问题标题】:Backbone.js router pattern for different response to browser "back" button or direct navigationBackbone.js 路由器模式,用于对浏览器“后退”按钮或直接导航的不同响应
【发布时间】:2012-07-19 01:32:57
【问题描述】:
是否有一个很好的模式来实现对这两个事件做出不同响应的 Backbone.js 路由器:
-
直接导航 - 用户通过将 url 直接放入浏览器或通过调用
Router.navigate() 在应用程序中直接导航到页面
-
浏览器“后退”按钮 - 用户按下“后退”按钮可转到他们之前所在的页面。
我问的原因是因为如果由于用户按下“返回”按钮而调用路由器,我只想通过$('element_id').html(view.el) 将旧视图放回其元素,而不需要重新加载数据模型并重新渲染视图。
如果由于用户通过在浏览器中输入 url、单击链接或从应用程序中调用 Router.navigate() 直接导航到页面而调用路由器,我希望router 指示模型重新请求数据并触发视图的重新渲染。
任何帮助和建议将不胜感激,非常感谢!
【问题讨论】:
标签:
javascript
backbone.js
backbone-views
backbone-routing
【解决方案1】:
不久前我遇到了类似的问题。这可能超出了您的预期,但这是我发现的有效方法。
直接导航
对于直接导航,通常的流程是这样的:
-
初始化应用程序:大多数backbone.js项目都会有一些初始化应用程序的代码(App.init)。虽然很多示例在实际的 HTML 中插入集合(待办事项等)的 JSON,但我个人喜欢使用这段代码作为在页面加载后获取集合的机会,如下所示(coffeescript):
window.App =
...
init: ->
@todos = new App.Todos()
@todos.deferred = @todos.fetch()
@threads.deferred.done ->
App.appRouter = new App.AppRouter(collection: self.todos)
...
(使用jQuery的deferred是为了确保在实际渲染页面之前获取集合。)
-
初始化路由器:在这里您有机会为路由器分配一个元素并将集合分配给路由器(我正在使用来自 thinkbot 的 backbone-support 的“SwappingRouter”,我强烈建议退房):
App.Router = Support.SwappingRouter.extend
...
initialize: (options) ->
@el = $('.content')
@collection = options.collection
-
执行路由处理程序:这是最后一步,此时集合已经初始化并且路由器有一个指向它的指针,所以我们只需要创建视图并渲染它:
show: (id) ->
view = new App.TodosView(model: @collection.get(id))
@swap(view)
(Swap 渲染视图并做一些其他事情来清理。)
浏览器返回按钮
在这种情况下,App.init 和 AppRouter.initialize 都不会被调用,因此默认情况下不会重新加载集合。 Backbone 将自动调用上一个路由的导航,因此根据您的路由处理程序中的内容,视图可能会重新呈现。在上面的示例中,它会是(交换调用渲染),但您可以解决这个问题。
这里和主干始终存在的关键问题是,您同时使用无状态 (HTTP) 协议和有状态(富客户端应用程序)环境。将两者对齐以便它们很好地协同工作可能非常棘手。