【问题标题】:How can I dynamically change the visibility of a Durandal Route?如何动态更改 Durandal 路线的可见性?
【发布时间】:2014-10-20 13:37:15
【问题描述】:

我的 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;
              }
         }
     }
});

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

【问题讨论】:

标签: durandal


【解决方案1】:

这就是我最终要做的。

//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 上有一些关于这个新功能的讨论。最终出于安全原因,我可能会从我的服务器提供登录的路由。但目前这应该可以正常工作。

【讨论】:

    【解决方案2】:

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

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

    这种方法在面对深度链接时是稳健的,因为它消除了通过应用程序的路径的概念。如果没有明确的重定向逻辑,它将验证用户,然后显示请求的资源。

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

    【讨论】:

      猜你喜欢
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多