【问题标题】:Make Knockout observable apply instantly?让 Knockout observable 立即应用?
【发布时间】:2015-05-14 19:28:27
【问题描述】:

我有一部分页面绑定到了 Knockout Viewmodel。当我单击一个链接时,它会加载一些数据并将其显示得更远一点。我想在它出去并加载数据时显示一点加载img,然后在完成时将其隐藏。我有以下代码(精简以显示重要部分)。 Ajax 调用是 NOT 异步的,对于其他人正在使用的其他代码,它被设置为 false,所以我无法更改它。问题是“self.Loading(false)”在 ajax 调用完成之前不会被触发,所以它似乎根本没有出现。如果我将 ajax 调用切换为异步,它会按预期工作。所以我想知道为什么 Ajax 调用会阻止 observables 更改,因为它是在它之前调用的,它不应该立即触发。有没有办法强制它立即触发。

HTML:

<a data-bind="click: GetInfo" href="javascript:;">
     <img data-bind="visible: Loading" src="myimg.jpg" alt="Loading" />
</a>

KO:

 self.Loading = ko.observable(false);
 self.GetInfo = function () {
    self.Loading(true);
    AjaxCall().done(function (data){
       self.Loading(false);
    }
 };

【问题讨论】:

  • 就像轶事一样,我上次看到一个基于非异步 XHR 构建的 Web 应用程序时,它已经无法挽救,不得不从头开始重写。

标签: javascript knockout.js


【解决方案1】:

observable 和 DOM 可能会立即更新,但您看不到它,因为浏览器可能无法绘制屏幕。该请求正在阻止重绘,因为......它是非异步的。这正是您应该发出非异步请求的确切原因。

作为一种解决方法,您可以尝试通过使用 setTimeout 以 0 超时来强制事件循环旋转一次,以在可观察到的更改之后运行您可怕的同步请求,但严肃地说,只需将您的请求修复为异步。当你的代码被阻塞时,浏览器不能保证做任何事情(包括运行任何加载动画)。

【讨论】:

  • 谢谢,是的,我个人也不喜欢同步请求,我相信它最初的设置是为了获得淘汰绑定以等待数据加载,因为它绑定到任何内容然后更改导致奇怪的闪烁,但这个问题比这个更容易解决。从来不知道同步阻止重绘认为它只是阻止了您的顶级代码。我看看能不能改。
【解决方案2】:

试试这个

<a data-bind="click: GetInfo,valueUpdate: 'keyup'" href="javascript:;">
    <img data-bind="visible: Loading" src="myimg.jpg" alt="Loading" />
</a>

【讨论】:

  • wtf valueUpdate 是否与点击事件有关
  • 为了完整起见,我试过了,它确实不起作用,谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-13
  • 2017-10-25
  • 2013-08-08
  • 2021-08-22
  • 2013-04-22
  • 2015-04-05
  • 2018-05-26
相关资源
最近更新 更多