0

我的 Durandal 应用程序的DOM结构如下:

  //shell.html
  <div id="applicationContentWrapper" >
    <!-- ko compose: {model: 'viewmodels/header', activate:true} --> <!-- /ko -->
    <div data-bind="router:{}"></div>
  </div>

这是我的路由器配置的片段

router.map([
        { route: '', moduleId: 'viewmodels/dashboard', name: 'dashboard'},
        { route: 'form', moduleId: 'viewmodels/form', name: 'form'},
        { route: 'login', moduleId: 'viewmodels/login', name: 'login'}
]);

如您所见,我的登录视图被插入到<div data-bind="router:{}"></div>预期的行为中。但是,如果我在登录视图中,我需要隐藏标题视图,我通过订阅标题视图模型中的路由器配置来设法做到这一点:

router.activeInstruction.subscribe(function (val) {
    val.config.name === "login" ? showHeader(false) : showHeader(true);
});

但这感觉有点乱,标题视图的DOM仍在页面中,我真正想做的是,如果我在登录视图中,我只想让登录视图的DOM在那里,就好像我我在单独的页面中,只有登录视图。但到目前为止,我还没有找到一种干净的方法来做到这一点。

4

1 回答 1

2

一些东西:

  1. 安全的最终责任永远不在您的前端。恶意用户可以轻松访问您在前端“关闭”的所有内容。后端应该保护您的所有功能和数据,前端仅将其隐藏以便为用户提供更好的体验。所以换句话说,它仍然在 DOM 中并不重要(从安全的角度来看)。即使不是,也不会更安全。
  2. 如果您无论如何都不想在 DOM 中包含节点(出于性能原因),请使用withor if-binding。如果条件是虚假的,他们会隐藏里面的任何东西。
  3. activeInstruction 的订阅确实有点乱。你需要改进你的逻辑。标题未隐藏,因为用户在登录页面上,标题隐藏,因为用户未登录。这是一个很大的区别。你所做的本质上是一个肮脏的黑客行为。在您的外壳视图模型(或其他地方)中有一个可观察/计算的可观察对象,它返回用户是否经过身份验证。然后基于此,显示/隐藏您的标题。
  4. 使用我上面提到的authenticated-observable,你还可以通过检查这个observable来“保护”你的观点。这样,您可以确保用户无法导航到需要对其进行身份验证的路由。尽管如此,这个安全检查的最终责任在你的后端,而不是你的前端。

编辑

我可以理解您想要一个完全不同的“布局”而不需要其余 DOM 用于您的登录视图的原因。但这违背了单页应用程序的整体理念。这也是不必要的。一些智能 css 和数据绑定(可见、if、with)将为您提供相同的结果,通常提供比整个页面重新加载更好的用户体验。但是,如果您坚持要破坏 SPA,请将路由器放置在低一级:例如,主路由器只知道登录路由和内部路由。内部路由有另一个路由器来保存所有其他页面。通过这种方式,您可以将通用 HTML 从 shell 视图移动到内部视图。

于 2014-03-03T12:48:53.847 回答