【问题标题】:How can I show a "loader" during knockout.js initialization?如何在 knockout.js 初始化期间显示“加载程序”?
【发布时间】:2013-09-02 00:14:11
【问题描述】:

我有一个使用 knockout.js 和 jQuery Mobile 构建的单页网络应用程序。

视图模型初始化(即ko.applyBindings() 函数)大约需要 7-8 秒。在此期间,页面显示为空白。

$(document).ready(function () {
    ko.applyBindings(viewModel);
})

有没有办法同时显示 JQM 加载器,或者显示一种“启动画面”,给用户一个“页面正在加载”的反馈?

请注意,在我看来@Jeroen 提出的解决方案与 jQuery Mobile 的默认页面转换一起也很好,至少我可以看到in this jsfiddle

老实说,@Omar 提出的技巧在我看来似乎与 JQM 有更好的集成,我将来会尝试将这两个答案结合起来,用一个可写的计算 observable 来打开/关闭 JQM 加载器。

【问题讨论】:

  • 使用$.mobile.loading('show')$.mobile.loading('hide')
  • 您可以发布您的 viewModel 的副本吗?为什么需要这么长时间?是因为 AJAX 吗?
  • @Omar:我试过了,但也许我做错了什么,它没有显示。 viewModel 大约有 2000 行长,但它的在线地址为 preciso-enjoy.it/ppc/product_configurator.html
  • @BradleyTrager:是的,如果您想知道这种延迟,您是对的!这不是因为 Ajax,它唯一的客户端。肯定有问题,我现在正在调查,但我不知道如何调试。
  • 这里有几种测试性能的方法(stackoverflow.com/questions/111368/…

标签: jquery-mobile knockout.js single-page-application


【解决方案1】:

保持简单!默认情况下在您的 html 中显示加载覆盖,但使用某种visible: false 绑定。这样,当applyBindings 调用完成时,UI 将隐藏覆盖。

例如,假设这个视图:

<div id="main">
    <div id="loading-overlay" data-bind="visible: loading"></div>
    Some content<br />
    Some content
</div>

假设这个视图模型:

vm = { loading: ko.observable(true) };

然后调用这个:

ko.applyBindings(vm);

如果由于某种原因加载需要 7 秒,则加载叠加层将显示,直到 UI 更新。

如果您有客户端 DAL 或运行 Ajax 调用的某个单点,则此方法非常有用,因为您可以遵循以下模式:

  1. vm.loading(true)
  2. 带有成功和失败回调的 Ajax 调用
  3. 在回调时做vm.loading(false)

Knockout 将为您处理叠加层可见性。

查看this fiddle 以获取演示,或查看此堆栈片段:

vm = { loading: ko.observable(true) };

ko.applyBindings(vm);

// Mock long loading time:
window.setTimeout(function() {
    vm.loading(false);
}, 5000);
html { height: 100%; }

body {
    position: relative;
    height: 100%;
    width: 100%;
}

#loading-overlay {
    position: absolute;
    top: 0; left: 0; right: 0; bottom: 0;
    background: url('http://img.cdn.tl/loading51.gif') white no-repeat center;
    opacity: 0.75;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>

<div id="main">
    <div id="loading-overlay" data-bind="visible: loading"></div>
    Some content<br />
    Some content<br />
    Some content<br />
    Some content<br />
    Some content<br />
    <input type='text' value='cant edit me until overlay is gone' /><br />
    <button>can't press me until overlay's gone!</button><br />
    Some content<br />
    Some content<br />
    Some content
</div>

【讨论】:

  • 很棒的提示!顺便说一句,如果有任何原因,我能问你为什么你提出一个用 div 自制的解决方案,而不是像 Omar 提出的那样更标准的解决方案吗?
  • 我现在发现您的解决方案还具有在 JQM 应用 DOM 转换之前工作的优势。我的意思是,在页面初始化开始时防止无样式元素的闪烁也很有用。
  • 是的,解决方案很简单,并且不依赖 jQuery 来初始显示。一个缺点是对浏览器的支持,尤其是 IE7 可能对绝对定位感到不满(虽然不确定移动浏览器)。
猜你喜欢
  • 2014-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-24
  • 2014-08-17
  • 1970-01-01
  • 2013-02-18
  • 1970-01-01
相关资源
最近更新 更多