所以我想在我的超酷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
那我们怎么做呢?
“claims route”: function() { load('ClaimsController'); },
“claims/:id route”: function() { load('ClaimController'); },
“admin”: function() { load(‘AdminController’); },
酷豆,我们走了。那么如果有人向某人发送链接怎么办...
http://myapp#!claims/1/pdf
什么都没发生!好吧,好吧,让我们添加路线。
“claims/:id/pdf route”: function() { load('ClaimController'); },
大。现在该链接有效。这里,路由器的工作只是加载控制器。控制器将识别出需要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!
我们可以绑定“控制器”更改。因此,定义can.route(':controller')
等路线并绑定:controller
。
{can.route} controller
// or
can.route.bind('controller', function() {...})
但是点击声明(从ClaimsController更改为ClaimController)将不会触发,因为在这两种情况下第一个标记claim
都是相同的。
我能依靠的约定吗?我应该指定应用程序中的每个路由并检查控制器是否已加载?我首选的路线网址是不起作用的吗?
答案 0 :(得分:5)
以下是我在复杂的CanJS应用程序中设置路由的方法。您可以看到此here的示例。
首先,不要使用can.Control路由。它是一种反模式,将在3.0中删除this issue中的想法。
而是设置一个routing app
模块,该模块按惯例导入和设置模块,类似于使用this的here。
我将在稍后解释如何设置routing app
模块。但首先,了解can.route
与您可能习惯于如何考虑路由的方式有何不同,这一点非常重要。它的区别在于一开始很难理解,但一旦得到它;您希望看到它对客户端路由有多么强大和完美。
不要考虑网址,而应考虑can.route的数据。 can.route.attr()
中有什么。例如,您的网址似乎包含以下数据:
例如,admin/users
可能希望can.route.attr()
返回:
{page: "admin", subpage: "users"}
而且,claims/5
可能会转化为:
{page: "claims", id: "5"}
当我开始构建应用程序时,我只使用看起来像#!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")
}
}) );
最后,在完成所有这些操作后,我将漂亮的路线映射到我预期的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"});
通过这种方式,您可以使路由独立于应用程序的其余部分。一切都只是听取了can.route属性的变化。您的所有路由规则都保存在一个位置。