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在这两种情况下第一个标记都是相同的.
我可以依靠的约定吗?我应该指定应用程序中的每个路由并检查控制器是否已加载?我首选的路线网址是否不起作用?
以下是我在复杂的CanJS应用程序中设置路由的方法.你可以在这里看到一个例子.
首先,不要使用can.Control路由.这是一个反模式,将在3.0中删除,就像本期中的想法一样.
相反,你设置一个routing app是进口并通过类似于常规设置模块模块此所使用这里.
我将在稍后解释如何设置routing app模块.但首先,了解can.route与您可能习惯于如何考虑路由的方式有何不同是非常重要的.它的区别在于一开始很难理解,但一旦得到它; 你希望看到它对客户端路由有多么强大和完美.
想想can.route的数据,而不是想到网址.什么在can.route.attr().例如,您的网址似乎包含以下数据:
例如,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属性的变化.您的所有路由规则都保存在一个位置.