Backbone JS - 路由器问题 - 如何获得干净的 URL

Posted

技术标签:

【中文标题】Backbone JS - 路由器问题 - 如何获得干净的 URL【英文标题】:BackboneJS - Router issues - how to get clean URL's 【发布时间】:2013-12-28 12:50:37 【问题描述】:

好的,我有

#each mainmenu
<li>
    <a href="#pages/this.url"><h2>this.name</h2></a>
</li>
/each

在我的路由器中

routes: 
    '': 'index',
    'pages/firstpage' : 'firstpage',
    'pages/secondpage' : 'secondpage',
    'pages/thirdpage' : 'thirdpage'
,
initialize: function () 
   Backbone.history.start(pushState: false);

我的 json 文件是:


    "name":"First page",
    "id":"1",
    "url":"firstpage"
,

    "name":"Second page",
    "id":"2",
    "url":"secondpage"
,

    "name":"Third page",
    "id":"3",
    "url":"thirdpage"

现在我的 URL 是“#pages/secondpage” - 我怎样才能让 URL 显示“pages/secondpage” - 我尝试了“pushState:true”,但它不起作用......然后在我的主菜单中.js 视图我添加了一个事件:

events: 
     'click a.second': 'secondpage'
,

secondpage: function() 
    var secondpageRouter = new Backbone.Router();
    var route = 'pages/secondpage';
    secondpageRouter.navigate(route, trigger: true);
  

但这也不起作用...当我从上面的锚点中删除“#pages/”时,我几乎得到了我想要的 URL “pages/secondpage” - 但它在单击后显示“找不到 URL”链接。那么这里发生了什么???

请帮助任何人?

【问题讨论】:

&lt;a href="/pages/this.url"&gt; 结合 pushState:true 应该可以工作。 很遗憾没有:-( 我认为你的最后一段代码已经很接近了,你只需要添加event.preventDefault() @muistooshort 这对我来说没有意义。主干.js 的全部意义在于不必返回服务器来刷新页面。如果您没有preventDefault() 链接,它将向服务器发送get 请求。 The example here 使用 preventDefault() @RustyToms:嗯,忘记了我埋在我的应用程序中的“让&lt;a&gt;s 表现得明智”样板黑客。过去六个月一直在服务器端。 【参考方案1】:

了解您需要能够在必要时从服务器提供这些 url,请在此处阅读文档:http://backbonejs.org/#History

那么你至少需要做三件事。

首先,在你定义好你的路由器之后,调用Backbone.history 并确保pushState 为真:

Backbone.history.start( pushState: true )

其次,删除链接中的所有#,如下所示:

<a href="pages/this.url"><h2>this.name</h2></a>

第三,这很重要,您需要拦截对本地链接的所有点击并阻止它们的默认行为,即会将您引导至新页面。使用 jQuery 很容易:

$(document).on("click", "a[href^='/']", function(event)
  event.preventDefault();
  RouterNameGoesHere.navigate($(event.target).attr("href"), trigger: true);
);

如果您不使用 jQuery,请在您的视图中侦听链接单击事件,以处理事件处理程序中的 url。我修改了您的代码以添加event 参数和event.preventDefault()

events: 
  'click a.second': 'secondpage'
,

secondpage: function(event) 
  event.preventDefault();
  var secondpageRouter = new Backbone.Router();
  var route = 'pages/secondpage';
  secondpageRouter.navigate(route, trigger: true);

Here is an interesting blog post about this issue

【讨论】:

文档中最重要的一点:请注意,使用真实的 URL 需要您的 Web 服务器能够正确呈现这些页面,因此还需要进行后端更改。例如,如果您有 /documents/100 的路由,如果浏览器直接访问该 URL,则您的 Web 服务器必须能够提供该页面。对于完整的搜索引擎可抓取性,最好让服务器为页面生成完整的 html ......但如果它是一个 Web 应用程序,只需呈现与根 URL 相同的内容,然后用 Backbone 填充其余内容视图和 javascript 工作正常。 太棒了!那行得通!我注意到的是,当我使用带有 URL“localhost/projectfolder/projectname”的 localhost 然后单击 secondpage-anchor 时,它使我的 URL “localhost/pages/secondpage” - 如何保留 projectfolder 和 projectname? @SHT,无论你想要在你的 url 中的任何内容都应该在你的链接中。然后,您可以以某种方式欺骗路线,但如果那是您想要的 url,那么您也应该将其包含在您的路线中。所以href="projectfolder/pages/this.url",路线是/projectfolder/pages/secondpage,等等。 虽然我们正在这样做,但每次要导航时都制作新路由器是没有意义的。制作一次路由器,并将其保存为全局变量。然后在需要路由器时调用全局变量。这样后退和前进按钮将起作用。它们可能不适合你,对吧? 是的,你完全正确。在哪里声明该全局变量?

以上是关于Backbone JS - 路由器问题 - 如何获得干净的 URL的主要内容,如果未能解决你的问题,请参考以下文章

如何防止 Backbone.js 路由(或历史记录)自动将参数添加到 GET 请求?

Backbone.js:未达到路由器回调

Backbone.js:查看状态和路由

如何使用 Backbone.js 在 changePage 后显示 JQuery Mobile 主页面

Backbone.js 路由器初始化不会立即运行

使用 Jasmine 监视 Backbone.js 路由调用