2013-04-27 73 views
7

有没有一种方法可以在Knockout将DOM添加到DOM并完成渲染后运行自定义代码?我需要这个,所以我可以绑定一个嵌套视图模型来动态添加html代码。afterRender for html binding

喜欢的东西:

<div data-bind="html: dynamicHtml, afterRender: customCode"></div> 

... 

MyViewModel.prototype.customCode = function(){ 
    ko.applyBindings(self.MyInnerViewModel(), document.getElementById('someTagInTheDynamicHtml')); 
}; 

afterRender这里不叫(仅与模板结合的作品?),和一个自定义绑定也没有帮助,因为不能保证“update”事件被称为DOM更新后。

回答

12

是,afterRender仅与template绑定。

但是,您可以创建自定义绑定处理程序,用于跟踪html绑定更改并在更新值时触发回调。我的例子:

ko.bindingHandlers.afterHtmlRender = { 
    update: function(el, va, ab){ 
     ab().html && va()(ab().html); 
    } 
} 

缩短PARAM名称:VA - valueAccessor,AB - allBindings

另外的标记应该是(绑定名称更改):

<div data-bind="html: dynamicHtml, afterHtmlRender: customCode"></div> 

http://jsfiddle.net/dDDjf/

更新

简化了解释绑定代码:

ko.bindingHandlers.afterHtmlRender = { 
    update: function(element, valueAccessor, allBindings){ 
     // check if element has 'html' binding 
     if (!allBindings().html) return; 
     // get bound callback (don't care about context, it's ready-to-use ref to function) 
     var callback = valueAccessor(); 
     // fire callback with new value of an observable bound via 'html' binding 
     callback(allBindings().html); 
    } 
} 
+0

谢谢 - 效果很好。我认为它应该以'ab()。html()'开头,否?另外,你能否以一种人们可以理解正在发生的事情的方式来重构代码? – seldary 2013-04-27 12:46:22

+0

不,应该有'ab()。html'。这只是检查所有绑定中的* html *绑定存在。我已经用解释更新了我的答案。 – 2013-04-27 13:07:39