Can.js中的路由约定

sav*_*ger 1 canjs canjs-routing

所以我想在我的超酷can.js应用程序中制作一些路线.瞄准这样的事情......

#!claims          ClaimsController - lists claims

#!claims/:id      ClaimController - views a single claim
#!claims/new      ClaimController - creates a new claim
#!claims/:id/pdf  - do nothing, the ClaimController will handle it

#!admin           AdminController - loads my Administrative panel with menu
#!admin/users     - do nothing, the AdminController will handle it
#!admin/settings  - do nothing, the AdminController will handle it
Run Code Online (Sandbox Code Playgroud)

那我们怎么做呢?

“claims route”:      function() { load('ClaimsController'); },
“claims/:id route”:  function() { load('ClaimController'); },
“admin”:             function() { load(‘AdminController’); },
Run Code Online (Sandbox Code Playgroud)

凉豆,我们走了.那么如果有人发送链接给某人,比如...

http://myapp#!claims/1/pdf
Run Code Online (Sandbox Code Playgroud)

什么都没发生!好吧,让我们添加路线.

“claims/:id/pdf route”: function() { load('ClaimController'); },
Run Code Online (Sandbox Code Playgroud)

大.现在该链接有效.这里,路由器的工作只是加载控制器.控制器将识别出需要pdf操作,并显示正确的视图.

所以假装我已经加载了一个索赔claims/:id,我编辑了一两件事.然后单击"打印预览"按钮以查看PDF并将路径更改为claims/:id/pdf.

应该怎么做 ......理赔控制器正在观察路线并显示pdf视图.

实际发生的事情 ......路由器看到更改,匹配claims/:id/pdf我们添加的路由,并重新加载Claim Controller,显示从服务器/缓存中提取的声明的新版本,丢失我的更改.

为了尝试定义问题,我需要路由器来识别路由何时更改,路由属于哪个控制器,以及控制器是否已加载,请忽略它.但这很难!

claims      //
claims/:id // different controllers!

claims/:id      //
claims/:id/pdf // same controller!
Run Code Online (Sandbox Code Playgroud)

我们可以绑定"控制器"更改.所以定义路径can.route(':controller')和绑定:controller.

{can.route} controller
// or
can.route.bind('controller', function() {...})
Run Code Online (Sandbox Code Playgroud)

但是点击声明(从ClaimsController更改为ClaimController)将不会触发,因为claim在这两种情况下第一个标记都是相同的.

我可以依靠的约定吗?我应该指定应用程序中的每个路由并检查控制器是否已加载?我首选的路线网址是否不起作用?

Jus*_*yer 5

以下是我在复杂的CanJS应用程序中设置路由的方法.你可以在这里看到一个例子.

首先,不要使用can.Control路由.这是一个反模式,将在3.0中删除,就像本期中的想法一样.

相反,你设置一个routing app是进口并通过类似于常规设置模块模块此所使用这里.

我将在稍后解释如何设置routing app模块.但首先,了解can.route与您可能习惯于如何考虑路由的方式有何不同是非常重要的.它的区别在于一开始很难理解,但一旦得到它; 你希望看到它对客户端路由有多么强大和完美.

想想can.route的数据,而不是想到网址.什么在can.route.attr().例如,您的网址似乎包含以下数据:

  • page - 某人正在处理的主要区域
  • 子页面 - 页面中的可选辅助区域
  • id - 类型的id

例如,admin/users可能想要can.route.attr()返回:

{page: "admin", subpage: "users"}
Run Code Online (Sandbox Code Playgroud)

并且,claims/5可能会转化为:

{page: "claims", id: "5"}
Run Code Online (Sandbox Code Playgroud)

当我开始构建应用程序时,我只使用看起来像的URL #!page=admin&subpage=users并忽略漂亮的路由,直到稍后.我首先围绕国家建立一个应用程序.

一旦我掌握了can.route.attr()封装应用程序状态的数据的心理图像,我就会构建一个routing app模块来监听更改can.route并设置正确的控件或组件.你的看起来像是这样的:

can.route.bind("change", throttle(function(){
  if( can.route.attr("page") == "admin" ) {
    load("AdminController")
  } else if(can.route.attr("page") === "claims" && can.route.attr("id") {
    load("ClaimController")
  } else if ( ... ) { 
    ... 
  } else {
    // by convention, load a controller for whatever page is
    load(can.capitalize(can.route.attr("page")+"Controller")
  }

}) );
Run Code Online (Sandbox Code Playgroud)

最后,在完成所有这些之后,我将漂亮的路线映射到我的预期can.route.attr()值:

can.route(":page"); // for #!claims, #!admin
can.route("claims/new", {page: "claims", subpage: "new"});
can.route("claims/:id", {page: "claims"});
can.route("admin/:subpage",{page: "admin"});
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以使路由独立于应用程序的其余部分.一切都只是听取can.route属性的变化.您的所有路由规则都保存在一个位置.