【问题标题】:Durandal and Knockout: do a css binding to body elementDurandal 和 Knockout:对 body 元素进行 css 绑定
【发布时间】:2014-05-31 15:19:16
【问题描述】:

我正在尝试通过检查模块的状态(用户登录的帐户类型)来制作 Durandal 应用程序(使用 Knockout 的 SPA 框架)的正文元素。在应用程序外壳的视图模型中,我有以下代码:

function bindingComplete() {
  viewhelper.accountVisualTreatment();
}

accountVisualTreatment 是在viewhelper 模块中定义的:

if (typeof(appsecurity.userInfo()) == 'undefined') {
  $("body").addClass("notloggedin");
  $(".container").addClass("notloggedin");
} else {
  if (appsecurity.isUserInRole(['Account Manager']) && !appsecurity.isUserInRole(['Administrator'])) {
    $("body").addClass("accountmanager");
    $("nav").addClass("hidden");
  } else {
    $("body").removeClass();
    $(".container").removeClass("notloggedin");
    $("nav").removeClass("hidden");
  }
}

如果我以差异帐户类型登录时刷新页面,一切正常。但是作为一个 SPA 框架,在使用时没有页面刷新。因此,这些课程并没有按照我的意愿应用。如何使 body、container 和 nav 元素的类按我的意愿绑定?

编辑:我尝试在不同帐户类型的登录页面的视图模型中调用 viewhelper.accountVisualTreatment(),但无济于事。仍然需要刷新页面。

编辑:我通过在我的 shell.html 中将 css 绑定应用到容器 div 来丑陋地修复它

<div class="container" data-bind="css: viewhelper.accountVisualTreatment()"> ... </div>

【问题讨论】:

  • 您的代码只在文档加载时运行一次,这就是为什么永远不会应用这些类的原因。你的答案肯定是在正确的轨道上。您绝对可以使用这样的帮助程序,或者如果您希望在标记中直接使用 css: { 'notloggedin': appsecurity.userInfo() == 'undefined' } 之类的条件绑定
  • 不确定我是否理解这个问题......淘汰赛绑定的全部目的是让您的页面动态而不需要刷新页面。您只需将可见性或 css 或任何东西绑定到可观察对象,当可观察对象发生时,您的页面就会更改。
  • 我正在尝试将它绑定到 body 元素,在我的 Durandal 部署中,该元素是在视图模型的入口点 main/shell.js 和 shell.html 之外定义的。我通过在 shell.html 中容器 div 上的 css 绑定中调用我的辅助函数来解决它。 css 绑定检查绑定并运行帮助函数,该函数检查用户登录的帐户类型并应用正确的 CSS 类。

标签: javascript html css knockout.js durandal


【解决方案1】:

因为您想在正文中执行此操作(全局如此)。所以我的假设是您想在 accountinfo 更改后立即更新 css 类。您可以使用 accountinfo 创建一个可观察的单例。当它发生变化时,您只需订阅 observable。

唯一的问题是不在 dom 中的元素。 (比如在加载页面之间)。因为你使用 Durandal,所以你有不同的钩子来用 jQuery 改变 dom。

要在视图模型中执行此操作,您应该使用 attached()compositionComplete() 请参阅:http://durandaljs.com/documentation/Hooking-Lifecycle-Callbacks.html。这是当 dom 完全附加到视图模型和所有可观察对象时从 durandal 获得的回调。

我会说你不想在每个视图模型中都这样做。所以我建议挂钩路由器上的router:navigation:composition-complete 事件,请参阅:http://durandaljs.com/documentation/api.html#class/Router/event/router:navigation:composition-complete。这将确保您获得每个新哈希导航的回调。

您可以在启动应用程序的数据主中注册全局事件:

app.on('router:navigation:composition-complete').then(viewhelper.accountVisualTreatment());

我希望这会有所帮助。

【讨论】:

  • 明天我可以访问我的笔记本电脑并更新您的信息时会尝试一下!
  • 有趣的是,body 的类被正确应用了,而 div.container 在第一次启动应用程序时却没有。当以Account Manager 类型帐户登录时,也不会应用 css 类。当我通过 div.container 上的 css 绑定调用辅助函数时,它会按我的意愿工作。但是通过这个全局事件,它的行为并不像预期的那样。
  • 查看我使用全局事件处理程序的一些代码后,我在 settimeout 中进行处理。这样,您将处理程序推送到事件堆栈,以便浏览器可以呈现所有内容,然后我使用 Jquery 应用自定义行为。也许你可以试试。另一种解决方案是创建自定义绑定并将其添加到组合绑定处理程序中。 Durandal 将延迟绑定直到组合完成。
猜你喜欢
  • 2013-03-11
  • 2014-12-31
  • 2015-11-09
  • 2012-03-16
  • 1970-01-01
  • 1970-01-01
  • 2012-04-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多