2

当整个模板完成渲染时,KnockoutJS 中有没有办法触发回调?

我了解afterRender您可以使用以下选项:

"template: { name: 'Template', afterRender : myCallback}"

但是回调在我的测试页面中触发了两次(我没有使用foreach也没有要显示的数据集合)。

我已经看到了与我要问的问题类似的以下问题:

模板渲染后的 KnockoutJS 绑定事件

但是那个问题的答案并没有帮助我。

Knockout 中是否有一个事件在整个模板完成渲染后触发,而不仅仅是在 KO 找到的每个元素之后触发?

编辑:该死,我急于发布这个问题,我忘了提到我正在使用它来加载模板:

https://github.com/ifandelse/Knockout.js-External-Template-Engine

由于模板存储在外部文件中。

4

4 回答 4

1

我无法(快速)在 github 上找到进一步解释这一点的条目,但它呈现两次的原因是一个错误。我的外部模板引擎的本地副本在第 22 行有一个额外的“自我”,它修复了它。

代替

options.afterRender = function() {

用这个

self.options.afterRender = function() {

请注意,NuGet 中的版本似乎已经过时,GitHub 版本已经包含此错误修复。

于 2013-05-27T12:53:26.570 回答
0

我正在为 KO 使用不同的 AMD 库,由作者编写。

https://github.com/rniemeyer/knockout-amd-helpers

我的不是最优雅的解决方案,但它有效。我所做的是使用 setTimeout(callback,100) 向我的所有模板添加 afterRender 调用。回调设置 jQuery 延迟解析。当 deferred 解决后,我知道我的所有渲染都已完成并且可以执行我的代码。

// create a jQuery deferred
var dfd = $.Deferred();

// in my template call
afterRender: function () {

  // clear the timeout if it's still in play
  if (renderTimeoutId !== undefined) {
      clearTimeout(renderTimeoutId);
  }

  // create a new timeout and restart the clock
  renderTimeoutId = setTimeout(function () {
      dfd.resolve();
  }, 100);
}

// when my code is complete
dfd.done(function(){ /* after rendering code */});

我对有一个更优雅的解决方案非常感兴趣,我真的不喜欢让我的代码依赖于超时,但这是我当时能想到的最好的解决方案。

于 2013-05-16T16:33:01.877 回答
0

我也在学习使用外部模板(与您相同的库)进行淘汰赛,我的也被解雇了两次。

原因是在注入器渲染 loadingTemplate 时触发一次 afterRender,然后在加载实际外部模板时触发一次。所以即使我在我的配置中设置了选项:

infuser.defaults.useLoadingTemplate = false;

除了现在使用空模板外,它仍然会触发两次。这意味着我可以做到这一点(我的 afterRender 所做的只是在将模板加载到模态窗口并调整其大小后显示模态窗口)。

仅仅为了绕过双重事件触发而关闭异步可能并不理想。

模板

<div data-bind="template: { name: template().name(), data: template().data(), afterRender: renderComplete }"></div>

查看模型

var renderComplete = function (params) {

  if (params.length > 0) {

     //Do my stuff here.

  }

};

如果有更好的方法或者我做错了什么,请告诉我:)

于 2013-02-13T09:05:16.173 回答
0

我设法对这个错误进行了不那么难看的快速修复。看起来,在 externalTemplateEngine “加载” div 渲染之后,第一个“afterRender”回调被触发。所以快速修复是检查哪些元素已被渲染:

afterRender = function (params) {
    // console.log(params);
    if (params.length <= 0 || $(params[0]).hasClass('infuser-loading'))
        return;

    // ... your code goes here
}
于 2013-07-31T10:41:46.433 回答