当整个模板完成渲染时,KnockoutJS中有没有办法让回调发生?
我了解您可以使用afterRender
选项:
"template: { name: 'Template', afterRender : myCallback}"
但回调在我的测试页面中触发两次(我没有使用foreach
,也没有要显示的数据集合。)
我看到以下问题与我提出的问题类似:
KnockoutJS bind event after template render
但那个问题的答案并没有帮助我。
Knockout中是否有一个事件在整个模板完成渲染后触发,而不是在KO找到的每个元素之后触发?
编辑: 该死的,我急着发布这个问题,我忘了提到我用它来加载模板:
https://github.com/ifandelse/Knockout.js-External-Template-Engine
由于模板存储在外部文件中。
答案 0 :(得分:1)
我无法(快速)在github上找到进一步解释这一条目的条目,但afaik它呈现两次的原因是一个错误。我的外部模板引擎的本地副本在第22行有一个额外的“self”,它修复了它。
而不是
options.afterRender = function() {
使用此
self.options.afterRender = function() {
请注意,NuGet中的版本似乎已经过时,GitHub版本已经包含此修复程序。
答案 1 :(得分:0)
我也在学习基于外部模板的淘汰赛(和你一样的库),我的也是两次射击。
原因是当infuser呈现loadingTemplate时afterRender触发一次,然后在加载实际外部模板时触发一次。所以即使我在配置中设置了选项:
infuser.defaults.useLoadingTemplate = false;
除了现在有一个空模板,它仍然会触发两次。这意味着我可以做到这一点(我的所有afterRender都会在模板加载到模板窗口后显示模态窗口,并调整大小到内容)。
关闭异步以解决双重事件发射可能并不理想。
TEMPLATE
<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.
}
};
如果有更好的方法或我做了明显错误的事情,请告诉我:)
答案 2 :(得分:0)
我正在为KO使用不同的AMD库,作者写的一个。
https://github.com/rniemeyer/knockout-amd-helpers
我不是最优雅的解决方案,但它确实有效。我所做的是使用setTimeout(回调,100)为我的所有模板添加一个afterRender调用。回调设置了一个延迟解析的jQuery。当延迟解决后,我知道我的所有渲染都已完成,并且可以执行我的代码。
// 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 */});
我对这个更优雅的解决方案非常感兴趣,我真的不喜欢我的代码依赖于超时,但这是我当时能想到的最好的。
答案 3 :(得分:0)
我设法做了不那么难看,快速修复这个bug。看来,在渲染externalTemplateEngine“loading”div之后,第一个“afterRender”回调被触发了。所以快速解决方法是检查已呈现的元素:
afterRender = function (params) {
// console.log(params);
if (params.length <= 0 || $(params[0]).hasClass('infuser-loading'))
return;
// ... your code goes here
}