如何动态更改Durandal Route的可见性?

时间:2013-05-14 19:32:14

标签: durandal

我的Durandal路线配置如下。

var routes = [ 
....... More Routes Here.....
{
    url: 'login',
    moduleId: 'viewmodels/login',
    name: 'Log In',
    visible: true,
    caption: 'Log In'
}, {
    url: 'logout',
    moduleId: 'viewmodels/logout',
    name: 'Log Out',
    visible: false,
    caption: 'Log Out'
}, {
    url: 'register',
    moduleId: 'viewmodels/register',
    name: 'Register',
    visible: false,
    caption: 'Register'
}];

一切都按预期工作。我希望能够在我登录时激活导航中的注销路线,并且我的登录按钮变为不可见。我尝试了以下代码,尽管没有抛出任何错误,但它不会改变界面中任何内容的可见性。

var isLoggedIn = ko.observable(false);
isLoggedIn.subscribe(function (newValue) {
    var routes = router.allRoutes();
    if (newValue == true) {
        for (var k = 0; k < routes.length; k++) {
            if (routes[k].url == 'logout') {
                routes[k].visible = true;
            }
            if (routes[k].url == 'login') {
                routes[k].visible = false;
            }
        }
     } else {
         for (var i = 0; i < routes.length; i++) {
             if (routes[i].url == 'logout') {
                 routes[i].visible = false;
              }          
              if (routes[i].url == 'login') {
                  routes[i].visible = true;
              }
         }
     }
});

我认为这不起作用,因为可见不是可观察的,isActive是一个没有写入功能的计算,所以它也不起作用。如何在导航菜单中动态更改路线的可见性?

2 个答案:

答案 0 :(得分:0)

这是我最终做的事情。

//ajax call to log user in
.done(function (recievedData) {
    if (recievedData == true) {
        router.deactivate();
        return router.map(config.routesLoggedIn);
    } else {
        router.deactivate();
        return router.map(config.routes);
    }
}).done(function() {
    router.activate('frames');
    return router.navigateTo('#/frames');
});

基本上在我的配置对象中创建了两个路由配置文件。一个登录,一个登录。有一点需要注意。 router.deactivate()方法是一个非常新的方法,但尚未在NuGet包中。我从Durandal的GitHub存储库的主分支复制了新路由器的代码。在Durandal User Group上对这个新功能进行了一些讨论。最终出于安全考虑,我可能会从我的服务器提供已登录的路由。但暂时这应该可以正常工作。

答案 1 :(得分:0)

另一种方法是使所有路由可用,但使用绑定表达式将内容或登录页面组合到路由指定的容器视图中。

不是提供文字视图名称,而是将compose参数绑定到三元表达式,该表达式在登录视图的名称和内容视图的名称之间进行选择。控制表达式是一个可观察的,例如app.isAuthenticated(),当用户成功登录或注销时,必须设置其值。

这种方法在深度链接方面很强大,因为它消除了通过应用程序的路径的概念。如果没有显式重定向逻辑,它将对用户进行身份验证,然后显示所请求的资源。

可以使用函数而不是三元表达式将其扩展到两个以上的可能状态。当根据用户权限必须交付不同的UI时,这很方便。